RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

Π’ artikel terakhir kami melihat pengelompokan RabbitMQ untuk toleransi kesalahan dan ketersediaan yang tinggi. Sekarang mari kita mendalami Apache Kafka.

Di sini unit replikasi ialah partition. Setiap topik mempunyai satu atau lebih bahagian. Setiap bahagian mempunyai ketua dengan atau tanpa pengikut. Apabila mencipta topik, anda menentukan bilangan partition dan pekali replikasi. Nilai biasa ialah 3, yang bermaksud tiga replika: seorang ketua dan dua pengikut.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 1. Empat bahagian diedarkan di antara tiga broker

Semua permintaan baca dan tulis pergi kepada ketua. Pengikut menghantar permintaan secara berkala kepada ketua untuk menerima mesej terkini. Pengguna tidak pernah beralih kepada pengikut; yang kedua wujud hanya untuk redundansi dan toleransi kesalahan.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

Kegagalan pembahagian

Apabila broker gagal, pemimpin beberapa bahagian sering gagal. Dalam setiap daripada mereka, pengikut dari nod lain menjadi ketua. Sebenarnya, ini tidak selalu berlaku, kerana faktor penyegerakan juga mempengaruhi: sama ada terdapat pengikut yang disegerakkan, dan jika tidak, maka sama ada menukar kepada replika yang tidak disegerakkan dibenarkan. Tetapi janganlah kita merumitkan perkara buat masa ini.

Broker 3 meninggalkan rangkaian, dan pemimpin baharu dipilih untuk bahagian 2 di broker 2.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 2. Broker 3 meninggal dunia dan pengikutnya pada broker 2 dipilih sebagai ketua partition 2 yang baru

Kemudian broker 1 keluar dan seksyen 1 juga kehilangan ketuanya, yang peranannya beralih kepada broker 2.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 3. Tinggal satu broker. Semua pemimpin berada di satu broker tanpa redundansi sifar

Apabila broker 1 kembali dalam talian, ia menambah empat pengikut, memberikan beberapa redundansi kepada setiap partition. Tetapi semua pemimpin masih kekal di broker 2.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 4. Pemimpin kekal di broker 2

Apabila broker 3 muncul, kami kembali kepada tiga replika setiap partition. Tetapi semua pemimpin masih menggunakan broker 2.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 5. Penempatan pemimpin yang tidak seimbang selepas pemulihan broker 1 dan 3

Kafka mempunyai alat untuk mengimbangi semula pemimpin yang lebih baik daripada RabbitMQ. Di sana, anda perlu menggunakan pemalam atau skrip pihak ketiga yang mengubah dasar untuk memindahkan nod induk dengan mengurangkan lebihan semasa penghijrahan. Di samping itu, untuk baris gilir yang besar kami terpaksa menerima ketidaktersediaan semasa penyegerakan.

Kafka mempunyai konsep "replika pilihan" untuk peranan pemimpin. Apabila pembahagian topik dibuat, Kafka cuba mengagihkan pemimpin secara sama rata merentasi nod dan menandakan pemimpin pertama tersebut sebagai pilihan. Dari masa ke masa, disebabkan but semula pelayan, kegagalan dan kerosakan sambungan, pemimpin mungkin berakhir pada nod lain, seperti dalam kes ekstrem yang diterangkan di atas.

Untuk membetulkannya, Kafka menawarkan dua pilihan:

  • Pilihan auto.leader.rebalance.enable=true membenarkan nod pengawal untuk menetapkan semula pemimpin secara automatik kembali kepada replika pilihan dan dengan itu memulihkan pengedaran seragam.
  • Pentadbir boleh menjalankan skrip kafka-preferred-replica-election.sh untuk penugasan semula manual.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 6. Replika selepas pengimbangan semula

Ini adalah versi kegagalan yang dipermudahkan, tetapi realitinya lebih kompleks, walaupun tidak ada yang terlalu rumit di sini. Semuanya datang kepada replika yang disegerakkan (Replika Dalam-Segerak, ISR).

Replika Disegerakkan (ISR)

ISR ialah satu set replika partition yang dianggap "disegerakkan" (selaras). Ada pemimpin, tetapi mungkin tidak ada pengikut. Seorang pengikut dianggap disegerakkan jika ia telah membuat salinan tepat semua mesej ketua sebelum selang waktu tamat replica.lag.time.max.ms.

Seorang pengikut dialih keluar daripada set ISR jika ia:

  • tidak membuat permintaan untuk memilih selang waktu replica.lag.time.max.ms (dianggap mati)
  • tidak berjaya mengemas kini semasa selang waktu replica.lag.time.max.ms (dianggap lambat)

Pengikut membuat permintaan pensampelan dalam selang waktu replica.fetch.wait.max.ms, yang lalai kepada 500ms.

Untuk menerangkan dengan jelas tujuan ISR, kita perlu melihat pengesahan daripada pengeluar dan beberapa senario kegagalan. Pengeluar boleh memilih apabila broker menghantar pengesahan:

  • acks=0, pengesahan tidak dihantar
  • acks=1, pengesahan dihantar selepas pemimpin menulis mesej ke log tempatannya
  • acks=all, pengesahan dihantar selepas semua replika dalam ISR telah menulis mesej ke log tempatan

Dalam terminologi Kafka, jika ISR telah menyimpan mesej, ia "komit". Acks=all ialah pilihan paling selamat, tetapi juga menambah kelewatan tambahan. Mari kita lihat dua contoh kegagalan dan bagaimana pilihan 'acks' yang berbeza berinteraksi dengan konsep ISR.

