Desain dengan mempertimbangkan skala dan ketersediaan tinggi

Last reviewed 2023-08-05 UTC

Dokumen dalam Framework Arsitektur Google Cloud ini memberikan prinsip-prinsip desain untuk merancang layanan Anda, sehingga layanan tersebut dapat menoleransi kegagalan dan skala sebagai respons terhadap permintaan pelanggan. Layanan yang andal akan terus merespons permintaan pelanggan saat ada permintaan yang tinggi atas layanan atau saat ada aktivitas pemeliharaan. Prinsip desain keandalan dan praktik terbaik berikut harus menjadi bagian dari rencana deployment dan arsitektur sistem Anda.

Membuat redundansi untuk ketersediaan yang lebih tinggi

Sistem dengan kebutuhan keandalan tinggi tidak boleh memiliki titik kegagalan tunggal, dan resource-nya harus direplikasi ke beberapa domain gagal. Domain gagal adalah kumpulan resource yang dapat gagal secara independen, seperti instance VM, zona, atau region. Saat mereplikasi di seluruh domain gagal, Anda akan mendapatkan level ketersediaan gabungan yang lebih tinggi daripada yang dapat dicapai oleh setiap instance. Untuk informasi selengkapnya, lihat Region dan zona.

Sebagai contoh spesifik redundansi yang mungkin menjadi bagian dari arsitektur sistem Anda, untuk mengisolasi kegagalan dalam pendaftaran DNS ke masing-masing zona, gunakan nama DNS zona untuk instance pada jaringan yang sama agar dapat saling mengakses.

Desain arsitektur multi-zona dengan failover untuk ketersediaan tinggi

Jadikan aplikasi Anda tahan terhadap kegagalan di level zona dengan merancangnya untuk menggunakan kumpulan resource yang didistribusikan di beberapa zona, dengan replikasi data, load balancing, dan failover otomatis antarzona. Jalankan replika zona setiap lapisan stack aplikasi, dan hilangkan semua dependensi lintas zona dalam arsitektur.

Replikasi data di seluruh region untuk pemulihan dari bencana

Replikasikan atau arsipkan data ke region remote untuk mengaktifkan pemulihan dari bencana jika terjadi pemadaman layanan atau kehilangan data regional. Saat replikasi digunakan, pemulihan akan lebih cepat karena sistem penyimpanan di region remote sudah memiliki data yang hampir terbaru, selain kemungkinan hilangnya sejumlah kecil data karena penundaan replikasi. Saat Anda menggunakan pengarsipan berkala, bukan replikasi berkelanjutan, pemulihan dari bencana melibatkan pemulihan data dari cadangan atau arsip di region baru. Prosedur ini biasanya menyebabkan periode nonaktif layanan yang lebih lama daripada mengaktifkan replika database yang terus-menerus diupdate, dan dapat menyebabkan lebih banyak kehilangan data karena jeda waktu antara operasi pencadangan berturut-turut. Apa pun pendekatan yang digunakan, seluruh stack aplikasi harus di-deploy ulang dan dimulai di region baru, dan layanan tidak akan tersedia saat hal ini terjadi.

Untuk pembahasan mendetail tentang konsep dan teknik pemulihan dari bencana, lihat Merancang pemulihan dari bencana untuk pemadaman infrastruktur cloud.

Desain arsitektur multi-region untuk ketahanan terhadap pemadaman layanan regional

Jika layanan perlu berjalan secara terus-menerus, bahkan dalam kasus yang jarang terjadi saat seluruh region gagal, desain layanan tersebut untuk menggunakan kumpulan resource komputasi yang didistribusikan di berbagai region. Menjalankan replika regional setiap lapisan stack aplikasi.

Menggunakan replikasi data di seluruh region dan failover otomatis saat satu region mengalami penurunan. Beberapa layanan Google Cloud memiliki varian multi-regional, seperti Spanner. Agar tidak terganggu oleh kegagalan regional, gunakan layanan multi-regional ini dalam desain Anda jika memungkinkan. Untuk mengetahui informasi selengkapnya tentang region dan ketersediaan layanan, lihat lokasi Google Cloud.

Pastikan tidak ada dependensi lintas region sehingga jangkauan dampak kegagalan tingkat region terbatas pada region tersebut.

