Houston kita punya masalah. Kegagalan Desain Sistem

Pada tahun 1970, insinyur Amerika meluncurkan pesawat ruang angkasa Apollo 13 ke bulan. Di papan ada tiga baterai sel bahan bakar, tidak ada yang perlu dikhawatirkan, semuanya dapat diandalkan dan berulang kali digandakan. Tapi tidak ada yang bisa membayangkan bahwa ledakan tabung oksigen akan menonaktifkan dua dari tiga baterai. Tragedi! Para astronot kembali ke rumah, sebuah film dibuat tentang acara dengan Tom Hanks, dan ungkapan astronot Jack Swigert: "Houston, kami memiliki masalah!", Turun dalam sejarah.



Kisah Apollo 13 adalah bukti lain dari fakta terkenal bahwa Anda tidak dapat mempersiapkan diri untuk semua masalah yang mungkin terjadi. Ini adalah properti alami dunia: pemecah besi secara berkala, kode mengalami crash, dan orang-orang membuat kesalahan. Tidak mungkin untuk sepenuhnya menghilangkan ini.

Untuk sistem terdistribusi besar, perilaku ini normal, itu adalah konsekuensi dari skala ekonomi dan statistik. Itulah sebabnya Design for Failure (AWS) adalah prinsip desain dasar untuk layanan cloud AWS. Sistem pada awalnya dibangun sedemikian rupa untuk memulihkan operasi penuh waktu secepat mungkin dan meminimalkan kerusakan dari kegagalan yang diketahui dan belum diketahui. Di HighLoad ++, Vasily Pantyukhin, menggunakan masalah kehidupan nyata dengan layanan tempur sebagai contoh, menunjukkan pola desain untuk sistem terdistribusi yang digunakan pengembang AWS.

Vasily Pantyukhin (Induk ayam) Adalah arsitek Amazon Web Services di Eropa, Timur Tengah dan Afrika. Dia mulai sebagai administrator Unix, bekerja di Sun Microsystem selama 6 tahun, mengajar kursus teknis, dan selama 11 tahun dia mengajar sentrisitas data dunia di EMC. Dalam tim internasional, ia merancang dan mengimplementasikan proyek-proyek dari Cape Town ke Oslo. Sekarang ini membantu perusahaan besar dan kecil untuk bekerja di cloud publik.


Pada tahun 1949, sebuah kecelakaan pesawat terbang diselidiki di pangkalan angkatan udara California. Salah satu insinyur yang melakukan ini adalah Edward Murphy. Dia menggambarkan pekerjaan teknisi lokal sebagai berikut: "Jika ada dua cara untuk melakukan sesuatu dan salah satunya menyebabkan bencana, maka seseorang akan memilih metode ini."

Belakangan, berkat Arthur Bloch, pernyataan itu tercatat dalam sejarah sebagai salah satu hukum Murphy. Di Rusia - hukum kekejaman. Esensinya adalah bahwa tidak mungkin untuk menghindari kerusakan dan kesalahan manusia, dan harus hidup dengannya. Itulah sebabnya, ketika merancang, kami segera memasukkan kegagalan dan kegagalan komponen individu ke dalam sistem kami.

Desain Kegagalan


Dalam desain untuk kegagalan, kami mencoba meningkatkan tiga karakteristik:

  • aksesibilitas ("sembilan" yang sama);
  • keandalan - properti sistem untuk memberikan tingkat layanan yang diperlukan;
  • toleransi kesalahan - properti sistem untuk mencegah terjadinya masalah dan pulih dengan cepat setelah mereka.

Keandalan memiliki properti " diketahui tidak dikenal ". Kami melindungi diri dari masalah yang diketahui, tetapi tidak tahu kapan itu akan terjadi.

" Unknown unknowns" ditambahkan ke toleransi kesalahan - ini adalah masalah kejutan yang tidak kita ketahui. Banyak masalah di cloud ini terkait dengan skala ekonomis: sistem tumbuh dengan ukuran ketika efek baru, luar biasa, dan tak terduga muncul.