Acks=1 dan ISR

Dalam contoh ini, kita akan melihat bahawa jika pemimpin tidak menunggu setiap mesej daripada semua pengikut disimpan, maka kehilangan data adalah mungkin jika pemimpin gagal. Menavigasi ke pengikut yang tidak disegerakkan boleh didayakan atau dilumpuhkan dengan tetapan najis.pemimpin.pilihanraya.dayakan.

Dalam contoh ini, pengilang mempunyai nilai acks=1. Bahagian ini diedarkan di ketiga-tiga broker. Broker 3 berada di belakang, ia disegerakkan dengan pemimpin lapan saat yang lalu dan kini ketinggalan 7456 mesej. Broker 1 hanya ketinggalan satu saat. Penerbit kami menghantar mesej dan dengan cepat menerima ack balik, tanpa overhed pengikut lambat atau mati yang pemimpin tidak tunggu.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 7. ISR dengan tiga replika

Broker 2 gagal dan pengeluar menerima ralat sambungan. Selepas kepimpinan beralih kepada broker 1, kami kehilangan 123 mesej. Pengikut pada broker 1 adalah sebahagian daripada ISR, tetapi tidak disegerakkan sepenuhnya dengan pemimpin apabila ia jatuh.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 8. Mesej hilang apabila ia ranap

Dalam konfigurasi bootstrap.servers Pengilang mempunyai beberapa broker yang disenaraikan dan boleh bertanya kepada broker lain yang merupakan ketua bahagian baharu. Ia kemudian mewujudkan sambungan kepada broker 1 dan terus menghantar mesej.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 9. Menghantar mesej disambung semula selepas berehat sebentar

Broker 3 lebih jauh di belakang. Ia membuat permintaan pengambilan tetapi tidak dapat disegerakkan. Ini mungkin disebabkan oleh sambungan rangkaian yang perlahan antara broker, isu storan, dll. Ia dialih keluar daripada ISR. Kini ISR ​​terdiri daripada satu replika - pemimpin! Pengilang terus menghantar mesej dan menerima pengesahan.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 10. Pengikut pada broker 3 dikeluarkan daripada ISR

Broker 1 turun dan peranan kepimpinan beralih kepada broker 3 dengan kehilangan 15286 mesej! Pengilang menerima mesej ralat sambungan. Peralihan kepada pemimpin di luar ISR hanya mungkin disebabkan oleh penetapan najis.pemimpin.pilihanraya.dayakan=benar. Jika ia dipasang di palsu, maka peralihan tidak akan berlaku dan semua permintaan baca dan tulis akan ditolak. Dalam kes ini, kami menunggu broker 1 kembali dengan data utuhnya dalam replika, yang sekali lagi akan mengambil alih kepimpinan.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 11. Broker 1 jatuh. Apabila kegagalan berlaku, sejumlah besar mesej hilang

Pengeluar mewujudkan hubungan dengan broker terakhir dan melihat bahawa dia kini ketua bahagian. Dia mula menghantar mesej kepada broker 3.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 12. Selepas berehat sebentar, mesej dihantar semula ke bahagian 0

Kami melihat bahawa, selain daripada gangguan singkat untuk mewujudkan sambungan baharu dan mencari pemimpin baharu, pengilang sentiasa menghantar mesej. Konfigurasi ini memastikan ketersediaan dengan mengorbankan ketekalan (keselamatan data). Kafka kehilangan beribu-ribu mesej tetapi terus menerima tulisan baharu.

Acks=semua dan ISR

Mari kita ulangi senario ini sekali lagi, tetapi dengan acks=semua. Broker 3 mempunyai kependaman purata empat saat. Pengilang menghantar mesej dengan acks=semua, dan kini tidak menerima respons pantas. Pemimpin menunggu mesej disimpan oleh semua replika dalam ISR.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 13. ISR dengan tiga replika. Satu perlahan, mengakibatkan penangguhan rakaman

Selepas empat saat kelewatan tambahan, broker 2 menghantar ack. Semua replika kini dikemas kini sepenuhnya.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 14. Semua replika menyimpan mesej dan menghantar ack

Broker 3 kini semakin ketinggalan dan dikeluarkan daripada ISR. Kependaman berkurangan dengan ketara kerana tiada replika perlahan yang tinggal dalam ISR. Broker 2 kini hanya menunggu untuk broker 1, dan dia mempunyai lag purata 500 ms.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 15. Replika pada broker 3 dikeluarkan daripada ISR

Kemudian broker 2 jatuh dan kepimpinan beralih kepada broker 1 tanpa kehilangan mesej.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 16. Broker 2 jatuh

Pengilang mencari pemimpin baharu dan mula menghantar mesej kepadanya. Latensi dikurangkan lagi kerana ISR kini terdiri daripada satu replika! Oleh itu pilihan acks=semua tidak menambah redundansi.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 17. Replika pada broker 1 memimpin tanpa kehilangan mesej

Kemudian broker 1 ranap dan petunjuk pergi ke broker 3 dengan kehilangan 14238 mesej!

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 18. Broker 1 mati dan peralihan kepimpinan dengan tetapan yang tidak bersih mengakibatkan kehilangan data yang meluas

Kami tidak dapat memasang pilihan najis.pemimpin.pilihanraya.dayakan menjadi makna benar. Secara lalai ia adalah sama palsu. tetapan acks=semua с najis.pemimpin.pilihanraya.dayakan=benar menyediakan kebolehaksesan dengan beberapa keselamatan data tambahan. Tetapi seperti yang anda lihat, kami masih boleh kehilangan mesej.

