Saran untuk Pemula dalam Sistem Terdistribusi
(somethingsimilar.com)- Kesulitan inti sistem terdistribusi bukanlah latensi melainkan kegagalan parsial, dan bahkan penanganan exception sederhana pada satu mesin menjadi bagian dari desain protokol saat melibatkan banyak mesin
- Sistem terdistribusi yang tangguh memiliki bug yang hanya terlihat pada banyak mesin nyata, kondisi jaringan antarpusat data, dan dataset besar, sehingga biayanya lebih tinggi daripada sistem satu mesin
- Untuk membangun sistem yang dapat dioperasikan, kita harus mengurangi koordinasi dan meningkatkan independensi, serta menjadikan backpressure, ketersediaan parsial, metrik, dan metrik persentil sebagai alat dasar
- Feature flag, desain ruang ID, lokalitas data, dan ekstraksi layanan adalah teknik praktis untuk menurunkan cakupan kegagalan dan biaya koordinasi selama migrasi dan ekspansi
- Teorema CAP lebih dekat sebagai alat kritik desain daripada titik awal membangun sistem, dan dalam sistem terdistribusi, koordinasi sosial antar tim dan organisasi sama sulitnya dengan masalah teknis
Hal yang Mudah Terlewat Saat Pertama Belajar Sistem Terdistribusi
- Banyak pelajaran dari engineer sistem terdistribusi berasal dari kesalahan di lalu lintas produksi dan luka operasional, tetapi engineer pemula memerlukan konteks yang lebih langsung dan dapat ditindaklanjuti
- Fallacies of Distributed Computing dan CAP theorem membantu untuk belajar mandiri, tetapi terlalu abstrak bagi engineer yang belum berpengalaman untuk langsung bergerak
- Sistem terdistribusi membutuhkan lebih banyak mesin dan modal, sehingga lebih mudah melibatkan lebih banyak tim dan organisasi yang lebih besar
- Masalah sosial umumnya merupakan bagian tersulit dari pekerjaan pengembang perangkat lunak, dan dalam pengembangan sistem terdistribusi hal ini bisa semakin menonjol
- Kadang solusi sosial lebih efisien dan memuaskan daripada solusi teknis, tetapi latar belakang, pendidikan, dan pengalaman sering mendorong engineer ke arah solusi teknis
Mendesain dengan Asumsi Kegagalan dan Biaya
- Sistem terdistribusi sering gagal, dan yang lebih buruk, gagal secara parsial
- Kegagalan
mutex unlockpada proses tunggal mungkin cukup ditangani dengan membuat proses crash, tetapi kegagalanunlockpada mutex terdistribusi harus dimasukkan ke dalam protokol lock itu sendiri - Pendekatan seperti “cukup kirim write ke dua mesin” atau “retry sampai berhasil” tidak cukup menangani situasi ketika hanya satu write yang berhasil dan yang lain gagal
- Bisa terjadi kegagalan switch, hilangnya leader akibat
GC pause, kegagalan jarak jauh padasocket writeyang tampak berhasil, atau satu disk lambat yang memperlambat seluruh protokol komunikasi klaster
- Kegagalan
- Solusi terdistribusi yang tangguh lebih mahal daripada solusi satu mesin
- Ada kegagalan yang hanya muncul pada banyak mesin, dan VM serta cloud memang menurunkan biaya, tetapi tetap tidak semurah merancang, mengimplementasikan, dan menguji pada satu komputer yang sudah dimiliki
- Kegagalan yang hanya tampak pada ukuran dataset yang tak muat di mesin bersama atau pada kondisi jaringan pusat data memerlukan lingkungan terdistribusi yang nyata
- Simulasi berguna, tetapi tidak bisa menggantikan semua bug sistem terdistribusi
- Sistem terdistribusi open source yang tangguh jauh lebih jarang daripada sistem satu mesin yang tangguh
- Biaya menjalankan banyak mesin dalam waktu lama menjadi beban bagi komunitas open source
- Pengembang hobi dan dilettante membuat open source dengan mesin yang sudah mereka miliki dan waktu luang mereka, sehingga sulit menemukan pengembang yang mau menyalakan, memelihara, dan membayar banyak mesin
- Engineer perusahaan memang mengisi sebagian kekosongan, tetapi prioritas organisasi mereka bisa tidak selaras dengan prioritas organisasi pengguna
Mengurangi Koordinasi dan Menyerap Gangguan
- Koordinasi antar mesin harus dihindari sebisa mungkin
- Inti skalabilitas horizontal adalah menempatkan data sedemikian independen sehingga kebutuhan mesin untuk saling berkomunikasi dan bersepakat bisa diminimalkan
- Setiap kali dua mesin harus menyepakati sesuatu, implementasi layanan menjadi lebih sulit
- Ada batas atas pada kecepatan penyampaian informasi, komunikasi jaringan lebih rapuh daripada yang dibayangkan, dan intuisi tentang konsensus bisa keliru
- Memahami Two Generals, Byzantine Generals, dan sulitnya implementasi Paxos akan membantu
- Jika masalah muat di memori, bagi engineer sistem terdistribusi itu biasanya mendekati masalah sepele
- Jauh lebih sulit memproses data dengan cepat ketika data berada di balik beberapa switch, bukan sekadar beberapa pointer
- Algoritme dan implementasi untuk mesin tunggal sangat melimpah, sedangkan literatur dan implementasi untuk sistem terdistribusi jauh lebih sedikit
- “Lambat” adalah masalah yang paling sulit di-debug
- Salah satu atau lebih dari beberapa sistem yang terlibat dalam permintaan pengguna bisa lambat, atau sebagian dari pipeline transformasi yang melintasi banyak mesin bisa lambat
- Deskripsi masalah itu sendiri hampir tidak memberi petunjuk tentang lokasi cacat, dan bisa ada kegagalan parsial tersembunyi yang tidak terlihat di grafik yang biasa dipantau
- Sulit mendapatkan cukup sumber daya seperti waktu, uang, dan alat sebelum penurunan performa menjadi sangat jelas
- Dapper dan Zipkin dibuat karena alasan ini
- Backpressure harus diterapkan di seluruh sistem
- Backpressure adalah cara sistem yang melayani memberi sinyal kegagalan ke sistem peminta, lalu sistem peminta menangani kegagalan itu agar tidak membebani dirinya sendiri maupun sistem lawan
- Membatasi penggunaan resource selama overload atau kegagalan sistem adalah komponen dasar dari sistem terdistribusi yang tangguh
- Implementasinya sering berupa membuang pesan baru atau mengembalikan error ke pengguna saat resource terbatas atau kegagalan terjadi, dan dalam kedua kasus metrik harus ditingkatkan
- Timeout dan exponential backoff wajib ada untuk koneksi dan permintaan ke sistem lain
- Tanpa backpressure, kegagalan berantai atau hilangnya pesan yang tidak disengaja lebih mudah terjadi
- Kita perlu menemukan cara untuk menyediakan ketersediaan parsial
- Ketersediaan parsial adalah kemampuan mengembalikan sebagian hasil meski sebagian sistem gagal
- Sistem pencarian melakukan trade-off antara kualitas hasil dan lamanya pengguna harus menunggu, lalu bisa mengembalikan hanya hasil yang sudah terkumpul setelah batas waktu tercapai
- Dalam private messaging, bisa jadi lebih baik gangguan hanya menimpa sebagian pengguna daripada sebagian pesan hilang untuk semua pengguna
- Perlu diputuskan seberapa jauh domain kegagalan dipisahkan agar gangguan private messaging tidak memengaruhi fitur yang tidak terkait seperti unggah gambar publik
Menjadikan Observabilitas, Kapasitas, dan Deployment sebagai Alat Operasional
- Metrik adalah sarana esensial untuk mengetahui apa yang benar-benar dilakukan sistem di produksi
- Metrik seperti persentil latensi, penghitung kenaikan untuk perilaku tertentu, dan laju perubahan membantu memperkecil jarak antara perilaku sistem yang diyakini dan yang benar-benar terjadi
- Mengetahui bagaimana perilaku sistem pada hari ke-20 berbeda dari hari ke-15 membedakan engineering yang sukses dari perdukunan yang gagal
- Metrik diperlukan untuk memahami masalah dan perilaku, tetapi tidak cukup untuk memberi tahu apa yang harus dilakukan selanjutnya
- File log berguna tetapi mudah berbohong
- Walau beberapa kelas error log memakan porsi besar ruang file, proporsi permintaan nyatanya bisa rendah
- Log sukses kebanyakan redundan dan bisa memenuhi disk, dan engineer sering salah menebak error log mana yang akan berguna
- Sebaiknya log ditulis dengan asumsi akan dibaca oleh orang yang belum pernah melihat kodenya
- Jika keanehan yang terlihat di log dibesar-besarkan tanpa diverifikasi lewat metrik, gangguan bisa berlangsung lebih lama
- Gunakan persentil alih-alih rata-rata
- Persentil 50th, 99th, 99.9th, dan 99.99th lebih akurat dan berguna daripada rata-rata di sebagian besar sistem terdistribusi
- Rata-rata mengasumsikan metrik evaluasi mengikuti distribusi berbentuk lonceng, padahal sangat sedikit metrik penting bagi engineer yang benar-benar demikian
- Jika latensi sistem terdistribusi tidak mengikuti distribusi berbentuk lonceng, rata-rata latensi akan menghasilkan keputusan dan pemahaman yang keliru
- Kita perlu menguasai kemampuan memperkirakan kapasitas
- Mengetahui berapa banyak mesin yang dibutuhkan untuk suatu pekerjaan membedakan sistem yang bertahan lama dari sistem yang harus diganti dalam 3 bulan
- Perkiraan kasar seperti mesin umum pada akhir 2012 memiliki 24GB memori, 4~5GB dibutuhkan OS, beberapa GB minimal untuk menangani permintaan, dan
tweet idberukuran 8 byte tetap diperlukan - Numbers Everyone Should Know dari Jeff Dean membantu membangun ekspektasi
- Feature flag adalah cara merollout infrastruktur
- Feature flag bukan hanya kuat untuk A/B test frontend, tetapi juga untuk penggantian infrastruktur
- Pendekatan “big cutover” telah menggagalkan banyak proyek karena bug yang ditemukan terlambat memaksa rollback
- Saat berpindah dari satu database ke layanan yang menyembunyikan storage baru, kita bisa perlahan meningkatkan pengiriman write paralel ke layanan baru, menguji read setelah backfill selesai tanpa memakainya untuk respons pengguna, lalu membandingkan read lama dan baru sebelum meningkatkan read nyata secara bertahap
- Jika ada masalah, nilai flag bisa segera diturunkan atau dikembalikan ke 0, sambil mengatur volume traffic untuk debugging dan eksperimen
- Feature flag adalah trade-off yang menukar kompleksitas lokal dalam kode dengan kesederhanaan global dan ketahanan
- Kita harus menerima bahwa banyak versi infrastruktur dan data adalah hal yang normal, bukan pengecualian
Mendesain Model Data dan Batas Sistem
- Ruang ID menentukan bentuk sistem
- Semakin banyak ID yang dibutuhkan untuk mencapai satu data, semakin banyak pilihan untuk mempartisi data
- Semakin sedikit ID yang dibutuhkan untuk satu data, semakin mudah output sistem dikonsumsi
- Twitter API v1 mengambil, membuat, dan menghapus tweet dengan satu ID numerik 64-bit, dan ID ini tidak terhubung ke data lain
- Saat jumlah tweet bertambah, tweet dari pengguna yang sama bisa disimpan di mesin yang sama untuk membangun
user tweet timelinedansubscription timelinesecara efisien, tetapi karena API publik membuat semua tweet dialamatkan hanya dengantweet id, dibutuhkan layanan lookup yang mengetahui pengguna mana yang memilikitweet idtertentu - Alternatifnya adalah mewajibkan
user iduntuk lookup tweet, atau memasukkanuser idke dalamtweet iditu sendiri, tetapi opsi terakhir membuattweet idtidak lagi berupa numerikk-sortable, yang ada biayanya - Struktur ID dapat memengaruhi serangan seperti deanonymization data privat, crawling tak terduga, masalah auto-increment ID, dan Insecure Direct Object References
- Kita harus memanfaatkan lokalitas data
- Semakin dekat pemrosesan dan caching data dengan penyimpanan permanen, semakin efisien pemrosesannya dan semakin mudah menjaga konsistensi serta kecepatan cache
- Jaringan memiliki lebih banyak kegagalan dan latensi daripada dereferensi pointer atau
fread(3) - Lokalitas berlaku bukan hanya pada ruang, tetapi juga pada waktu
- Jika banyak pengguna melakukan permintaan mahal yang sama hampir bersamaan, permintaan itu bisa digabung menjadi satu, dan jika permintaan data sejenis terjadi berdekatan dalam waktu, permintaan itu bisa dibundel menjadi satu permintaan yang lebih besar
- Pendekatan ini menurunkan overhead komunikasi dan mempermudah penanganan gangguan
- Menulis kembali data yang di-cache ke penyimpanan permanen adalah ide buruk
- Cacat seperti ini terutama bisa muncul pada sistem yang pertama kali dirancang oleh orang yang minim pengalaman dengan sistem terdistribusi
- Implementasi yang menyebut “Russian-doll caching” sangat mungkin mengandung bug yang menonjol
- Gejala umum adalah informasi pengguna, misalnya
screenname,email,hashed password, kembali ke nilai sebelumnya
- Komputer mampu melakukan lebih banyak hal daripada yang dibayangkan
- Server web ringan pada akhir 2012 pun memiliki lebih dari 6 prosesor, 24GB memori, dan ruang disk yang sangat besar
- Bahkan aplikasi CRUD yang relatif kompleks pada runtime bahasa modern bisa menangani ribuan
requests per seconddalam ratusan milidetik di satu mesin - Dalam kebanyakan kasus, ratusan
requests per secondper mesin bukan angka yang layak dibanggakan dari sudut pandang kemampuan operasional - Dengan melakukan profiling aplikasi dan menerapkan efisiensi berbasis pengukuran, meraih performa lebih tinggi bukan hal yang sulit
- Teorema CAP sebaiknya dipakai sebagai alat kritik desain, bukan cara membangun sistem
- Teorema CAP terlalu umum dan ruang solusi yang mungkin terlalu luas, sehingga tidak cocok dijadikan prinsip pertama untuk menurunkan sistem yang benar-benar bekerja
- Dengan berulang kali meninjau desain sistem dan kendala yang dipaksakan CAP pada subsistem, kita bisa sampai pada desain yang lebih baik
- Di antara C, A, dan P, CA bukan pilihan
- Mengekstrak layanan memberi keuntungan enkapsulasi dan deployment
- Layanan di sini berarti sistem terdistribusi yang mencakup logika tingkat lebih tinggi daripada sistem penyimpanan dan biasanya memiliki API bergaya request-response
- Kita harus terus mengevaluasi apakah kode tertentu akan lebih mudah diubah jika berada di layanan terpisah alih-alih di dalam sistem
- Layanan yang diekstrak memberi enkapsulasi seperti library, tetapi membuat deployment perubahan lebih cepat dan mudah dibanding meningkatkan library pada sistem klien
- Layanan kecil memiliki lebih sedikit dependensi kode dan operasional, dan batas yang ketat mengurangi jalan pintas yang biasanya diperbolehkan di library
- Saat ada banyak sistem klien, shared library mengharuskan koordinasi deployment pada tiap klien, dan menjadi lebih sulit jika korupsi data bisa terjadi tergantung urutan deployment
- Jika pemelihara sistem klien berbeda-beda, prioritas mereka mungkin tidak selaras sehingga biaya koordinasi sosial untuk mendapatkan persetujuan upgrade juga membesar
- Kasus penggunaan yang representatif adalah menyembunyikan lapisan storage yang sedang diubah di balik layanan dengan API yang lebih nyaman dan permukaan yang lebih kecil
1 komentar
Komentar Hacker News
Tulisan itu seharusnya membahas CALM (konsistensi sebagai monotonisitas logis). Ini jauh lebih mudah dipahami daripada CAP dan merupakan hasil yang lebih fundamental, serta memungkinkan orang yang kurang berpengalaman membangun sistem terdistribusi yang sangat kokoh.
Idempotensi, CRDT, WAL, dan Raft semuanya adalah kasus khusus dari prinsip CALM.
https://arxiv.org/pdf/1901.01930
Ada satu prinsip umum yang saya sukai tetapi tidak disebut di sini: pengiriman tepat satu kali itu mustahil.
Paling banyak satu kali atau paling sedikit satu kali memang mungkin, tetapi kita harus memilih mode kegagalan mana yang akan diterima dan merancang sesuai itu.
Memindahkan data satu baris ke baris lain dalam database klaster itu mungkin, dan itu juga bisa ditafsirkan sebagai pesan yang telah terkirim.
Jika seluruh sistem bersifat idempoten, atau jika seluruh sistem terdistribusi dapat diperlakukan sebagai satu unit tunggal yang bisa di-rollback bersama, maka pengiriman tepat satu kali bisa dicapai. Artinya, tidak boleh ada efek samping terhadap sistem lain di luar domain tersebut.
Keduanya merupakan semacam monotonisitas logis. Idempotensi mudah dikenali, dan transaksionalitas juga berbasis pada monotonisitas melalui algoritme seperti WAL dan Raft.
Tulisan itu seharusnya membahas CALM (konsistensi sebagai monotonisitas logis). Ini jauh lebih mudah dipahami daripada CAP dan merupakan hasil yang lebih fundamental.
https://arxiv.org/pdf/1901.01930
An Overview of End-to-End Exactly-Once Processing in Apache Flink (with Apache Kafka, too!) — https://flink.apache.org/2018/02/28/an-overview-of-end-to-en...
Flink's Fault Tolerance Guarantees — https://nightlies.apache.org/flink/flink-docs-release-1.20/d...
Sebagai konsekuensi dari “kalau masalahnya bisa dimuat ke memori, mungkin itu masalah sepele,” ruang lingkup yang bisa dimuat ke memori jauh lebih besar daripada yang dibayangkan.
Saya kira saya tahu apa itu RAM besar, tetapi pandangan saya berubah ketika cloud besar mulai menyediakan VM 12TB untuk SAP HANA.
Tulisan itu memang menyinggung sangat singkat dengan “komputer bisa melakukan lebih banyak hal daripada yang Anda kira,” tetapi di sana hanya dibahas mesin 24GB. Meski mempertimbangkan bahwa itu tahun 2012, pada masa itu pun kemungkinan sudah cukup banyak mesin dengan RAM 10 kali lipatnya.
Saya membagikan dokumen ini kepada orang-orang paling menjanjikan yang bekerja bersama saya.
Saat bekerja di Lookout, Jeff Hodges membagikan esai ini dalam bentuk presentasi, lalu menambahkan konsekuensi di bagian akhir: “jangan berpura-pura bahwa engineering itu tidak politis.”
Orang yang mengira kode berbicara dengan sendirinya melewatkan aspek penting dalam memengaruhi bagaimana sesuatu akan dibuat dan dalam mendapatkan hasil nyata.
Bahkan 10 tahun kemudian, tidak banyak orang yang memahami secara ringkas persilangan antara kepemimpinan engineering dan hal-hal yang biasanya saya anggap sebagai kompetensi dasar SRE/DevOps seperti ini.
Ini diskusi-diskusi lama.
https://news.ycombinator.com/item?id=5055371
346 points|jcdavis|12 years ago|42 comments
https://news.ycombinator.com/item?id=12245909
386 points|kiyanwang|8 years ago|133 comments
Daftar yang bagus, dan saya suka penjelasannya yang praktis dan realistis. Tidak ada buzzword, juga tidak ada “microservices”.
Menurut saya, banyak dari saran ini juga berlaku untuk sistem satu mesin. Bisa ada banyak subkomponen yang sampai taraf tertentu terdistribusi, seperti IPC antarprogram atau koordinasi thread dalam satu proses.
Konsep memori terpadu pada satu mesin juga sampai batas tertentu tidak benar, tetapi hardware masih bisa memberikan jaminan yang lebih baik daripada lingkungan terdistribusi “sungguhan”.
Banyak saran dalam tulisan itu yang membandingkan “terdistribusi” dengan “satu mesin” juga cukup cocok untuk perbandingan multithread vs single-thread.
Pada sumbu lain, jika Anda membuat program lalu mendistribusikannya agar dijalankan banyak orang, itu juga menjadi semacam situasi “terdistribusi”. Ada berbagai versi berbeda di alam liar, dan Anda perlu memikirkan kompatibilitas serta masalah upgrade, sehingga feature flag yang disebut dalam tulisan itu juga relevan.
Keterdistribusian lebih mirip spektrum, dari satu CPU ke banyak CPU, banyak komputer yang terhubung rapat, hingga banyak komputer yang tersebar di seluruh dunia, dengan banyak titik dan dimensi di antaranya.
Beberapa proses yang berkomunikasi lewat localhost di mesin yang sama juga merupakan contoh sistem terdistribusi yang sangat terkenal, dan banyak orang memang pertama kali belajar sistem terdistribusi dari situ.
Kalau begitu, semua orang akan menulis semua kode sebagai program MPI memori terdistribusi yang indah. False sharing juga akan hilang, dan kita akan dipaksa memikirkan pola komunikasi secara eksplisit dan mendalam.
Dalam beberapa tahun terakhir, saya sempat berkesempatan bekerja sebentar dengan penulis tulisan ini. Jeff adalah salah satu orang paling berwawasan dan positif yang pernah saya pelajari darinya.
Ia sangat jujur tentang kesulitan yang dialaminya, dan juga sangat mudah didekati untuk mentoring dan saran.
Pada “sistem terdistribusi berbeda karena sering gagal,” intinya bukan sekadar tingkat kegagalan, melainkan tingkat kegagalan dalam sistem yang terdiri dari banyak node.
Dan “masalah sistem terdistribusi” tidak hanya muncul pada banyak server yang terhubung jaringan. Jika itu adalah kumpulan node yang saling berhubungan, file di disk yang terhubung secara logis atau buffer pada perangkat I/O yang berbeda pun mengalami masalah serupa.
Sebagian old-timer menertawakan kompleksitas berlebihan yang muncul saat mencoba meredakan masalah ini, lalu mengeluh bahwa menjalankan software di satu server saja jauh lebih sederhana.
Secara realistis, bahkan pada era AS/400 atau VAXft pun pernyataan itu hampir tidak benar, dan semakin tidak berlaku di dunia Unix multi-user dan multi-process yang lebih kacau.
“Kalau masalahnya bisa dimuat ke memori, mungkin itu masalah sepele” adalah kekeliruan umum di kalangan sebagian engineer sistem terdistribusi.
Sama sekali tidak sepele; hanya saja masalah yang harus ditangani berpindah ke wilayah yang komplementer.
Kekeliruan ini dengan mudah berujung pada situasi di mana pekerjaan yang bisa dilakukan di satu mesin jika dioptimalkan dengan benar malah ditangani oleh klaster 100 mesin.