Kegagalan biasanya bukan fenomena biner. Properti utamanya adalah "radius ledakan" atau tingkat degradasi layanan, radius kehancuran. Tugas kita adalah mengurangi "radius ledakan" sistem.

Jika kita menyadari bahwa masalah tidak dapat dihindari, maka kita harus secara proaktif mempersiapkan mereka. Ini berarti bahwa kami merancang layanan sedemikian rupa sehingga jika terjadi masalah (mereka pasti akan), kami mengendalikan masalah, dan bukan sebaliknya.
Ketika kita menanggapi suatu masalah, itu mengendalikan kita.

Bidang data dan bidang Kontrol


Tentunya, Anda memiliki elektronik di rumah yang dikendalikan oleh remote control, seperti TV. Layar TV adalah bagian dari bidang Data - yang secara langsung menjalankan fungsi. Remote control adalah antarmuka pengguna - Control plane. Ini digunakan untuk mengelola dan mengkonfigurasi layanan. Di cloud, kami mencoba memisahkan bidang Data dan bidang Kontrol untuk pengujian dan pengembangan.

Pengguna, paling sering, tidak melihat kerumitan bidang Kontrol. Tetapi kesalahan dalam desain dan implementasinya adalah penyebab paling umum dari kegagalan massal. Itu sebabnya saran saya terfokus pada bidang Kontrol - kadang-kadang secara eksplisit, kadang tidak.

Kisah satu masalah


Pada Juli 2012, badai hebat melanda Virginia Utara. Pusat data memiliki perlindungan, generator diesel dan banyak lagi, tetapi kebetulan bahwa di salah satu pusat data dari salah satu zona ketersediaan (Zona Ketersediaan, AZ) wilayah Virginia Utara, listrik terputus. Listrik dengan cepat dipulihkan, tetapi pemulihan layanan berlangsung selama berjam-jam.



Saya akan memberi tahu Anda tentang alasan pada contoh salah satu layanan dasar - CLB (Classic Load Balancer). Ini berfungsi sederhana: ketika Anda memulai penyeimbang baru di setiap zona ketersediaan, mesin virtual terpisah dibuat, IP-nya akan menyelesaikan DNS.



Ketika salah satu contoh gagal, pesan tentang ini dikirim ke database khusus.



Sebagai tanggapan, prosedur mulai: menghapus catatan dari DNS, memulai instance baru dan menambahkan IP baru ke DNS.

Catatan: Ini adalah bagaimana sistem bekerja di masa lalu, sekarang semuanya berbeda secara mendasar.

Semuanya sederhana - tidak ada yang bisa dipatahkan. Tetapi selama kegagalan massal, ketika ribuan instance runtuh pada saat yang sama, Backlog besar muncul di database dari pesan untuk diproses.



Tapi itu semakin buruk. Pesawat kontrol adalah sistem terdistribusi. Karena bug, kami menerima duplikat dan ribuan catatan dalam basis data membengkak hingga ratusan ribu. Menjadi sangat sulit untuk bekerja dengan ini.

Ketika kegagalan terjadi di salah satu contoh, semua lalu lintas hampir secara instan beralih ke mesin yang masih hidup dan beban berlipat ganda (dalam contoh, untuk kesederhanaan, hanya ada dua zona akses).



Tidak ada sumber daya yang cukup, contoh langsung secara otomatis mulai skala. Prosesnya memakan waktu yang relatif lama. Semuanya terjadi puncak dan pada saat yang sama dengan sejumlah besar contoh - sumber daya gratis zona ketersediaan habis. "Perjuangan" untuk sumber daya dimulai.

Di Virginia Utara, otomatisasi gagal mengatasi kegagalan besar-besaran, dan para insinyur secara manual (menggunakan skrip) mengembalikan layanan agar berfungsi. Masalah seperti itu jarang terjadi. Selama tanya jawab, muncul pertanyaan tentang penyebab kegagalan, mereka memutuskan bahwa situasinya tidak boleh diulangi lagi dan seluruh layanan harus diubah.