Tetapi bagaimana jika kita ingin meningkatkan keselamatan data? Anda boleh meletakkan najis.pemimpin.pilihanraya.boleh = palsu, tetapi ini tidak semestinya akan melindungi kami daripada kehilangan data. Jika pemimpin jatuh kuat dan mengambil data bersamanya, maka mesej masih hilang, ditambah ketersediaan hilang sehingga pentadbir memulihkan keadaan.

Adalah lebih baik untuk memastikan bahawa semua mesej adalah berlebihan, dan sebaliknya membuang rakaman. Kemudian, sekurang-kurangnya dari sudut pandangan broker, kehilangan data hanya mungkin sekiranya berlaku dua atau lebih kegagalan serentak.

Acks=all, min.insync.replicas dan ISR

Dengan konfigurasi topik min.insync.replicas Kami meningkatkan tahap keselamatan data. Mari kita ulangi bahagian terakhir senario sebelumnya, tetapi kali ini dengan min.insync.replicas=2.

Jadi broker 2 mempunyai pemimpin replika dan pengikut pada broker 3 dikeluarkan daripada ISR.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 19. ISR daripada dua replika

Broker 2 jatuh dan kepimpinan beralih kepada broker 1 tanpa kehilangan mesej. Tetapi kini ISR ​​hanya terdiri daripada satu replika. Ini tidak memenuhi bilangan minimum untuk menerima rekod, dan oleh itu broker bertindak balas kepada percubaan menulis dengan ralat NotEnoughReplika.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 20. Bilangan ISR adalah satu lebih rendah daripada yang dinyatakan dalam min.insync.replicas

Konfigurasi ini mengorbankan ketersediaan untuk konsistensi. Sebelum menerima mesej, kami memastikan bahawa ia ditulis kepada sekurang-kurangnya dua replika. Ini memberikan pengilang lebih keyakinan. Di sini, kehilangan mesej hanya mungkin jika dua replika gagal serentak dalam selang masa yang singkat sehingga mesej itu direplikasi kepada pengikut tambahan, yang tidak mungkin. Tetapi jika anda sangat paranoid, anda boleh menetapkan faktor replikasi kepada 5, dan min.insync.replicas oleh 3. Di sini tiga broker mesti jatuh pada masa yang sama untuk kehilangan rekod! Sudah tentu, anda membayar untuk kebolehpercayaan ini dalam kependaman tambahan.

Apabila kebolehcapaian diperlukan untuk keselamatan data

Seperti dalam kes dengan RabbitMQ, kadangkala kebolehcapaian diperlukan untuk keselamatan data. Inilah perkara yang perlu anda fikirkan:

  • Bolehkah penerbit hanya mengembalikan ralat dan meminta perkhidmatan huluan atau pengguna mencuba lagi kemudian?
  • Bolehkah penerbit menyimpan mesej secara setempat atau dalam pangkalan data untuk mencuba lagi nanti?

Jika jawapannya tidak, maka mengoptimumkan ketersediaan meningkatkan keselamatan data. Anda akan kehilangan lebih sedikit data jika anda memilih ketersediaan dan bukannya tidak merakam. Oleh itu, semuanya bergantung kepada mencari keseimbangan, dan keputusan bergantung pada situasi tertentu.

Maksud ISR

Suite ISR membolehkan anda memilih keseimbangan optimum antara keselamatan data dan kependaman. Contohnya, pastikan ketersediaan sekiranya berlaku kegagalan kebanyakan replika, meminimumkan kesan replika mati atau lambat dari segi kependaman.

Kita sendiri yang memilih maknanya replica.lag.time.max.ms mengikut keperluan anda. Pada asasnya, parameter ini bermaksud berapa banyak kelewatan yang kami sanggup terima bila acks=semua. Nilai lalai ialah sepuluh saat. Jika ini terlalu panjang untuk anda, anda boleh mengurangkannya. Kemudian kekerapan perubahan dalam ISR akan meningkat, kerana pengikut akan dialih keluar dan ditambah lebih kerap.

RabbitMQ hanyalah satu set cermin yang perlu ditiru. Cermin perlahan memperkenalkan kependaman tambahan, dan cermin mati boleh menunggu sehingga paket yang menyemak ketersediaan setiap nod (tanda bersih) untuk bertindak balas. ISR ialah cara yang menarik untuk mengelakkan isu kependaman ini. Tetapi kita berisiko kehilangan redundansi kerana ISR hanya boleh mengecut kepada pemimpin. Untuk mengelakkan risiko ini, gunakan tetapan min.insync.replicas.

Jaminan sambungan pelanggan

Dalam tetapan bootstrap.servers pengeluar dan pengguna boleh menentukan berbilang broker untuk menghubungkan pelanggan. Ideanya ialah apabila satu nod turun, terdapat beberapa nod ganti yang tinggal dengan pelanggan boleh membuka sambungan. Ini tidak semestinya ketua bahagian, tetapi hanya papan anjal untuk pemuatan awal. Pelanggan boleh bertanya kepada mereka nod yang menjadi tuan rumah ketua partition baca/tulis.

Dalam RabbitMQ, pelanggan boleh menyambung ke mana-mana nod, dan penghalaan dalaman menghantar permintaan ke tempat yang perlu dituju. Ini bermakna anda boleh memasang pengimbang beban di hadapan RabbitMQ. Kafka memerlukan pelanggan untuk menyambung ke nod yang menjadi tuan rumah ketua partition yang sepadan. Dalam keadaan sedemikian, anda tidak boleh memasang pengimbang beban. Senaraikan bootstrap.servers Adalah penting bahawa pelanggan boleh mengakses dan mencari nod yang betul selepas kegagalan.