Menghilangkan titik tunggal kegagalan regional, seperti database utama satu region yang dapat menyebabkan pemadaman layanan global jika tidak dapat dijangkau. Perlu diperhatikan bahwa arsitektur multi-region sering kali memerlukan biaya yang lebih mahal, jadi pertimbangkan kebutuhan bisnis dibandingkan biayanya sebelum Anda menerapkan pendekatan ini.

Untuk panduan lebih lanjut tentang cara menerapkan redundansi di seluruh domain gagal, lihat makalah survei Arsitektur Deployment untuk Aplikasi Cloud (PDF).

Menghilangkan hambatan skalabilitas.

Identifikasi komponen sistem yang tidak dapat berkembang melebihi batas resource satu VM atau satu zona. Beberapa aplikasi melakukan penskalaan secara vertikal, tempat Anda menambahkan lebih banyak core CPU, memori, atau bandwidth jaringan pada satu instance VM untuk menangani peningkatan beban. Aplikasi ini memiliki batasan ketat pada skalabilitasnya, dan Anda sering kali harus mengonfigurasinya secara manual untuk menangani pertumbuhan.

Jika memungkinkan, desain ulang komponen tersebut untuk melakukan penskalaan secara horizontal, seperti dengan sharding, atau partisi, di seluruh VM atau zona. Untuk menangani pertumbuhan traffic atau penggunaan, Anda menambahkan lebih banyak shard. Gunakan jenis VM standar yang dapat ditambahkan secara otomatis untuk menangani peningkatan beban per shard. Untuk informasi selengkapnya, lihat Pola untuk aplikasi yang skalabel dan tangguh.

Jika tidak dapat mendesain ulang aplikasi, Anda dapat mengganti komponen yang dikelola oleh Anda dengan layanan cloud terkelola sepenuhnya yang didesain untuk diskalakan secara horizontal tanpa tindakan pengguna.

Menurunkan level layanan dengan baik saat kelebihan beban

Desain layanan Anda agar dapat menoleransi kelebihan beban. Layanan harus mendeteksi kelebihan beban dan menampilkan respons berkualitas lebih rendah kepada pengguna atau menurunkan traffic sebagian, bukan gagal sepenuhnya karena kelebihan beban.

Misalnya, layanan dapat merespons permintaan pengguna dengan halaman web statis dan untuk sementara menonaktifkan perilaku dinamis yang lebih mahal untuk diproses. Perilaku ini dijelaskan dalam pola failover pemanasan dari Compute Engine ke Cloud Storage. Atau, layanan dapat mengizinkan operasi hanya baca dan menonaktifkan update data untuk sementara.

Operator harus diberi tahu untuk memperbaiki kondisi error saat layanan mengalami penurunan.

Mencegah dan mengurangi lonjakan traffic

Jangan sinkronkan permintaan lintas klien. Terlalu banyak klien yang mengirim traffic secara instan akan menyebabkan lonjakan traffic yang mungkin menyebabkan kegagalan beruntun.

Terapkan strategi mitigasi lonjakan pada sisi server seperti throttling, queueing, penghentian beban, atau pemutusan sirkuit, degradasi halus, dan memprioritaskan permintaan penting.

Strategi mitigasi pada klien mencakup throttling sisi klien dan backoff eksponensial dengan jitter.

Membersihkan dan memvalidasi input

Untuk mencegah input yang salah, acak, atau berbahaya dan menyebabkan pemadaman layanan atau pelanggaran keamanan, bersihkan dan validasi parameter input untuk API dan alat operasional. Misalnya, Apigee dan Google Cloud Armor dapat membantu melindungi dari serangan injection.

Gunakan pengujian fuzz secara teratur jika tes otomatis sengaja memanggil API dengan input acak, kosong, atau terlalu besar. Lakukan pengujian ini di lingkungan pengujian yang terisolasi.

Alat operasional harus otomatis memvalidasi perubahan konfigurasi sebelum perubahan diluncurkan, dan harus menolak perubahan jika validasi gagal.

Fail safe dengan tetap mempertahankan fungsi

Jika terjadi kegagalan karena suatu masalah, komponen sistem akan gagal dengan cara yang memungkinkan keseluruhan sistem untuk terus berfungsi. Masalah ini dapat berupa bug software, input atau konfigurasi yang buruk, pemadaman instance yang tidak direncanakan, atau error manusia. Proses layanan Anda akan membantu menentukan apakah Anda harus terlalu permisif atau terlalu sederhana, bukan terlalu ketat.