Delapan pola yang akan saya bahas adalah jawaban atas beberapa pertanyaan.

Catatan. Ini adalah pengalaman kami dalam desain layanan, bukan kebijakan universal untuk penggunaan luas. Pola digunakan dalam situasi tertentu.

— . AWS . — , . . — . !


Untuk meminimalisir dampak kegagalan, banyak pendekatan. Salah satunya adalah menjawab pertanyaan: "Bagaimana saya bisa memastikan bahwa pengguna yang tidak tahu tentang masalah tidak tahu apa-apa tentang hal itu selama kegagalan dan selama pemulihan?"

Backlog kami yang besar tidak hanya menerima pesan macet, tetapi juga pesan lainnya, misalnya, tentang penskalaan atau bahwa seseorang meluncurkan penyeimbang baru. Pesan-pesan seperti itu perlu diisolasi dari satu sama lain, pengelompokan secara fungsional: sekelompok pesan pemulihan yang terpisah setelah kegagalan, secara terpisah meluncurkan penyeimbang baru.

Misalkan sepuluh pengguna melihat masalah - salah satu simpul penyeimbang mereka jatuh. Layanan entah bagaimana bekerja pada sumber daya yang tersisa, tetapi masalahnya terasa.



Kami memiliki sepuluh pengguna yang frustrasi. Kesebelas muncul - dia tidak tahu apa-apa tentang masalahnya, tetapi hanya menginginkan penyeimbang baru. Jika permintaannya untuk meletakkan antrian untuk diproses, maka kemungkinan besar dia tidak akan menunggu. Sementara prosedur pemrosesan lainnya selesai, waktu permintaan akan berakhir. Alih-alih sepuluh pengguna yang frustrasi, kami akan memiliki sebelas.

Untuk mencegah hal ini terjadi, kami memprioritaskan beberapa permintaan - kami menempatkan antrian di bagian atas, misalnya, permintaan untuk sumber daya baru. Dengan kegagalan massal, sejumlah kecil permintaan semacam itu tidak akan memengaruhi waktu pemulihan sumber daya pelanggan lain. Namun dalam proses pemulihan, kami akan menahan jumlah pengguna yang terlibat dalam masalah tersebut.

Pekerjaan penuh waktu


Respons terhadap laporan masalah adalah peluncuran prosedur pemulihan, khususnya, bekerja dengan DNS. Kegagalan massal adalah beban puncak yang sangat besar pada bidang Kontrol. Pola kedua membantu pesawat Kontrol menjadi lebih stabil dan dapat diprediksi dalam situasi seperti itu.



Kami menggunakan pendekatan yang disebut pekerjaan Konstan - pekerjaan permanen .



Sebagai contoh, DNS dapat dibuat sedikit lebih pintar: ia akan terus memeriksa contoh penyeimbang, apakah mereka hidup atau tidak. Hasilnya akan berupa bitmap setiap kali: instance merespons - 1, mati - 0.

DNS memeriksa instance setiap beberapa detik, terlepas dari apakah sistem dipulihkan setelah kegagalan massal atau beroperasi secara normal. Dia melakukan pekerjaan yang sama - tidak ada puncak, semuanya dapat diprediksi dan stabil.

Contoh lain yang disederhanakan: kami ingin mengubah konfigurasi pada armada besar. Dalam terminologi kami, armada adalah sekelompok mesin virtual yang bersama-sama melakukan beberapa pekerjaan.