Seni Bina Konsensus Kafka

Sehingga kini, kami tidak mempertimbangkan bagaimana kluster mengetahui tentang kejatuhan broker dan cara pemimpin baharu dipilih. Untuk memahami cara Kafka berfungsi dengan partition rangkaian, anda perlu memahami seni bina konsensus terlebih dahulu.

Setiap gugusan Kafka digunakan bersama-sama dengan gugusan Zookeeper, yang merupakan perkhidmatan konsensus teragih yang membolehkan sistem mencapai konsensus pada beberapa keadaan tertentu, mengutamakan konsistensi berbanding ketersediaan. Persetujuan majoriti nod Zookeeper diperlukan untuk meluluskan operasi baca dan tulis.

Zookeeper menyimpan keadaan kluster:

  • Senarai topik, bahagian, konfigurasi, replika pemimpin semasa, replika pilihan.
  • ahli kluster. Setiap broker ping kluster Zookeeper. Jika ia tidak menerima ping dalam tempoh masa yang ditetapkan, maka Zookeeper merekodkan broker sebagai tidak tersedia.
  • Memilih nod utama dan ganti untuk pengawal.

Nod pengawal adalah salah satu broker Kafka yang bertanggungjawab untuk memilih pemimpin replika. Zookeeper menghantar pemberitahuan kepada pengawal tentang keahlian kelompok dan perubahan topik, dan pengawal mesti bertindak ke atas perubahan ini.

Sebagai contoh, mari kita ambil topik baharu dengan sepuluh partition dan faktor replikasi 3. Pengawal mesti memilih ketua bagi setiap partition, cuba mengagihkan pemimpin secara optimum di kalangan broker.

Untuk setiap pengawal bahagian:

  • mengemas kini maklumat dalam Zookeeper tentang ISR dan pemimpin;
  • Menghantar LeaderAndISRCommand kepada setiap broker yang menjadi tuan rumah replika partition ini, memaklumkan broker tentang ISR dan pemimpin.

Apabila broker dengan pemimpin jatuh, Zookeeper menghantar pemberitahuan kepada pengawal, dan ia memilih pemimpin baharu. Sekali lagi, pengawal mula-mula mengemas kini Zookeeper dan kemudian menghantar arahan kepada setiap broker yang memberitahu mereka tentang perubahan kepimpinan.

Setiap pemimpin bertanggungjawab untuk merekrut ISR. tetapan replica.lag.time.max.ms menentukan siapa yang akan masuk ke sana. Apabila ISR berubah, ketua menghantar maklumat baharu kepada Zookeeper.

Penjaga zoo sentiasa dimaklumkan tentang sebarang perubahan supaya sekiranya berlaku kegagalan, pengurusan beralih dengan lancar kepada pemimpin baharu.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 21. Muafakat Kafka

Protokol replikasi

Memahami butiran replikasi membantu anda memahami dengan lebih baik kemungkinan senario kehilangan data.

Pertanyaan pensampelan, Log Tamat Offset (LEO) dan Tanda Air Tinggi (HW)

Kami menganggap bahawa pengikut menghantar permintaan pengambilan secara berkala kepada ketua. Selang lalai ialah 500ms. Ini berbeza daripada RabbitMQ kerana dalam RabbitMQ replikasi tidak dimulakan oleh cermin giliran tetapi oleh tuan. Tuan menolak perubahan pada cermin.

Pemimpin dan semua pengikut menyimpan Log End Offset (LEO) dan label Highwater (HW). Tanda LEO menyimpan offset mesej terakhir dalam replika tempatan, dan HW memegang offset komit terakhir. Ingat bahawa untuk status komit, mesej mesti dikekalkan merentas semua replika ISR. Ini bermakna LEO biasanya mendahului sedikit daripada HW.

Apabila pemimpin menerima mesej, ia menyimpannya secara tempatan. Pengikut membuat permintaan pengambilan dengan menghantar LEOnya. Pemimpin kemudian menghantar sekumpulan mesej bermula dari LEO ini dan juga menghantar HW semasa. Apabila ketua menerima maklumat bahawa semua replika telah menyimpan mesej pada offset yang diberikan, ia menggerakkan tanda HW. Hanya pemimpin boleh menggerakkan HW, jadi semua pengikut akan mengetahui nilai semasa dalam respons kepada permintaan mereka. Ini bermakna pengikut mungkin ketinggalan daripada pemimpin dalam kedua-dua mesej dan pengetahuan HW. Pengguna menerima mesej hanya sehingga HW semasa.

Ambil perhatian bahawa "berterusan" bermaksud ditulis ke memori, bukan ke cakera. Untuk prestasi, Kafka menyegerakkan ke cakera pada selang waktu tertentu. RabbitMQ juga mempunyai selang sedemikian, tetapi ia akan menghantar pengakuan kepada penerbit hanya selepas induk dan semua cermin telah menulis mesej ke cakera. Pembangun Kafka, atas sebab prestasi, memutuskan untuk menghantar ack sebaik sahaja mesej ditulis ke ingatan. Kafka bertaruh bahawa redundansi mengimbangi risiko menyimpan secara ringkas mesej yang diakui dalam ingatan sahaja.

Kegagalan pemimpin