Pertimbangkan contoh skenario berikut dan cara merespons kegagalan:

  • Biasanya lebih baik jika komponen firewall dengan konfigurasi yang buruk atau kosong tidak terbuka dan memungkinkan traffic jaringan yang tidak sah melewati dalam waktu singkat sementara operator memperbaiki error tersebut. Perilaku ini membuat layanan tetap tersedia, bukan mengalami kegagalan tertutup dan memblokir 100% traffic. Layanan harus mengandalkan pemeriksaan autentikasi dan otorisasi yang lebih dalam pada stack aplikasi untuk melindungi area sensitif saat semua traffic melewatinya.
  • Namun, sebaiknya komponen server izin yang mengontrol akses ke data pengguna gagal ditutup dan memblokir semua akses. Perilaku ini menyebabkan pemadaman layanan saat konfigurasinya rusak, tetapi menghindari risiko kebocoran data rahasia pengguna jika gagal dibuka.

Dalam kedua kasus tersebut, kegagalan akan memunculkan pemberitahuan berprioritas tinggi sehingga operator dapat memperbaiki kondisi error. Komponen layanan harus mencegah terjadinya kegagalan operasi kecuali jika hal ini menimbulkan risiko ekstrem bagi bisnis.

Desain panggilan API dan perintah agar dapat dicoba lagi

API dan alat operasional harus membuat pemanggilan aman untuk dicoba ulang sejauh mungkin. Pendekatan alami untuk banyak kondisi error adalah mencoba kembali tindakan sebelumnya, tetapi Anda mungkin tidak tahu apakah percobaan pertama berhasil.

Arsitektur sistem Anda harus membuat tindakan yang idempoten - jika Anda melakukan tindakan yang identik pada sebuah objek dua kali atau lebih secara berturut-turut, tindakan tersebut akan memberikan hasil yang sama dengan satu pemanggilan. Tindakan non-idempoten memerlukan kode yang lebih kompleks untuk menghindari kerusakan status sistem.

Mengidentifikasi dan mengelola dependensi layanan

Desainer dan pemilik layanan harus mempertahankan daftar lengkap dependensi pada komponen sistem lainnya. Desain layanan juga harus menyertakan pemulihan dari kegagalan dependensi, atau degradasi halus jika pemulihan penuh tidak memungkinkan. Hitung dependensi pada layanan cloud yang digunakan oleh sistem Anda dan dependensi eksternal, seperti API layanan pihak ketiga, yang memahami bahwa setiap dependensi sistem memiliki tingkat kegagalan yang bukan nol.

Saat Anda menetapkan target keandalan, ketahuilah bahwa SLO untuk layanan dibatasi secara matematis oleh SLO semua dependensi pentingnya. Anda tidak boleh lebih andal daripada SLO terendah salah satu dependensi. Untuk informasi selengkapnya, lihat kalkulus ketersediaan layanan.

Dependensi startup

Layanan berperilaku berbeda saat dimulai dibandingkan dengan perilaku status stabil. Dependensi startup dapat berbeda secara signifikan dengan dependensi runtime stabil.

Misalnya, saat startup, layanan mungkin perlu memuat informasi pengguna atau akun dari layanan metadata pengguna yang jarang dipanggil lagi. Jika banyak replika layanan dimulai ulang setelah error atau pemeliharaan rutin, replika dapat secara tajam meningkatkan beban pada dependensi startup, terutama jika cache kosong dan perlu diisi ulang.

Menguji startup layanan saat dimuat, dan menyediakan dependensi startup sebagaimana mestinya. Pertimbangkan desain untuk melakukan degradasi halus dengan menyimpan salinan data yang diambil dari dependensi startup penting. Perilaku ini memungkinkan layanan Anda memulai ulang dengan data yang berpotensi tidak berlaku, bukan tidak dapat dimulai saat dependensi penting mengalami pemadaman. Nantinya, layanan Anda dapat memuat data baru, jika memungkinkan, untuk dikembalikan ke operasi normal.