Kami menempatkan perubahan konfigurasi di bucket S3, dan setiap 10 detik (misalnya) mendorong semua konfigurasi ini ke armada mesin virtual kami. Dua poin penting.

  • Kami melakukan ini secara teratur dan tidak pernah melanggar aturan. Jika Anda memilih segmen 10 detik, maka tekan hanya dengan cara ini, apa pun situasinya.
  • Kami selalu memberikan seluruh konfigurasi , terlepas dari apakah sudah berubah atau belum. Pesawat data (mesin virtual) sendiri memutuskan apa yang harus dilakukan dengannya. Kami tidak mendorong delta. Itu bisa menjadi sangat besar dengan gangguan atau perubahan besar. Secara potensial, ini dapat berkontribusi pada ketidakstabilan dan ketidakpastian.

Ketika kami melakukan semacam pekerjaan permanen, kami membayar lebih untuk itu. Misalnya, 100 mesin virtual meminta konfigurasi setiap detik. Harganya sekitar $ 1.200 per tahun. Jumlah ini pada dasarnya kurang dari gaji seorang programmer, kepada siapa kita bisa mempercayakan pengembangan pesawat Control dengan pendekatan klasik - reaksi terhadap kegagalan dan distribusi perubahan konfigurasi saja.

Jika Anda mengubah konfigurasi setiap beberapa detik, seperti dalam contoh, maka ini lambat. Tetapi dalam banyak kasus, perubahan konfigurasi atau peluncuran layanan membutuhkan waktu beberapa menit - beberapa detik tidak menyelesaikan apa pun.

Detik penting untuk layanan di mana konfigurasi harus berubah secara instan, misalnya, ketika mengubah pengaturan VPC. Di sini "pekerjaan tetap" tidak berlaku. Ini hanya sebuah pola, bukan aturan. Jika ini tidak berhasil dalam kasus Anda, jangan gunakan.

Penskalaan awal


Dalam contoh kita, ketika instance penyeimbang crash, instance penyintas kedua menerima beban yang berlipat hampir dengan segera dan mulai menskala. Dalam kegagalan besar, ia memakan banyak sumber daya. Pola ketiga membantu untuk mengendalikan proses ini - untuk skala di muka .

Dalam kasus dua zona ketersediaan, kami mengukur saat membuang kurang dari 50%.



Jika semuanya dilakukan di muka, maka jika terjadi kegagalan, instance penyeimbang yang bertahan siap untuk menerima lalu lintas berlipat ganda.

Sebelumnya, kami diskalakan hanya dengan pemanfaatan tinggi, misalnya, 80%, dan sekarang 45%. Sistem idle sebagian besar waktu dan menjadi lebih mahal. Tetapi kami siap untuk bertahan dengan ini dan secara aktif menggunakan polanya, karena ini adalah asuransi. Anda harus membayar asuransi, tetapi jika terjadi masalah serius, kemenangan tersebut mencakup semua biaya. Jika Anda memutuskan untuk menggunakan polanya, hitung semua risiko dan harga di muka.

Arsitektur seluler


Ada dua cara untuk membangun dan meningkatkan layanan: monolit dan struktur sarang lebah (berbasis sel).



Monolith berkembang dan tumbuh sebagai wadah besar tunggal. Kami menambahkan sumber daya, sistem membengkak, kami berlari ke batas yang berbeda, karakteristik linier menjadi non-linear dan menjadi jenuh, dan "radius ledakan" dari sistem - seluruh sistem.

Jika monolit diuji dengan buruk, itu meningkatkan kemungkinan kejutan - "tidak diketahui tidak diketahui". Tetapi monolit besar tidak dapat sepenuhnya diuji. Terkadang untuk ini Anda harus membangun zona akses terpisah, misalnya, untuk layanan populer yang dibangun sebagai monolit di dalam zona akses (ini banyak pusat data). Selain entah bagaimana membuat beban uji besar yang mirip dengan saat ini, ini tidak mungkin dari sudut pandang keuangan.

Oleh karena itu, dalam kebanyakan kasus, kami menggunakan arsitektur seluler - konfigurasi di mana sistem dibangun dari sel dengan ukuran tetap. Dengan menambahkan sel, kami skala itu.