Apabila pemimpin jatuh, Zookeeper memberitahu pengawal, dan ia memilih replika pemimpin baharu. Pemimpin baharu itu menetapkan tanda HW baharu mengikut LEOnya. Pengikut kemudian menerima maklumat tentang pemimpin baharu. Bergantung pada versi Kafka, pengikut akan memilih salah satu daripada dua senario:

  1. Ia akan memotong log tempatan ke HW yang diketahui dan menghantar permintaan kepada pemimpin baharu untuk mesej selepas tanda ini.
  2. Akan menghantar permintaan kepada pemimpin untuk mengetahui HW pada masa beliau dipilih sebagai ketua, dan kemudian memotong log ke offset ini. Ia kemudiannya akan mula membuat permintaan pengambilan berkala bermula pada ofset ini.

Seorang pengikut mungkin perlu memotong log atas sebab berikut:

  • Apabila seorang pemimpin gagal, pengikut pertama dalam set ISR yang berdaftar dengan Zookeeper memenangi pilihan raya dan menjadi ketua. Semua pengikut di ISR, walaupun dianggap "selaras", mungkin tidak menerima salinan semua mesej daripada bekas ketua. Ada kemungkinan bahawa pengikut yang ditampilkan tidak mempunyai salinan yang paling terkini. Kafka memastikan tiada perbezaan antara replika. Oleh itu, untuk mengelakkan percanggahan, setiap pengikut mesti memotong lognya kepada nilai HW pemimpin baharu pada masa pemilihannya. Ini adalah satu lagi sebab mengapa menetapkan acks=semua sangat penting untuk konsisten.
  • Mesej ditulis secara berkala ke cakera. Jika semua nod kluster gagal pada masa yang sama, maka replika dengan offset berbeza akan disimpan pada cakera. Ada kemungkinan apabila broker kembali dalam talian, pemimpin baru yang dipilih akan berada di belakang pengikutnya kerana dia telah disimpan ke cakera sebelum yang lain.

Reuni dengan kluster

Apabila menyertai semula kluster, replika melakukan perkara yang sama seperti apabila pemimpin gagal: mereka menyemak replika pemimpin dan memotong log mereka ke HWnya (pada masa pilihan raya). Sebagai perbandingan, RabbitMQ sama-sama menganggap nod yang bersatu semula sebagai benar-benar baharu. Dalam kedua-dua kes, broker membuang mana-mana keadaan sedia ada. Jika penyegerakan automatik digunakan, maka tuan mesti mereplikasi sepenuhnya semua kandungan semasa ke cermin baharu dalam kaedah "biar seluruh dunia menunggu". Tuan tidak menerima sebarang operasi baca atau tulis semasa operasi ini. Pendekatan ini menimbulkan masalah dalam baris gilir yang besar.

Kafka ialah log yang diedarkan dan secara amnya ia menyimpan lebih banyak mesej daripada baris gilir RabbitMQ, di mana data dialih keluar daripada baris gilir selepas ia dibaca. Barisan gilir aktif harus kekal agak kecil. Tetapi Kafka ialah log dengan dasar pengekalannya sendiri, yang boleh menetapkan tempoh hari atau minggu. Penyekatan baris gilir dan pendekatan penyegerakan penuh sama sekali tidak boleh diterima untuk log yang diedarkan. Sebaliknya, pengikut Kafka hanya memotong log mereka ke HW pemimpin (pada masa pemilihannya) jika salinan mereka mendahului pemimpin. Dalam kes yang lebih berkemungkinan, apabila pengikut berada di belakang, ia hanya mula membuat permintaan pengambilan bermula dengan LEO semasanya.

Pengikut baharu atau yang menyertai semula bermula di luar ISR dan tidak mengambil bahagian dalam komitmen. Mereka hanya bekerja bersama kumpulan, menerima mesej secepat mungkin sehingga mereka mengejar ketua dan memasuki ISR. Tiada kunci masuk dan tidak perlu membuang semua data anda.

Kehilangan sambungan

Kafka mempunyai lebih banyak komponen daripada RabbitMQ, jadi ia mempunyai set gelagat yang lebih kompleks apabila gugusan menjadi terputus sambungan. Tetapi Kafka pada asalnya direka untuk kelompok, jadi penyelesaiannya difikirkan dengan sangat baik.

Berikut ialah beberapa senario kegagalan sambungan:

  • Senario 1: Pengikut tidak melihat ketua, tetapi masih melihat Penjaga Zoo.
  • Senario 2: Pemimpin tidak melihat mana-mana pengikut, tetapi masih melihat Zookeeper.
  • Senario 3: Pengikut melihat ketua, tetapi tidak melihat Penjaga Zoo.
  • Senario 4: Pemimpin melihat pengikut, tetapi tidak melihat Penjaga Zoo.
  • Senario 5: Pengikut adalah berasingan sepenuhnya daripada kedua-dua nod Kafka dan Penjaga Zoo yang lain.
  • Senario 6: Pemimpin benar-benar terpisah daripada kedua-dua nod Kafka dan Penjaga Zoo yang lain.
  • Senario 7: Nod pengawal Kafka tidak dapat melihat nod Kafka yang lain.
  • Senario 8: Pengawal Kafka tidak melihat Zookeeper.

Setiap senario mempunyai tingkah laku sendiri.

Senario 1: Pengikut tidak melihat ketua, tetapi masih melihat Penjaga Zoo

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 22. Senario 1: ISR tiga replika