Dependensi startup juga penting saat Anda mem-bootstrap layanan di lingkungan baru. Desain stack aplikasi Anda dengan arsitektur berlapis, tanpa dependensi siklik antarlapisan. Dependensi siklik mungkin tampak dapat dipertahankan karena tidak memblokir perubahan inkremental pada satu aplikasi. Namun, dependensi siklik dapat menyulitkan atau tidak memungkinkan untuk memulai ulang setelah bencana menghapus seluruh stack layanan.

Meminimalkan dependensi kritis.

Minimalkan jumlah dependensi penting untuk layanan Anda, yaitu komponen lain yang kegagalannya pasti akan menyebabkan pemadaman layanan untuk layanan Anda. Agar layanan lebih tahan terhadap kegagalan atau kelambatan dalam komponen lain yang menjadi tempatnya bergantung, pertimbangkan contoh teknik dan prinsip desain berikut untuk mengonversi dependensi penting menjadi dependensi yang tidak begitu penting:

  • Tingkatkan level redundansi dalam dependensi kritis. Dengan menambahkan lebih banyak replika akan mengurangi kemungkinan seluruh komponen tidak tersedia.
  • Gunakan permintaan asinkron ke layanan lain, bukan memblokir respons atau menggunakan pesan publikasikan/berlangganan untuk memisahkan permintaan dari respons.
  • Simpan respons dari layanan lain ke dalam cache untuk pulih dari tidak tersedianya dependensi dalam jangka pendek.

Untuk merender kegagalan atau kelambatan dalam layanan Anda agar tidak terlalu berbahaya bagi komponen lain yang bergantung padanya, pertimbangkan contoh teknik dan prinsip desain berikut:

  • Gunakan antrean permintaan yang diprioritaskan dan berikan prioritas yang lebih tinggi untuk permintaan yang sedang ditunggu responsnya oleh pengguna.
  • Sajikan respons dari cache untuk mengurangi latensi dan beban.
  • Fail safe dengan tetap mempertahankan fungsi
  • Turunkan kualitas dengan baik saat terjadi kelebihan beban.

Memastikan setiap perubahan dapat di-roll back

Jika tidak ada cara yang jelas untuk mengurungkan jenis perubahan tertentu pada layanan, ubah desain layanan untuk mendukung rollback. Uji proses rollback secara berkala. API untuk setiap komponen atau microservice harus diberi versi, dengan kompatibilitas mundur sehingga klien generasi sebelumnya terus berfungsi dengan benar seiring berkembangnya API. Prinsip desain ini sangat penting untuk mengizinkan peluncuran bertahap perubahan API, dengan rollback cepat jika diperlukan.

Rollback dapat memerlukan banyak biaya untuk diterapkan pada aplikasi seluler. Firebase Remote Config adalah layanan Google Cloud untuk mempermudah rollback fitur.

Anda tidak dapat melakukan roll back perubahan skema database dengan mudah, jadi jalankan perubahan dalam beberapa fase. Desain setiap fase untuk mengizinkan pembacaan dan update skema yang aman berdasarkan versi terbaru aplikasi Anda, dan versi sebelumnya. Pendekatan desain ini memungkinkan Anda melakukan roll back dengan aman jika ada masalah dengan versi terbaru.

Rekomendasi

Untuk menerapkan panduan dalam Framework Arsitektur ke lingkungan Anda sendiri, ikuti rekomendasi berikut:

  • Terapkan backoff eksponensial dengan pengacakan dalam logika percobaan ulang error aplikasi klien.
  • Implementasikan arsitektur multi-region dengan failover otomatis untuk ketersediaan tinggi.
  • Gunakan load balancing untuk mendistribusikan permintaan pengguna di seluruh shard dan region.
  • Desain aplikasi untuk menurunkan tingkat secara halus saat terjadi overload. Sajikan respons sebagian atau sediakan fungsi terbatas, bukan gagal sepenuhnya.
  • Jalankan proses berbasis data untuk perencanaan kapasitas, dan gunakan uji beban dan perkiraan traffic untuk menentukan kapan harus menyediakan resource.
  • Tetapkan prosedur pemulihan dari bencana (disaster recovery), dan lakukan pengujian secara berkala.

Langkah selanjutnya

Pelajari kategori lain di Framework Arsitektur seperti desain sistem, keunggulan operasional, serta keamanan, privasi, dan kepatuhan.