Arsitektur seluler populer di awan AWS. Ini membantu mengisolasi gangguan dan mengurangi radius ledakan.ke satu atau lebih sel. Kami dapat sepenuhnya menguji sel berukuran sedang, ini serius mengurangi risiko.

Pendekatan serupa digunakan dalam pembuatan kapal: lambung kapal atau kapal dibagi dengan partisi menjadi kompartemen. Jika ada lubang, satu atau beberapa kompartemen terendam, tetapi kapal tidak tenggelam. Ya, itu tidak membantu Titanic, tetapi kami jarang menemui masalah gunung es.

Saya akan menggambarkan penerapan pendekatan mesh menggunakan Layanan Simple Shapes sebagai contoh. Ini bukan layanan AWS, saya datang sendiri. Ini adalah satu set API sederhana untuk bekerja dengan bentuk geometris sederhana. Anda bisa membuat turunan bentuk geometris, meminta jenis bentuk berdasarkan idnya, atau menghitung semua contoh jenis yang diberikan. Misalnya, objek put(triangle)"segitiga" dengan beberapa id dibuat berdasarkan permintaan .getShape(id)mengembalikan tipe "segitiga", "lingkaran" atau "belah ketupat".



Untuk membuat layanan mendung, itu harus digunakan oleh pengguna yang berbeda secara bersamaan. Mari membuatnya multi-tenant.



Selanjutnya, Anda perlu membuat cara untuk partisi - untuk memisahkan angka menjadi sel. Ada beberapa opsi untuk memilih kunci partisi. Yang paling sederhana adalah dalam bentuk geometris : semua rhombus di sel pertama, lingkaran di kedua, segitiga di ketiga.

Metode ini memiliki pro dan kontra.

  • Jika terdapat lebih sedikit lingkaran daripada gambar lain, maka sel yang sesuai akan tetap kurang dimanfaatkan (distribusi tidak merata).
  • Beberapa permintaan API mudah diimplementasikan. Misalnya, dengan menghitung semua objek di sel kedua, kami menemukan jumlah lingkaran dalam sistem.
  • Pertanyaan lain lebih rumit. Misalnya, untuk menemukan bentuk geometris dengan id, Anda harus melalui semua sel.

Cara kedua adalah dengan menggunakan id objek dengan rentang : seribu objek pertama di sel pertama, yang kedua di kedua. Jadi distribusinya lebih seragam, tetapi ada kesulitan lain. Misalnya, untuk menghitung semua segitiga, Anda perlu menggunakan metode ini scatter/gather: kami mendistribusikan permintaan ke setiap sel, itu menghitung segitiga di dalam dirinya sendiri, kemudian mengumpulkan jawaban, merangkum dan menghasilkan hasilnya.

Cara ketiga - divisi penyewa(kepada pengguna). Di sini kita dihadapkan dengan masalah klasik. Biasanya ada banyak pengguna "kecil" di cloud yang mencoba sesuatu dan praktis tidak memuat layanan. Ada pengguna mastodon. Mereka sedikit, tetapi mereka mengkonsumsi sejumlah besar sumber daya. Pengguna tersebut tidak akan pernah masuk ke dalam sel apa pun. Anda harus menemukan cara rumit untuk mendistribusikannya di antara banyak sel.



Tidak ada cara yang ideal, setiap layanan bersifat individual. Kabar baiknya adalah bahwa kebijaksanaan duniawi bekerja di sini - memotong kayu bakar lebih mudah dilakukan di sepanjang serat, daripada memotongnya. Dalam banyak layanan, "serat" ini kurang lebih jelas. Kemudian Anda dapat melakukan percobaan dan menemukan kunci partisi yang optimal.

Sel saling berhubungan (walaupun lemah). Karena itu, harus ada level penghubung. Seringkali disebut layer routing atau pemetaan. Diperlukan untuk memahami sel mana untuk mengirim permintaan khusus. Level ini harus sesederhana mungkin. Cobalah untuk tidak meletakkan logika bisnis di dalamnya.