Kegagalan sambungan memisahkan broker 3 daripada broker 1 dan 2, tetapi bukan dari Zookeeper. Broker 3 tidak lagi boleh menghantar permintaan pengambilan. Selepas masa berlalu replica.lag.time.max.ms ia dikeluarkan daripada ISR dan tidak mengambil bahagian dalam komit mesej. Setelah ketersambungan dipulihkan, ia akan menyambung semula permintaan pengambilan dan menyertai ISR ​​apabila ia mengejar pemimpin. Zookeeper akan terus menerima ping dan menganggap bahawa broker itu masih hidup dan sihat.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 23. Senario 1: Broker dikeluarkan daripada ISR jika tiada permintaan pengambilan diterima daripadanya dalam selang replica.lag.time.max.ms

Tiada penggantungan otak belah atau nod seperti dalam RabbitMQ. Sebaliknya, redundansi dikurangkan.

Senario 2: Pemimpin tidak melihat mana-mana pengikut, tetapi masih melihat Zookeeper

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 24. Senario 2. Pemimpin dan dua pengikut

Pecahan dalam sambungan rangkaian memisahkan pemimpin daripada pengikut, tetapi broker masih boleh melihat Zookeeper. Seperti dalam senario pertama, ISR mengecut, tetapi kali ini hanya kepada ketua kerana semua pengikut berhenti menghantar permintaan pengambilan. Sekali lagi, tidak ada pembahagian logik. Sebaliknya, terdapat kehilangan redundansi untuk mesej baharu sehingga ketersambungan dipulihkan. Zookeeper terus menerima ping dan percaya bahawa broker itu masih hidup dan sihat.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 25. Senario 2. ISR telah menyusut hanya kepada pemimpin

Senario 3. Pengikut melihat ketua, tetapi tidak melihat Penjaga Zoo

Pengikut dipisahkan daripada Zookeeper, tetapi bukan daripada broker dengan ketua. Akibatnya, pengikut terus membuat permintaan pengambilan dan menjadi ahli ISR. Zookeeper tidak lagi menerima ping dan mendaftarkan kemalangan broker, tetapi kerana ia hanya pengikut, tiada akibat selepas pemulihan.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 26. Senario 3: Pengikut terus menghantar permintaan pengambilan kepada ketua

Senario 4. Pemimpin melihat pengikut, tetapi tidak melihat Zookeeper

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 27. Senario 4. Pemimpin dan dua pengikut

Pemimpin dipisahkan daripada Zookeeper, tetapi bukan daripada broker dengan pengikut.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 28. Senario 4: Pemimpin diasingkan daripada Zookeeper

Selepas beberapa lama, Zookeeper akan mendaftarkan kegagalan broker dan memberitahu pengawal tentangnya. Dia akan memilih pemimpin baru di kalangan pengikutnya. Walau bagaimanapun, pemimpin asal akan terus menganggap bahawa ia adalah ketua dan akan terus menerima penyertaan daripada acks=1. Pengikut tidak lagi menghantar permintaan pengambilan kepadanya, jadi dia akan menganggap permintaan tersebut telah mati dan cuba mengecilkan ISR kepada dirinya sendiri. Tetapi kerana ia tidak mempunyai sambungan ke Zookeeper, ia tidak akan dapat melakukan ini, dan pada ketika itu akan menolak untuk menerima sebarang penyertaan selanjutnya.

БообщСния acks=semua tidak akan menerima pengakuan kerana ISR mula-mula menghidupkan semua replika, dan mesej tidak sampai kepada mereka. Apabila pemimpin asal cuba mengeluarkan mereka daripada ISR, ia tidak akan dapat berbuat demikian dan akan berhenti menerima sebarang mesej sama sekali.

Pelanggan tidak lama lagi menyedari perubahan dalam pemimpin dan mula menghantar rekod ke pelayan baharu. Setelah rangkaian dipulihkan, pemimpin asal melihat bahawa ia bukan lagi pemimpin dan memotong lognya kepada nilai HW yang pemimpin baharu itu pada masa kegagalan untuk mengelakkan perbezaan log. Ia kemudiannya akan mula menghantar permintaan pengambilan kepada ketua baharu. Semua rekod daripada pemimpin asal yang tidak direplikasi kepada pemimpin baharu hilang. Iaitu, mesej yang tidak diakui oleh pemimpin asal dalam beberapa saat ketika dua pemimpin bekerja akan hilang.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 29. Senario 4. Pemimpin pada broker 1 menjadi pengikut selepas rangkaian dipulihkan

Senario 5: Pengikut adalah berasingan sepenuhnya daripada kedua-dua nod Kafka dan Penjaga Zoo yang lain

Pengikut diasingkan sepenuhnya daripada kedua-dua nod Kafka dan Penjaga Zooke yang lain. Dia hanya mengeluarkan dirinya daripada ISR sehingga rangkaian dipulihkan, dan kemudian mengejar yang lain.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 30. Senario 5: Pengikut terpencil dialih keluar daripada ISR

Senario 6: Pemimpin benar-benar terpisah daripada kedua-dua nod Kafka dan Penjaga Zoo yang lain

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 31. Senario 6. Pemimpin dan dua pengikut

Pemimpin benar-benar terasing daripada pengikutnya, pengawal dan Penjaga Zoo. Untuk tempoh yang singkat ia akan terus menerima penyertaan daripada acks=1.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 32. Senario 6: Mengasingkan ketua daripada nod Kafka dan Zookeeper yang lain

Tidak menerima permintaan selepas tamat tempoh replica.lag.time.max.ms, ia akan cuba mengecilkan ISR kepada dirinya sendiri, tetapi tidak akan dapat berbuat demikian kerana tiada komunikasi dengan Zookeeper, maka ia akan berhenti menerima penulisan.

Sementara itu, Zookeeper akan menandakan broker terpencil sebagai mati dan pengawal akan memilih pemimpin baharu.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 33. Senario 6. Dua orang pemimpin