Muncul pertanyaan tentang ukuran sel: kecil - buruk, besar - juga buruk. Tidak ada saran universal - putuskan sesuai situasi.

Di cloud AWS, kami menggunakan sel logis dan fisik dengan ukuran berbeda. Ada layanan regional dengan ukuran sel besar, ada layanan zona, di mana sel lebih kecil.



Catatan. Saya berbicara tentang sel mikro di Saint Highload ++ Online pada awal April tahun ini. Di sana saya membahas secara rinci contoh penggunaan khusus pola ini dalam layanan inti EBS Amazon kami.

Multi-tenant


Ketika pengguna meluncurkan penyeimbang baru, ia menerima contoh di setiap zona ketersediaan. Terlepas dari apakah sumber daya digunakan atau tidak, sumber daya tersebut dialokasikan dan secara eksklusif dimiliki oleh penyewa cloud ini.

Untuk AWS, pendekatan ini tidak efisien, karena pemanfaatan sumber daya layanan rata-rata sangat rendah. Ini mempengaruhi biaya. Untuk pengguna cloud, ini bukan solusi yang fleksibel. Ini tidak dapat beradaptasi dengan kondisi yang berubah dengan cepat, misalnya, untuk menyediakan sumber daya dengan peningkatan beban yang tidak terduga dalam waktu singkat.



CLB adalah penyeimbang pertama di cloud Amazon. Layanan saat ini menggunakan pendekatan multi-tenant, seperti NLB (Network Load Balancer). Dasarnya, "mesin" dari layanan jaringan tersebut adalah HyperPlane. Ini adalah internal, tidak terlihat oleh pengguna akhir, armada besar mesin virtual (node).



Keuntungan dari pendekatan multi-tenant atau pola kelima.

  • Toleransi kesalahan secara fundamental lebih tinggi . Di HyperPlane, sejumlah besar node sudah berjalan dan sedang menunggu beban. Node mengetahui keadaan satu sama lain - ketika beberapa sumber daya gagal, beban didistribusikan secara instan di antara yang lainnya. Pengguna bahkan tidak melihat crash massal.
  • Perlindungan beban puncak . Penyewa menjalani hidup mereka sendiri dan beban mereka biasanya tidak berkorelasi satu sama lain. Total beban rata-rata di HyperPlane cukup mulus.
  • Pemanfaatan layanan tersebut secara fundamental lebih baik . Karena itu, memberikan kinerja yang lebih baik, mereka lebih murah.

Itu terdengar keren! Tetapi pendekatan multitenant memiliki kelemahan. Dalam gambar, armada HyperPlane dengan tiga penyewa (belah ketupat, lingkaran dan segitiga), yang didistribusikan di semua node .



Ini menimbulkan masalah klasik Tetangga tetangga: tindakan destruktif penyewa, yang menghasilkan lalu lintas sangat tinggi atau buruk, berpotensi akan mempengaruhi semua pengguna.



"Blast radius" dalam sistem seperti itu adalah semua penyewa. Kemungkinan “tetangga berisik” destruktif di zona ketersediaan AWS sebenarnya tidak tinggi. Tetapi kita harus selalu siap untuk yang terburuk. Kami membela diri menggunakan pendekatan mesh - kami memilih kelompok node sebagai sel. Dalam konteks ini, kami menyebutnya pecahan. Sel, pecahan, partisi - ini dia satu dan sama.



Dalam contoh ini, belah ketupat, sebagai "tetangga yang bising", hanya akan memengaruhi satu penyewa - sebuah segitiga. Tapi segitiga itu akan sangat menyakitkan. Untuk memperlancar efek, terapkan pola keenam - pencampuran sharding.

Mengocok sharding


Kami mendistribusikan penyewa secara acak ke node. Sebagai contoh, sebuah belah ketupat mendarat pada 1, 3, dan 6 node, dan segitiga pada 2, 6, dan 8. Kami memiliki 8 node dan beling ukuran 3.



Di sini, kombinatorik sederhana bekerja. Dengan probabilitas 54%, hanya akan ada satu persimpangan antara penyewa.



"Tetangga yang bising" hanya akan memengaruhi satu penyewa, dan bukan seluruh beban, tetapi hanya 30 persen.

Pertimbangkan konfigurasi yang mendekati real - 100 node, ukuran beling 5. Dengan probabilitas 77%, tidak akan ada persimpangan sama sekali.



Shuffle sharding dapat secara signifikan mengurangi "radius ledakan". Pendekatan ini digunakan di banyak layanan AWS.

"Armada kecil menyebabkan armada besar, dan bukan sebaliknya"


Ketika memulihkan dari kegagalan massal, kami memperbarui konfigurasi banyak komponen. Pertanyaan umum dalam hal ini adalah mendorong atau mengubah konfigurasi yang diubah? Siapa pemrakarsa perubahan: sumber yang berisi perubahan konfigurasi, atau konsumennya? Tetapi pertanyaan-pertanyaan ini salah. Pertanyaan yang tepat adalah armada mana yang lebih besar?

Pertimbangkan situasi sederhana: armada besar mesin virtual front-end dan sejumlah backend.



Kami menggunakan pendekatan jala - kelompok instance front-end akan bekerja dengan backend tertentu. Untuk melakukan ini, tentukan rute - pemetaan backend dan frontends yang bekerja dengannya.



Routing statis tidak cocok. Algoritme hash tidak berfungsi dengan baik pada kegagalan massal, saat Anda perlu mengubah sebagian besar rute dengan cepat. Karena itu lebih baik digunakanrouting dinamis . Di samping armada besar unit front-end dan back-end, kami menempatkan layanan kecil yang hanya akan menangani perutean. Dia akan tahu dan menetapkan pemetaan backend dan frontend pada waktu tertentu.



Misalkan kita mengalami crash besar, banyak contoh front-end jatuh. Mereka mulai pulih secara besar-besaran dan hampir secara bersamaan meminta konfigurasi pemetaan dari layanan routing.



Layanan perutean kecil dibombardir dengan sejumlah besar permintaan. Dia tidak akan mengatasi beban, dalam kasus terbaik, itu akan menurun, dan yang terburuk dia akan mati.

Karena itu, memang benar untuk tidak meminta perubahan konfigurasi dari layanan kecil, melainkan membangun sistem Anda sehingga "bayi" itu sendiriperubahan konfigurasi yang diprakarsai terhadap sejumlah besar instance .



Kami menggunakan pola kerja konstan. Layanan perutean kecil akan mengirimkan konfigurasi ke semua instance armada front-end sekali setiap beberapa detik. Dia tidak akan pernah bisa membebani layanan hebat. Pola ketujuh membantu meningkatkan stabilitas dan ketahanan .

Tujuh pola pertama meningkatkan sistem. Pola yang terakhir bekerja secara berbeda.

Menjatuhkan beban


Di bawah ini adalah grafik klasik dari penundaan versus beban. Di sisi kanan grafik adalah "lutut", ketika pada beban yang sangat tinggi bahkan peningkatan kecil menyebabkan peningkatan signifikan dalam latensi.


Dalam mode normal, kami tidak pernah membawa layanan kami ke sisi kanan jadwal. Cara mudah untuk mengontrol ini adalah menambahkan sumber daya tepat waktu. Tapi kami sedang bersiap-siap untuk masalah. Sebagai contoh, kita dapat bergerak ke sisi kanan grafik pulih dari kegagalan massa.

Kami menempatkan batas waktu klien pada tabel. Siapa pun dapat menjadi klien, misalnya, komponen lain di dalam layanan kami. Untuk kesederhanaan, kami menggambar grafik keterlambatan 50 persen.



Di sini kita dihadapkan dengan situasi yang disebut brownout . Anda mungkin akrab dengan istilah pemadaman listrik ketika listrik terputus di kota. Brownout adalah ketika sesuatu bekerja, tetapi sangat buruk dan lambat sehingga, dihitung, itu tidak bekerja sama sekali