Pemimpin asal boleh menerima entri selama beberapa saat, tetapi kemudian berhenti menerima sebarang mesej. Pelanggan dikemas kini setiap 60 saat dengan metadata terkini. Mereka akan dimaklumkan tentang pertukaran pemimpin dan akan mula menghantar penyertaan kepada pemimpin baharu.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 34. Senario 6: Pengilang bertukar kepada peneraju baharu

Semua penyertaan yang disahkan yang dibuat oleh ketua asal sejak kehilangan ketersambungan akan hilang. Setelah rangkaian dipulihkan, pemimpin asal akan mengetahui melalui Zookeeper bahawa ia bukan lagi ketua. Kemudian ia akan memotong lognya ke HW pemimpin baharu pada masa pemilihan dan mula menghantar permintaan sebagai pengikut.

RabbitMQ lwn Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
nasi. 35. Senario 6: Pemimpin asal menjadi pengikut selepas sambungan rangkaian dipulihkan

Dalam keadaan ini, pemisahan logik mungkin berlaku untuk tempoh yang singkat, tetapi hanya jika acks=1 ΠΈ min.insync.replicas juga 1. Pemisahan logik secara automatik tamat sama ada selepas rangkaian dipulihkan, apabila pemimpin asal menyedari bahawa dia bukan lagi ketua, atau apabila semua pelanggan menyedari bahawa ketua telah berubah dan mula menulis kepada pemimpin baru - yang mana berlaku dahulu. Walau apa pun, beberapa mesej akan hilang, tetapi hanya dengan acks=1.

Terdapat satu lagi varian senario ini di mana, sejurus sebelum rangkaian berpecah, pengikut ketinggalan dan ketua memampatkan ISR kepada dirinya sahaja. Ia kemudiannya menjadi terpencil kerana kehilangan sambungan. Pemimpin baru dipilih, tetapi pemimpin asal terus menerima penyertaan, malah acks=semua, kerana tidak ada orang lain di ISR ​​kecuali dia. Rekod ini akan hilang setelah rangkaian dipulihkan. Satu-satunya cara untuk mengelakkan pilihan ini ialah min.insync.replicas = 2.

Senario 7: Nod Pengawal Kafka Tidak Dapat Melihat Nod Kafka Lain

Secara umum, sebaik sahaja sambungan dengan nod Kafka terputus, pengawal tidak akan dapat menghantar sebarang maklumat perubahan pemimpin kepadanya. Dalam kes yang paling teruk, ini akan membawa kepada pemisahan logik jangka pendek, seperti dalam senario 6. Selalunya, broker tidak akan menjadi calon kepimpinan jika yang terakhir gagal.

Senario 8: Pengawal Kafka tidak melihat Zookeeper

Zookeeper tidak akan menerima ping daripada pengawal yang jatuh dan akan memilih nod Kafka baharu sebagai pengawal. Pengawal asal boleh terus menunjukkan dirinya seperti itu, tetapi ia tidak menerima pemberitahuan daripada Zookeeper, jadi ia tidak akan mempunyai sebarang tugas untuk dilakukan. Setelah rangkaian dipulihkan, dia akan menyedari bahawa dia bukan lagi pengawal, tetapi telah menjadi nod Kafka biasa.

Kesimpulan daripada senario

Kami melihat bahawa kehilangan sambungan pengikut tidak mengakibatkan kehilangan mesej, tetapi hanya mengurangkan redundansi buat sementara waktu sehingga rangkaian dipulihkan. Ini, sudah tentu, boleh menyebabkan kehilangan data jika satu atau lebih nod hilang.

Jika ketua dipisahkan daripada Zookeeper kerana kehilangan sambungan, ini boleh mengakibatkan mesej hilang daripada acks=1. Kekurangan komunikasi dengan Zookeeper menyebabkan perpecahan logik ringkas dengan kedua-dua pemimpin. Masalah ini diselesaikan oleh parameter acks=semua.

Parameter min.insync.replicas menjadi dua atau lebih replika memberikan jaminan tambahan bahawa senario jangka pendek sedemikian tidak akan mengakibatkan kehilangan mesej seperti dalam Senario 6.

Ringkasan Mesej Hilang

Mari senaraikan semua cara anda boleh kehilangan data dalam Kafka:

  • Sebarang kegagalan pemimpin jika mesej disahkan menggunakan acks=1
  • Mana-mana peralihan kepimpinan yang tidak bersih, iaitu, kepada pengikut di luar ISR, walaupun dengan acks=semua
  • Mengasingkan ketua daripada Zookeeper jika mesej disahkan menggunakan acks=1
  • Pengasingan sepenuhnya pemimpin yang telah mengecilkan kumpulan ISR kepada dirinya sendiri. Semua mesej akan hilang, malah acks=semua. Ini hanya benar jika min.insync.replicas=1.
  • Kegagalan serentak semua nod partition. Oleh kerana mesej diakui daripada ingatan, sesetengahnya mungkin belum ditulis ke cakera. Selepas but semula pelayan, beberapa mesej mungkin hilang.

Peralihan kepimpinan yang tidak tulen boleh dielakkan sama ada dengan melarangnya atau memastikan sekurang-kurangnya dua pemberhentian. Konfigurasi yang paling tahan lama ialah gabungan acks=semua ΠΈ min.insync.replicas lebih 1.

Perbandingan langsung kebolehpercayaan RabbitMQ dan Kafka

Untuk memastikan kebolehpercayaan dan ketersediaan tinggi, kedua-dua platform melaksanakan sistem replikasi primer dan sekunder. Walau bagaimanapun, RabbitMQ mempunyai tumit Achilles. Apabila menyambung semula selepas kegagalan, nod membuang data mereka dan penyegerakan disekat. Kesan berganda ini mempersoalkan jangka hayat baris gilir besar dalam RabbitMQ. Anda perlu menerima sama ada redundansi yang dikurangkan atau masa penyekatan yang panjang. Mengurangkan redundansi meningkatkan risiko kehilangan data secara besar-besaran. Tetapi jika baris gilir kecil, maka demi redundansi, tempoh singkat ketidaktersediaan (beberapa saat) boleh ditangani menggunakan percubaan sambungan berulang.

Kafka tidak mempunyai masalah ini. Ia membuang data hanya dari sudut perbezaan antara pemimpin dan pengikut. Semua data yang dikongsi disimpan. Di samping itu, replikasi tidak menyekat sistem. Pemimpin terus menerima jawatan sementara pengikut baharu mengejar, jadi bagi devops, menyertai atau menyertai semula kluster menjadi tugas yang remeh. Sudah tentu, masih terdapat isu seperti lebar jalur rangkaian semasa replikasi. Jika anda menambah berbilang pengikut pada masa yang sama, anda mungkin menghadapi had lebar jalur.

RabbitMQ lebih unggul daripada Kafka dalam kebolehpercayaan apabila berbilang pelayan dalam gugusan gagal pada masa yang sama. Seperti yang telah kami katakan, RabbitMQ menghantar pengesahan kepada penerbit hanya selepas mesej ditulis ke cakera oleh induk dan semua cermin. Tetapi ini menambah kependaman tambahan atas dua sebab:

  • fsync setiap beberapa ratus milisaat
  • Kegagalan cermin hanya dapat dilihat selepas hayat paket yang menyemak ketersediaan setiap nod (tanda bersih) telah tamat tempoh. Jika cermin perlahan atau jatuh, ini menambah kelewatan.

Pertaruhan Kafka ialah jika mesej disimpan merentasi berbilang nod, ia boleh mengakui mesej sebaik sahaja ia mencapai ingatan. Disebabkan ini, terdapat risiko kehilangan sebarang jenis mesej (walaupun acks=semua, min.insync.replicas=2) sekiranya berlaku kegagalan serentak.

Secara keseluruhan, Kafka mempamerkan prestasi perisian yang lebih baik dan direka bentuk dari bawah untuk kelompok. Bilangan pengikut boleh ditambah kepada 11 jika perlu untuk kebolehpercayaan. Faktor replikasi 5 dan bilangan minimum replika dalam penyegerakan min.insync.replicas=3 akan menjadikan kehilangan mesej sebagai peristiwa yang sangat jarang berlaku. Jika infrastruktur anda boleh menyokong nisbah replikasi dan tahap redundansi ini, maka anda boleh memilih pilihan ini.

Pengelompokan RabbitMQ bagus untuk baris gilir kecil. Tetapi barisan kecil pun boleh berkembang dengan cepat apabila terdapat trafik yang sesak. Setelah baris gilir menjadi besar, anda perlu membuat pilihan yang sukar antara ketersediaan dan kebolehpercayaan. Pengelompokan RabbitMQ paling sesuai untuk situasi bukan tipikal di mana manfaat fleksibiliti RabbitMQ mengatasi sebarang kelemahan pengelompokannya.

Satu penawar kepada kerentanan RabbitMQ kepada baris gilir yang besar adalah dengan memecahkannya kepada banyak baris gilir yang lebih kecil. Jika anda tidak memerlukan pesanan lengkap bagi keseluruhan baris gilir, tetapi hanya mesej yang berkaitan (contohnya, mesej daripada pelanggan tertentu), atau tidak memesan apa-apa langsung, maka pilihan ini boleh diterima: lihat projek saya Pengimbang semula untuk membahagikan baris gilir (projek masih di peringkat awal).

Akhir sekali, jangan lupa tentang beberapa pepijat dalam mekanisme pengelompokan dan replikasi kedua-dua RabbitMQ dan Kafka. Dari masa ke masa, sistem telah menjadi lebih matang dan stabil, tetapi tiada mesej yang akan selamat 100% daripada kehilangan! Di samping itu, kemalangan berskala besar berlaku di pusat data!

Jika saya terlepas sesuatu, membuat kesilapan, atau anda tidak bersetuju dengan mana-mana perkara, sila tulis komen atau hubungi saya.

Saya sering ditanya: "Apa yang perlu dipilih, Kafka atau RabbitMQ?", "Platform mana yang lebih baik?". Sebenarnya ia sangat bergantung pada situasi anda, pengalaman semasa, dsb. Saya teragak-agak untuk memberikan pendapat saya kerana terlalu banyak penyederhanaan untuk mengesyorkan satu platform untuk semua kes penggunaan dan kemungkinan had. Saya menulis siri artikel ini supaya anda boleh membentuk pendapat anda sendiri.

Saya ingin mengatakan bahawa kedua-dua sistem adalah pemimpin dalam bidang ini. Saya mungkin agak berat sebelah kerana daripada pengalaman saya dengan projek, saya cenderung untuk menghargai perkara seperti pesanan mesej yang terjamin dan kebolehpercayaan.

Saya melihat teknologi lain yang tidak mempunyai kebolehpercayaan dan pesanan yang terjamin, kemudian saya melihat RabbitMQ dan Kafka dan menyedari nilai luar biasa kedua-dua sistem ini.

Sumber: www.habr.com

Tambah komen