Mari kita lihat zona brown brownout. Layanan menerima permintaan dari klien, memprosesnya dan mengembalikan hasilnya. Namun, dalam setengah kasus, klien sudah kehabisan waktu dan tidak ada yang menunggu hasilnya. Di separuh lainnya, hasilnya kembali lebih cepat dari batas waktu, tetapi dalam sistem yang lambat itu membutuhkan terlalu banyak waktu.

Kami menghadapi masalah ganda: kami sudah kelebihan beban dan berada di sisi kanan jadwal, tetapi pada saat yang sama kami masih "menghangatkan udara", melakukan banyak pekerjaan yang tidak berguna. Bagaimana cara menghindarinya?

Temukan "lutut" - titik belok pada bagan . Kami mengukur atau memperkirakan secara teoritis.

Jatuhkan traffic yang memaksa kita untuk pergi ke kanan titik belok .



Kami hanya harus mengabaikan sebagian dari permintaan. Kami bahkan tidak mencoba memprosesnya, tetapi segera mengembalikan kesalahan kepada klien. Bahkan dengan kelebihan beban, kami mampu melakukan operasi ini - ini “murah”. Permintaan tidak terpenuhi, ketersediaan keseluruhan layanan berkurang. Meskipun permintaan yang ditolak akan diproses cepat atau lambat setelah satu atau beberapa percobaan dari klien.



Pada saat yang sama, bagian lain dari permintaan diproses dengan latensi rendah yang dijamin. Akibatnya, kita tidak melakukan pekerjaan yang tidak berguna, dan apa yang kita lakukan, kita lakukan dengan baik.

Perasan singkat pola desain sistem untuk kegagalan


Isolasi dan regulasi . Terkadang masuk akal untuk memprioritaskan jenis kueri tertentu. Misalnya, dengan volume permintaan yang relatif kecil untuk membuat sumber daya baru, mereka dapat ditempatkan di bagian atas antrian. Penting bahwa ini tidak melanggar pengguna lain. Dalam pemadaman masif, pengguna yang menunggu sumber daya mereka pulih tidak akan merasakan perbedaan yang signifikan.

Pekerjaan penuh waktu . Mengurangi atau sepenuhnya menghilangkan pergantian mode layanan. Satu mode, yang bekerja secara stabil dan terus-menerus, terlepas dari situasi darurat atau kerja, secara fundamental meningkatkan stabilitas dan prediktabilitas bidang Kontrol.

Penskalaan awal. Skala di muka dengan nilai pembuangan yang lebih rendah. Anda harus membayar sedikit lebih untuk ini, tetapi ini adalah asuransi yang terbayar selama kegagalan sistem yang serius.

Arsitektur seluler . Banyak sel yang digabungkan secara longgar lebih disukai daripada monolit. Pendekatan mesh mengurangi "radius ledakan" dan kemungkinan kesalahan kejutan.

Pendekatan multitenant secara signifikan meningkatkan pemanfaatan layanan, mengurangi biaya dan mengurangi "radius ledakan".

Mengocok sharding . Ini adalah pendekatan yang berlaku untuk layanan multi-tenant. Selain itu memungkinkan Anda untuk mengontrol "radius ledakan".

"Armada kecil menyebabkan armada besar, dan bukan sebaliknya". Kami mencoba membangun layanan sehingga layanan kecil melakukan perubahan pada konfigurasi besar. Kami sering menggunakannya bersamaan dengan pola beban konstan.

Menjatuhkan beban . Dalam situasi darurat, kami hanya mencoba melakukan pekerjaan yang bermanfaat, dan melakukannya dengan baik. Untuk melakukan ini, kami membuang sebagian muatan, yang masih belum dapat kami tangani.

— , Saint HighLoad++ Online. -- , Q&A-, , . - . , - .

telegram- @HighLoadChannel — , .

All Articles