RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

В artikel terakhir kami melihat pengelompokan RabbitMQ untuk toleransi kesalahan dan ketersediaan tinggi. Sekarang mari kita gali lebih dalam tentang Apache Kafka.

Di sini unit replikasinya adalah partisi. Setiap topik memiliki satu atau lebih bagian. Setiap bagian memiliki pemimpin dengan atau tanpa pengikut. Saat membuat topik, Anda menentukan jumlah partisi dan koefisien replikasi. Nilai biasanya adalah 3 yang berarti tiga replika: satu pemimpin dan dua pengikut.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 1. Empat bagian didistribusikan ke tiga broker

Semua permintaan baca dan tulis ditujukan kepada pemimpin. Pengikut secara berkala mengirimkan permintaan kepada pemimpin untuk menerima pesan terbaru. Konsumen tidak pernah beralih ke pengikut; pengikut hanya ada untuk redundansi dan toleransi kesalahan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi

Kegagalan partisi

Ketika seorang broker gagal, para pemimpin beberapa bagian sering kali gagal. Di masing-masing node, pengikut dari node lain menjadi pemimpin. Faktanya, hal ini tidak selalu terjadi, karena faktor sinkronisasi juga mempengaruhi: apakah ada pengikut yang disinkronkan, dan jika tidak, apakah peralihan ke replika yang tidak disinkronkan diperbolehkan. Tapi jangan mempersulit keadaan untuk saat ini.

Broker 3 meninggalkan jaringan, dan pemimpin baru dipilih untuk bagian 2 di broker 2.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 2. Broker 3 meninggal dan pengikutnya di broker 2 terpilih sebagai pemimpin baru partisi 2

Kemudian broker 1 keluar dan bagian 1 pun kehilangan pemimpinnya, yang perannya beralih ke broker 2.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 3. Tinggal satu broker lagi. Semua pemimpin berada di satu broker tanpa redundansi

Ketika broker 1 kembali online, ia menambah empat pengikut, memberikan beberapa redundansi pada setiap partisi. Namun semua leader masih tetap berada di broker 2.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 4. Pemimpin tetap pada broker 2

Ketika broker 3 muncul, kita kembali ke tiga replika per partisi. Namun semua leader masih berada di broker 2.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 5. Penempatan pimpinan yang tidak seimbang pasca restorasi broker 1 dan 3

Kafka memiliki alat untuk menyeimbangkan kembali pemimpin yang lebih baik daripada RabbitMQ. Di sana, Anda harus menggunakan plugin atau skrip pihak ketiga yang mengubah kebijakan migrasi node master dengan mengurangi redundansi selama migrasi. Selain itu, untuk antrian besar kami harus menerima ketidaktersediaan selama sinkronisasi.

Kafka memiliki konsep “replika pilihan” untuk peran pemimpin. Saat partisi topik dibuat, Kafka berupaya mendistribusikan pemimpin secara merata di seluruh node dan menandai pemimpin pertama tersebut sebagai pilihan. Seiring waktu, karena reboot server, kegagalan, dan gangguan konektivitas, pemimpin mungkin berakhir di node lain, seperti dalam kasus ekstrim yang dijelaskan di atas.

Untuk memperbaikinya, Kafka menawarkan dua opsi:

  • Pilihan auto.leader.rebalance.enable=benar memungkinkan node pengontrol untuk secara otomatis menugaskan kembali pemimpin ke replika pilihan dan dengan demikian memulihkan distribusi seragam.
  • Administrator dapat menjalankan skrip kafka-preferred-replica-election.sh untuk penugasan kembali secara manual.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 6. Replika setelah penyeimbangan ulang

Ini adalah versi kegagalan yang disederhanakan, namun kenyataannya lebih kompleks, meskipun tidak ada yang terlalu rumit di sini. Semuanya bermuara pada replika yang disinkronkan (Replika In-Sync, ISR).

Replika Tersinkronisasi (ISR)

ISR adalah sekumpulan replika partisi yang dianggap “tersinkronisasi” (in-sync). Ada pemimpin, tapi mungkin tidak ada pengikut. Seorang pengikut dianggap tersinkronisasi jika ia telah membuat salinan persis semua pesan pemimpin sebelum intervalnya berakhir replika.lag.time.max.ms.

Seorang pengikut dihapus dari kumpulan ISR jika:

  • tidak membuat permintaan untuk memilih interval replika.lag.time.max.ms (diduga meninggal)
  • tidak berhasil memperbarui selama interval replika.lag.time.max.ms (dianggap lambat)

Pengikut membuat permintaan pengambilan sampel dalam interval tersebut replika.fetch.wait.max.ms, yang defaultnya adalah 500ms.

Untuk menjelaskan tujuan ISR dengan jelas, kita perlu melihat konfirmasi dari produsen dan beberapa skenario kegagalan. Produsen dapat memilih kapan broker mengirimkan konfirmasi:

  • acks=0, konfirmasi tidak terkirim
  • acks=1, konfirmasi dikirim setelah pemimpin menulis pesan ke log lokalnya
  • acks=all, konfirmasi dikirim setelah semua replika di ISR ​​menulis pesan ke log lokal

Dalam terminologi Kafka, jika ISR telah menyimpan sebuah pesan, maka pesan tersebut “berkomitmen”. Acks=all adalah opsi teraman, tetapi juga menambahkan penundaan tambahan. Mari kita lihat dua contoh kegagalan dan bagaimana pilihan 'acks' yang berbeda berinteraksi dengan konsep ISR.

Acks=1 dan ISR

Dalam contoh ini, kita akan melihat bahwa jika pemimpin tidak menunggu sampai setiap pesan dari semua pengikut disimpan, maka kehilangan data mungkin terjadi jika pemimpin gagal. Menavigasi ke pengikut yang tidak disinkronkan dapat diaktifkan atau dinonaktifkan dengan pengaturan najis.pemimpin.pemilihan.aktifkan.

Dalam contoh ini, pabrikan memiliki nilai acks=1. Bagian ini didistribusikan ke ketiga broker. Broker 3 tertinggal, disinkronkan dengan pemimpin delapan detik yang lalu dan sekarang tertinggal 7456 pesan. Broker 1 hanya tertinggal satu detik. Produser kami mengirimkan pesan dan dengan cepat menerima balasan, tanpa harus menunggu pengikut yang lambat atau mati yang tidak ditunggu oleh pemimpin.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 7. ISR dengan tiga replika

Broker 2 gagal dan produsen menerima kesalahan koneksi. Setelah kepemimpinan berpindah ke broker 1, kami kehilangan 123 pesan. Pengikut pada broker 1 adalah bagian dari ISR, namun tidak sepenuhnya tersinkronisasi dengan pemimpin ketika jatuh.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 8. Pesan hilang saat crash

Dalam konfigurasi bootstrap.server Pabrikan memiliki beberapa broker yang terdaftar dan dapat bertanya kepada broker lain siapa yang menjadi pemimpin bagian baru. Kemudian membuat koneksi ke broker 1 dan terus mengirimkan pesan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 9. Pengiriman pesan dilanjutkan setelah istirahat sejenak

Broker 3 bahkan tertinggal jauh. Itu membuat permintaan pengambilan tetapi tidak dapat menyinkronkan. Hal ini mungkin disebabkan oleh koneksi jaringan yang lambat antar broker, masalah penyimpanan, dll. Ini dihapus dari ISR. Sekarang ISR terdiri dari satu replika - pemimpin! Pabrikan terus mengirimkan pesan dan menerima konfirmasi.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 10. Follower pada broker 3 dihapus dari ISR

Broker 1 turun dan peran kepemimpinan jatuh ke tangan broker 3 dengan hilangnya 15286 pesan! Pabrikan menerima pesan kesalahan koneksi. Transisi ke pemimpin di luar ISR hanya mungkin terjadi karena adanya situasi najis.pemimpin.pemilihan.aktifkan=benar. Jika sudah terpasang di palsu, maka transisi tidak akan terjadi dan semua permintaan baca dan tulis akan ditolak. Dalam hal ini, kami menunggu broker 1 kembali dengan data utuhnya di replika, yang akan kembali mengambil alih kepemimpinan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 11. Pialang 1 jatuh. Ketika terjadi kegagalan, banyak pesan yang hilang

Produser menjalin hubungan dengan broker terakhir dan melihat bahwa dia sekarang menjadi pemimpin bagian tersebut. Dia mulai mengirim pesan ke broker 3.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 12. Setelah istirahat sejenak, pesan dikirim lagi ke bagian 0

Kami melihat bahwa, selain interupsi singkat untuk membangun koneksi baru dan mencari pemimpin baru, pabrikan terus mengirimkan pesan. Konfigurasi ini menjamin ketersediaan dengan mengorbankan konsistensi (keamanan data). Kafka kehilangan ribuan pesan tetapi terus menerima pesan baru.

Acks=semua dan ISR

Mari kita ulangi skenario ini lagi, tapi dengan acks=semua. Broker 3 memiliki latensi rata-rata empat detik. Pabrikan mengirimkan pesan dengan acks=semua, dan sekarang tidak menerima tanggapan cepat. Pemimpin menunggu pesan disimpan oleh semua replika di ISR.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 13. ISR dengan tiga replika. Yang satu lambat, mengakibatkan penundaan perekaman

Setelah penundaan tambahan selama empat detik, broker 2 mengirimkan ack. Semua replika sekarang telah diperbarui sepenuhnya.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 14. Semua replika menyimpan pesan dan mengirim ack

Broker 3 kini semakin tertinggal dan dikeluarkan dari ISR. Latensi berkurang secara signifikan karena tidak ada replika lambat yang tersisa di ISR. Broker 2 sekarang hanya menunggu broker 1, dan ia memiliki rata-rata lag 500 ms.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 15. Replika pada broker 3 dihapus dari ISR

Kemudian broker 2 jatuh dan kepemimpinan berpindah ke broker 1 tanpa kehilangan pesan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 16. Pialang 2 jatuh

Pabrikan menemukan pemimpin baru dan mulai mengirimkan pesan kepadanya. Latensi semakin berkurang karena ISR kini terdiri dari satu replika! Oleh karena itu pilihannya acks=semua tidak menambah redundansi.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 17. Replika pada broker 1 memimpin tanpa kehilangan pesan

Kemudian broker 1 crash dan lead jatuh ke broker 3 dengan kehilangan 14238 pesan!

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 18. Broker 1 meninggal dan transisi kepemimpinan dengan lingkungan yang tidak bersih mengakibatkan hilangnya data dalam jumlah besar

Kami tidak dapat menginstal opsi tersebut najis.pemimpin.pemilihan.aktifkan ke dalam makna benar. Secara default sama dengan palsu. Pengaturan acks=semua с najis.pemimpin.pemilihan.aktifkan=benar menyediakan aksesibilitas dengan beberapa keamanan data tambahan. Namun seperti yang Anda lihat, kami masih bisa kehilangan pesan.

Namun bagaimana jika kita ingin meningkatkan keamanan data? Anda bisa menempatkan najis.pemimpin.pemilihan.aktifkan = salah, namun hal ini belum tentu melindungi kita dari kehilangan data. Jika pemimpin terjatuh dan mengambil datanya, maka pesan akan tetap hilang, ditambah ketersediaan hilang hingga administrator memulihkan situasi.

Lebih baik memastikan bahwa semua pesan berlebihan, dan jika tidak, buang rekamannya. Kemudian, setidaknya dari sudut pandang broker, kehilangan data hanya mungkin terjadi jika terjadi dua atau lebih kegagalan secara bersamaan.

Acks=all, min.insync.replika dan ISR

Dengan konfigurasi topik min.insync.replika Kami meningkatkan tingkat keamanan data. Mari kita ulangi bagian terakhir dari skenario sebelumnya, tapi kali ini dengan min.insync.replika=2.

Jadi broker 2 mempunyai replika leader dan follower pada broker 3 dikeluarkan dari ISR.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 19. ISR dari dua replika

Pialang 2 jatuh dan kepemimpinan berpindah ke pialang 1 tanpa kehilangan pesan. Namun kini ISR ​​hanya terdiri dari satu replika. Ini tidak memenuhi jumlah minimum untuk menerima catatan, dan oleh karena itu broker merespons upaya penulisan dengan kesalahan Replika Tidak Cukup.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 20. Jumlah ISR satu lebih rendah dari yang ditentukan di min.insync.replicas

Konfigurasi ini mengorbankan ketersediaan demi konsistensi. Sebelum mengakui suatu pesan, kami memastikan bahwa pesan tersebut ditulis ke setidaknya dua replika. Hal ini membuat pabrikan lebih percaya diri. Di sini, kehilangan pesan hanya mungkin terjadi jika dua replika gagal secara bersamaan dalam interval pendek hingga pesan direplikasi ke pengikut tambahan, yang kemungkinannya kecil. Namun jika Anda sangat paranoid, Anda dapat menyetel faktor replikasi ke 5, dan min.insync.replika oleh 3. Di sini tiga broker harus jatuh pada saat yang sama untuk kehilangan rekor! Tentu saja, Anda membayar keandalan ini dengan latensi tambahan.

Ketika aksesibilitas diperlukan untuk keamanan data

Seperti dalam kasus dengan RabbitMQ, terkadang aksesibilitas diperlukan untuk keamanan data. Inilah yang perlu Anda pikirkan:

  • Bisakah penerbit mengembalikan kesalahan dan meminta layanan upstream atau pengguna mencoba lagi nanti?
  • Bisakah penerbit menyimpan pesan secara lokal atau di database untuk dicoba lagi nanti?

Jika jawabannya tidak, maka mengoptimalkan ketersediaan akan meningkatkan keamanan data. Anda akan kehilangan lebih sedikit data jika memilih ketersediaan daripada tidak merekam. Jadi, semuanya bermuara pada menemukan keseimbangan, dan keputusannya bergantung pada situasi spesifik.

Arti ISR

Rangkaian ISR memungkinkan Anda memilih keseimbangan optimal antara keamanan data dan latensi. Misalnya, memastikan ketersediaan jika terjadi kegagalan pada sebagian besar replika, meminimalkan dampak replika yang mati atau lambat dalam hal latensi.

Kami memilih sendiri artinya replika.lag.time.max.ms sesuai dengan kebutuhan Anda. Intinya, parameter ini berarti berapa banyak penundaan yang ingin kita terima saat itu acks=semua. Nilai defaultnya adalah sepuluh detik. Jika ini terlalu lama bagi Anda, Anda bisa menguranginya. Kemudian frekuensi perubahan ISR akan meningkat, karena pengikut akan lebih sering dihapus dan ditambah.

RabbitMQ hanyalah sekumpulan cermin yang perlu direplikasi. Mirror lambat menimbulkan latensi tambahan, dan mirror mati dapat menunggu hingga paket yang memeriksa ketersediaan setiap node (net tick) merespons. ISR adalah cara menarik untuk menghindari masalah latensi ini. Namun kita berisiko kehilangan redundansi karena ISR hanya dapat menyusut hingga mencapai posisi terdepan. Untuk menghindari risiko ini, gunakan pengaturan min.insync.replika.

Jaminan koneksi klien

Dalam pengaturan bootstrap.server produsen dan konsumen dapat menentukan beberapa broker untuk menghubungkan klien. Idenya adalah ketika satu node mati, ada beberapa node cadangan yang tersisa sehingga klien dapat membuka koneksi. Ini belum tentu merupakan pemimpin bagian, tetapi hanya sebuah batu loncatan untuk pemuatan awal. Klien dapat menanyakan node mana yang menampung pemimpin partisi baca/tulis.

Di RabbitMQ, klien dapat terhubung ke node mana pun, dan perutean internal mengirimkan permintaan ke tempat yang dituju. Ini berarti Anda dapat memasang penyeimbang beban di depan RabbitMQ. Kafka mengharuskan klien untuk terhubung ke node yang menghosting pemimpin partisi yang sesuai. Dalam situasi seperti ini, Anda tidak dapat menginstal penyeimbang beban. Daftar bootstrap.server Sangat penting bagi klien untuk dapat mengakses dan menemukan node yang benar setelah terjadi kegagalan.

Arsitektur Konsensus Kafka

Hingga saat ini, kami belum mempertimbangkan bagaimana klaster mengetahui jatuhnya broker dan bagaimana pemimpin baru dipilih. Untuk memahami cara Kafka bekerja dengan partisi jaringan, Anda perlu memahami arsitektur konsensus terlebih dahulu.

Setiap klaster Kafka disebarkan bersama dengan klaster Zookeeper, yang merupakan layanan konsensus terdistribusi yang memungkinkan sistem mencapai konsensus pada beberapa negara bagian tertentu, dengan memprioritaskan konsistensi daripada ketersediaan. Persetujuan dari mayoritas node Zookeeper diperlukan untuk menyetujui operasi baca dan tulis.

Zookeeper menyimpan status cluster:

  • Daftar topik, bagian, konfigurasi, replika pemimpin saat ini, replika pilihan.
  • Anggota klaster. Setiap broker melakukan ping ke cluster Zookeeper. Jika tidak menerima ping dalam jangka waktu tertentu, maka Zookeeper mencatat broker tersebut sebagai tidak tersedia.
  • Memilih node utama dan cadangan untuk pengontrol.

Node pengontrol adalah salah satu broker Kafka yang bertanggung jawab memilih pemimpin replika. Zookeeper mengirimkan pemberitahuan ke pengontrol tentang keanggotaan cluster dan perubahan topik, dan pengontrol harus bertindak atas perubahan ini.

Sebagai contoh, mari kita ambil topik baru dengan sepuluh partisi dan faktor replikasi 3. Pengontrol harus memilih seorang pemimpin untuk setiap partisi, mencoba mendistribusikan pemimpin secara optimal di antara para broker.

Untuk setiap pengontrol bagian:

  • memperbarui informasi di Zookeeper tentang ISR dan pemimpin;
  • Mengirimkan LeaderAndISRCommand ke setiap broker yang menghosting replika partisi ini, memberi tahu broker tentang ISR dan pemimpinnya.

Ketika broker dengan pemimpin jatuh, Zookeeper mengirimkan pemberitahuan ke pengontrol, dan memilih pemimpin baru. Sekali lagi, pengontrol terlebih dahulu memperbarui Zookeeper dan kemudian mengirimkan perintah ke setiap broker yang memberi tahu mereka tentang perubahan kepemimpinan.

Setiap pemimpin bertanggung jawab merekrut ISR. Pengaturan replika.lag.time.max.ms menentukan siapa yang akan masuk ke sana. Ketika ISR berubah, pemimpin mengirimkan informasi baru ke Zookeeper.

Penjaga kebun binatang selalu diberitahu tentang perubahan apa pun sehingga jika terjadi kegagalan, manajemen akan bertransisi dengan lancar ke pemimpin baru.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 21. Konsensus Kafka

Protokol replikasi

Memahami detail replikasi membantu Anda lebih memahami potensi skenario kehilangan data.

Kueri pengambilan sampel, Log End Offset (LEO) dan Highwater Mark (HW)

Kami menganggap bahwa pengikut secara berkala mengirimkan permintaan pengambilan ke pemimpin. Interval defaultnya adalah 500 ms. Hal ini berbeda dengan RabbitMQ karena replikasi di RabbitMQ tidak dimulai oleh cermin antrian tetapi oleh master. Master mendorong perubahan ke cermin.

Pemimpin dan seluruh pengikut menyimpan label Log End Offset (LEO) dan Highwater (HW). Tanda LEO menyimpan offset pesan terakhir di replika lokal, dan HW menyimpan offset dari penerapan terakhir. Ingatlah bahwa untuk status penerapan, pesan harus tetap ada di seluruh replika ISR. Artinya LEO biasanya sedikit di depan HW.

Ketika pemimpin menerima pesan, ia menyimpannya secara lokal. Pengikut membuat permintaan pengambilan dengan mengirimkan LEO miliknya. Pemimpin kemudian mengirimkan sejumlah pesan mulai dari LEO ini dan juga mengirimkan HW saat ini. Ketika pemimpin menerima informasi bahwa semua replika telah menyimpan pesan pada offset yang diberikan, ia memindahkan tanda HW. Hanya pemimpin yang dapat menggerakkan HW, sehingga semua pengikut akan mengetahui nilai terkini dari respons terhadap permintaan mereka. Ini berarti bahwa pengikut mungkin tertinggal dari pemimpin dalam hal pesan dan pengetahuan HW. Konsumen menerima pesan hanya sampai HW saat ini.

Perhatikan bahwa "bertahan" berarti ditulis ke memori, bukan ke disk. Untuk performa, Kafka melakukan sinkronisasi ke disk pada interval tertentu. RabbitMQ juga memiliki interval seperti itu, tetapi ia akan mengirimkan pengakuan ke penerbit hanya setelah master dan semua mirror menulis pesan ke disk. Pengembang Kafka, karena alasan kinerja, memutuskan untuk mengirimkan ack segera setelah pesan ditulis ke memori. Kafka yakin bahwa redundansi mengimbangi risiko penyimpanan singkat pesan yang diakui hanya di memori.

Kegagalan pemimpin

Ketika seorang pemimpin jatuh, Zookeeper memberi tahu pengontrol, dan ia memilih replika pemimpin baru. Pemimpin baru menetapkan tanda HW baru sesuai dengan LEO-nya. Pengikut kemudian menerima informasi tentang pemimpin baru. Bergantung pada versi Kafka, pengikut akan memilih salah satu dari dua skenario:

  1. Ini akan memotong log lokal ke HW yang dikenal dan mengirim permintaan ke pemimpin baru untuk pesan setelah tanda ini.
  2. Akan mengirimkan permintaan kepada pemimpin untuk mengetahui HW pada saat dia terpilih sebagai pemimpin, dan kemudian memotong log ke offset ini. Kemudian akan mulai membuat permintaan pengambilan berkala mulai dari offset ini.

Seorang pengikut mungkin perlu memotong log karena alasan berikut:

  • Ketika seorang pemimpin gagal, pengikut pertama di set ISR yang terdaftar di Zookeeper memenangkan pemilihan dan menjadi pemimpin. Semua pengikut di ISR, meskipun dianggap “sinkron,” mungkin tidak menerima salinan semua pesan dari mantan pemimpin tersebut. Sangat mungkin bahwa pengikut yang ditampilkan tidak memiliki salinan terbaru. Kafka memastikan tidak ada perbedaan antar replika. Oleh karena itu, untuk menghindari perbedaan, setiap pengikut harus memotong lognya menjadi nilai HW pemimpin baru pada saat pemilihannya. Ini adalah alasan lain mengapa pengaturan acks=semua sangat penting untuk konsistensi.
  • Pesan ditulis secara berkala ke disk. Jika semua node cluster gagal pada saat yang sama, maka replika dengan offset berbeda akan disimpan di disk. Ada kemungkinan ketika broker kembali online, pemimpin baru yang terpilih akan berada di belakang pengikutnya karena dia disimpan ke disk sebelum yang lain.

Reuni dengan cluster

Saat bergabung kembali dengan klaster, replika melakukan hal yang sama seperti saat pemimpin gagal: mereka memeriksa replika pemimpin dan memotong log mereka ke HW-nya (pada saat pemilihan). Sebagai perbandingan, RabbitMQ sama-sama memperlakukan node yang disatukan kembali sebagai node yang benar-benar baru. Dalam kedua kasus tersebut, broker membuang negara bagian yang ada. Jika sinkronisasi otomatis digunakan, maka master harus benar-benar mereplikasi semua konten saat ini ke mirror baru dengan metode “biarkan seluruh dunia menunggu”. Master tidak menerima operasi baca atau tulis apa pun selama operasi ini. Pendekatan ini menciptakan masalah dalam antrian yang besar.

Kafka adalah log terdistribusi, dan secara umum ia menyimpan lebih banyak pesan daripada antrean RabbitMQ, tempat data dihapus dari antrean setelah dibaca. Antrean aktif harus tetap relatif kecil. Namun Kafka adalah log dengan kebijakan penyimpanannya sendiri, yang dapat menetapkan jangka waktu beberapa hari atau minggu. Pendekatan pemblokiran antrian dan sinkronisasi penuh benar-benar tidak dapat diterima untuk log terdistribusi. Sebaliknya, pengikut Kafka hanya memotong catatan mereka ke HW pemimpin (pada saat pemilihannya) jika salinannya ada di depan pemimpin. Dalam kasus yang lebih mungkin terjadi, ketika pengikut berada di belakang, ia akan mulai membuat permintaan pengambilan yang dimulai dengan LEO-nya saat ini.

Pengikut baru atau yang bergabung kembali memulai di luar ISR dan tidak berpartisipasi dalam komitmen. Mereka hanya bekerja bersama kelompoknya, menerima pesan secepat mungkin hingga mereka berhasil menyusul pemimpinnya dan memasuki ISR. Tidak ada penguncian dan tidak perlu membuang semua data Anda.

Hilangnya konektivitas

Kafka memiliki lebih banyak komponen daripada RabbitMQ, sehingga memiliki serangkaian perilaku yang lebih kompleks ketika cluster terputus. Namun Kafka pada awalnya dirancang untuk cluster, sehingga solusinya dipikirkan dengan sangat matang.

Berikut adalah beberapa skenario kegagalan konektivitas:

  • Skenario 1: Pengikut tidak melihat pemimpinnya, namun tetap melihat Penjaga Kebun Binatang.
  • Skenario 2: Pemimpin tidak melihat pengikut apa pun, namun tetap melihat Penjaga Kebun Binatang.
  • Skenario 3: Pengikut melihat pemimpinnya, tetapi tidak melihat Penjaga Kebun Binatang.
  • Skenario 4: Pemimpin melihat pengikutnya, namun tidak melihat Penjaga Kebun Binatang.
  • Skenario 5: Pengikut benar-benar terpisah dari node Kafka dan Zookeeper lainnya.
  • Skenario 6: Pemimpin benar-benar terpisah dari node Kafka dan Zookeeper lainnya.
  • Skenario 7: Node pengontrol Kafka tidak dapat melihat node Kafka lainnya.
  • Skenario 8: Pengontrol Kafka tidak melihat Zookeeper.

Setiap skenario memiliki perilakunya sendiri.

Skenario 1: Pengikut tidak melihat pemimpinnya, namun tetap melihat Penjaga Kebun Binatang

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 22. Skenario 1: ISR dari tiga replika

Kegagalan konektivitas memisahkan broker 3 dari broker 1 dan 2, namun tidak dari Zookeeper. Broker 3 tidak dapat lagi mengirimkan permintaan pengambilan. Setelah waktu berlalu replika.lag.time.max.ms itu dihapus dari ISR ​​dan tidak berpartisipasi dalam komitmen pesan. Setelah konektivitas dipulihkan, permintaan pengambilan akan dilanjutkan dan bergabung dengan ISR ketika berhasil mengejar pemimpinnya. Penjaga kebun binatang akan terus menerima ping dan berasumsi bahwa broker tersebut masih hidup dan sehat.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 23. Skenario 1: Broker dihapus dari ISR ​​jika tidak ada permintaan pengambilan yang diterima dari broker tersebut dalam interval replica.lag.time.max.ms

Tidak ada suspensi otak terpisah atau simpul seperti di RabbitMQ. Sebaliknya, redundansi dikurangi.

Skenario 2: Pemimpin tidak melihat pengikut apa pun, namun tetap melihat Penjaga Kebun Binatang

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 24. Skenario 2. Pemimpin dan dua pengikut

Gangguan dalam konektivitas jaringan memisahkan pemimpin dari pengikut, namun broker masih dapat melihat Zookeeper. Seperti dalam skenario pertama, ISR menyusut, namun kali ini hanya ke pemimpin karena semua pengikut berhenti mengirimkan permintaan pengambilan. Sekali lagi, tidak ada pembagian logis. Sebaliknya, terjadi kehilangan redundansi untuk pesan-pesan baru hingga konektivitas dipulihkan. Penjaga kebun binatang terus menerima ping dan yakin bahwa broker tersebut masih hidup dan sehat.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 25. Skenario 2. ISR menyusut hanya pada pemimpin

Skenario 3. Pengikut melihat pemimpin, namun tidak melihat Penjaga Kebun Binatang

Pengikut dipisahkan dari Penjaga Kebun Binatang, tetapi tidak dipisahkan dari perantara dengan pemimpin. Hasilnya, pengikut terus melakukan permintaan pengambilan dan menjadi anggota ISR. Zookeeper tidak lagi menerima ping dan mencatat kerusakan broker, tetapi karena hanya pengikut, tidak ada konsekuensi setelah pemulihan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 26. Skenario 3: Pengikut terus mengirimkan permintaan pengambilan ke pemimpin

Skenario 4. Pemimpin melihat pengikut, namun tidak melihat Penjaga Kebun Binatang

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 27. Skenario 4. Pemimpin dan dua pengikut

Pemimpin dipisahkan dari Penjaga Kebun Binatang, namun tidak dipisahkan dari perantara yang memiliki pengikut.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 28. Skenario 4: Pemimpin diisolasi dari Penjaga Kebun Binatang

Setelah beberapa waktu, Zookeeper akan mendaftarkan kegagalan broker dan memberi tahu pengontrol tentang hal itu. Dia akan memilih pemimpin baru di antara para pengikutnya. Namun, pemimpin asli akan terus berpikir bahwa itu adalah pemimpinnya dan akan terus menerima entri darinya jawaban=1. Pengikut tidak lagi mengiriminya permintaan pengambilan, jadi dia akan menganggapnya mati dan mencoba mengecilkan ISR ke dirinya sendiri. Namun karena ia tidak memiliki koneksi ke Zookeeper, ia tidak akan dapat melakukan hal ini, dan pada saat itu ia akan menolak menerima entri lebih lanjut.

Сообщения acks=semua tidak akan menerima pengakuan karena ISR terlebih dahulu mengaktifkan semua replika, dan pesan tidak sampai ke replika tersebut. Ketika pemimpin asli mencoba untuk menghapus mereka dari ISR, mereka tidak akan mampu melakukannya dan akan berhenti menerima pesan apa pun sama sekali.

Klien segera menyadari perubahan pemimpin dan mulai mengirimkan catatan ke server baru. Setelah jaringan dipulihkan, pemimpin asli melihat bahwa jaringan tersebut bukan lagi pemimpin dan memotong lognya ke nilai HW yang dimiliki pemimpin baru pada saat kegagalan untuk menghindari divergensi log. Kemudian akan mulai mengirimkan permintaan pengambilan ke pemimpin baru. Semua catatan dari pemimpin asli yang tidak direplikasi ke pemimpin baru akan hilang. Artinya, pesan-pesan yang tidak diketahui oleh pemimpin asli dalam beberapa detik ketika dua pemimpin sedang bekerja akan hilang.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 29. Skenario 4. Pemimpin pada broker 1 menjadi pengikut setelah jaringan pulih

Skenario 5: Pengikut benar-benar terpisah dari node Kafka dan Zookeeper lainnya

Pengikutnya sepenuhnya terisolasi dari node Kafka dan Zookeeper lainnya. Dia hanya menghapus dirinya dari ISR ​​sampai jaringan pulih, dan kemudian menyusul yang lain.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 30. Skenario 5: Pengikut yang terisolasi dihapus dari ISR

Skenario 6: Pemimpin benar-benar terpisah dari node Kafka dan Zookeeper lainnya

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 31. Skenario 6. Pemimpin dan dua pengikut

Pemimpinnya benar-benar terisolasi dari para pengikutnya, pengontrol dan Penjaga Kebun Binatang. Untuk waktu yang singkat, mereka akan terus menerima entri dari jawaban=1.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 32. Skenario 6: Mengisolasi pemimpin dari node Kafka dan Zookeeper lainnya

Belum menerima permintaan setelah habis masa berlakunya replika.lag.time.max.ms, ia akan mencoba mengecilkan ISR ke dirinya sendiri, tetapi tidak dapat melakukannya karena tidak ada komunikasi dengan Zookeeper, maka ia akan berhenti menerima tulisan.

Sementara itu, Penjaga Kebun Binatang akan menandai broker yang terisolasi itu sebagai orang mati dan pengawas akan memilih pemimpin baru.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 33. Skenario 6. Dua pemimpin

Pemimpin asli mungkin menerima entri selama beberapa detik, tetapi kemudian berhenti menerima pesan apa pun. Klien diperbarui setiap 60 detik dengan metadata terbaru. Mereka akan diberitahu tentang pergantian pemimpin dan akan mulai mengirimkan entri ke pemimpin baru.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 34. Skenario 6: Produsen beralih ke pemimpin baru

Semua entri yang dikonfirmasi dibuat oleh pemimpin asli sejak hilangnya konektivitas akan hilang. Setelah jaringan dipulihkan, pemimpin asli akan mengetahui melalui Zookeeper bahwa ia bukan lagi pemimpin. Kemudian ia akan memotong lognya ke HW pemimpin baru pada saat pemilihan dan mulai mengirimkan permintaan sebagai pengikut.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi
Beras. 35. Skenario 6: Pemimpin asli menjadi pengikut setelah konektivitas jaringan dipulihkan

Dalam situasi ini, pemisahan logis mungkin terjadi dalam waktu singkat, tetapi hanya jika jawaban=1 и min.insync.replika juga 1. Pemisahan logis secara otomatis berakhir setelah jaringan dipulihkan, ketika pemimpin asli menyadari bahwa dia bukan lagi pemimpin, atau ketika semua klien menyadari bahwa pemimpin telah berubah dan mulai menulis surat kepada pemimpin baru - mana saja yang lebih dulu. Bagaimanapun, beberapa pesan akan hilang, tetapi hanya dengan jawaban=1.

Ada varian lain dari skenario ini di mana, tepat sebelum jaringan terpecah, para pengikut tertinggal dan pemimpin memampatkan ISR menjadi dirinya sendiri. Kemudian menjadi terisolasi karena hilangnya konektivitas. Seorang pemimpin baru dipilih, tetapi pemimpin asli tetap menerima entri acks=semua, karena tidak ada orang lain di ISR ​​kecuali dia. Catatan ini akan hilang setelah jaringan dipulihkan. Satu-satunya cara untuk menghindari opsi ini adalah min.insync.replika = 2.

Skenario 7: Node Pengontrol Kafka Tidak Dapat Melihat Node Kafka Lainnya

Secara umum, setelah koneksi dengan node Kafka terputus, pengontrol tidak akan dapat mengirimkan informasi perubahan pemimpin apa pun ke node tersebut. Dalam kasus terburuk, hal ini akan mengarah pada pemisahan logis jangka pendek, seperti dalam skenario 6. Seringkali, broker tidak akan menjadi kandidat kepemimpinan jika kandidat tersebut gagal.

Skenario 8: Pengontrol Kafka tidak melihat Zookeeper

Zookeeper tidak akan menerima ping dari pengontrol yang jatuh dan akan memilih node Kafka baru sebagai pengontrol. Pengontrol asli dapat terus menampilkan dirinya seperti itu, tetapi tidak menerima pemberitahuan dari Zookeeper, sehingga tidak ada tugas yang harus dilakukan. Setelah jaringan pulih, dia akan menyadari bahwa dia bukan lagi pengontrol, tetapi telah menjadi node Kafka biasa.

Kesimpulan dari skenario

Kami melihat bahwa hilangnya konektivitas pengikut tidak mengakibatkan hilangnya pesan, namun hanya mengurangi redundansi untuk sementara hingga jaringan dipulihkan. Hal ini tentu saja dapat menyebabkan hilangnya data jika satu atau lebih node hilang.

Jika pemimpin terpisah dari Penjaga Kebun Binatang karena hilangnya konektivitas, hal ini dapat mengakibatkan hilangnya pesan jawaban=1. Kurangnya komunikasi dengan Zookeeper menyebabkan perpecahan logis singkat antara kedua pemimpin tersebut. Masalah ini diselesaikan dengan parameter acks=semua.

Parameter min.insync.replika menjadi dua atau lebih replika memberikan jaminan tambahan bahwa skenario jangka pendek tersebut tidak akan mengakibatkan hilangnya pesan seperti pada Skenario 6.

Ringkasan Pesan yang Hilang

Mari daftar semua cara Anda bisa kehilangan data di Kafka:

  • Kegagalan pemimpin apa pun jika pesan dikonfirmasi menggunakan jawaban=1
  • Setiap transisi kepemimpinan yang tidak bersih, yaitu menjadi pengikut di luar ISR, bahkan dengan acks=semua
  • Mengisolasi pemimpin dari Penjaga Kebun Binatang jika pesan dikonfirmasi menggunakan jawaban=1
  • Isolasi total terhadap pemimpin yang telah menyusutkan kelompok ISR menjadi dirinya sendiri. Bahkan semua pesan akan hilang acks=semua. Hal ini hanya berlaku jika min.insync.replika=1.
  • Kegagalan simultan dari semua node partisi. Karena pesan diakui dari memori, beberapa pesan mungkin belum ditulis ke disk. Setelah me-reboot server, beberapa pesan mungkin hilang.

Transisi kepemimpinan yang tidak murni dapat dihindari dengan melarangnya atau memastikan setidaknya dua kali pemutusan hubungan kerja. Konfigurasi yang paling tahan lama adalah kombinasi acks=semua и min.insync.replika lebih dari 1.

Perbandingan langsung keandalan RabbitMQ dan Kafka

Untuk memastikan keandalan dan ketersediaan tinggi, kedua platform menerapkan sistem replikasi primer dan sekunder. Namun, RabbitMQ memiliki kelemahan. Saat menyambung kembali setelah kegagalan, node membuang datanya dan sinkronisasi diblokir. Pukulan ganda ini mempertanyakan umur panjang antrian besar di RabbitMQ. Anda harus menerima pengurangan redundansi atau waktu pemblokiran yang lama. Mengurangi redundansi akan meningkatkan risiko kehilangan data secara besar-besaran. Namun jika antriannya kecil, maka demi redundansi, ketidaktersediaan dalam waktu singkat (beberapa detik) dapat diatasi dengan menggunakan upaya koneksi berulang-ulang.

Kafka tidak memiliki masalah ini. Ini membuang data hanya dari titik perbedaan antara pemimpin dan pengikut. Semua data bersama disimpan. Selain itu, replikasi tidak memblokir sistem. Pemimpin terus menerima postingan sementara pengikut baru mengejar ketinggalan, jadi bagi devop, bergabung atau bergabung kembali dengan cluster menjadi tugas yang sepele. Tentu saja masih ada masalah seperti bandwidth jaringan selama replikasi. Jika Anda menambahkan beberapa pengikut sekaligus, Anda mungkin mengalami batas bandwidth.

RabbitMQ lebih unggul dari Kafka dalam hal keandalan ketika beberapa server dalam satu cluster gagal pada saat yang bersamaan. Seperti yang telah kami katakan, RabbitMQ mengirimkan konfirmasi ke penerbit hanya setelah pesan ditulis ke disk oleh master dan semua mirror. Namun hal ini menambah latensi tambahan karena dua alasan:

  • fsync setiap beberapa ratus milidetik
  • Kegagalan mirror hanya dapat diketahui setelah masa pakai paket yang memeriksa ketersediaan setiap node (net tick) telah habis. Jika cermin melambat atau jatuh, hal ini menambah penundaan.

Taruhan Kafka adalah jika sebuah pesan disimpan di beberapa node, ia dapat mengenali pesan segera setelah mencapai memori. Oleh karena itu, ada risiko kehilangan pesan jenis apa pun (bahkan acks=semua, min.insync.replika=2) jika terjadi kegagalan secara bersamaan.

Secara keseluruhan, Kafka menunjukkan kinerja perangkat lunak yang lebih baik dan dirancang dari awal untuk cluster. Jumlah pengikut dapat ditingkatkan menjadi 11 jika diperlukan untuk keandalan. Faktor replikasi 5 dan jumlah minimum replika dalam sinkronisasi min.insync.replika=3 akan membuat hilangnya pesan menjadi peristiwa yang sangat jarang terjadi. Jika infrastruktur Anda dapat mendukung rasio replikasi dan tingkat redundansi ini, Anda dapat memilih opsi ini.

Pengelompokan RabbitMQ bagus untuk antrian kecil. Namun antrean kecil pun dapat bertambah dengan cepat ketika lalu lintas padat. Ketika antrean menjadi besar, Anda harus membuat pilihan sulit antara ketersediaan dan keandalan. Pengelompokan RabbitMQ paling cocok untuk situasi yang tidak biasa di mana manfaat fleksibilitas RabbitMQ lebih besar daripada kerugian pengelompokannya.

Salah satu penangkal kerentanan RabbitMQ terhadap antrean besar adalah dengan memecahnya menjadi beberapa antrean yang lebih kecil. Jika Anda tidak memerlukan pengurutan lengkap seluruh antrian, tetapi hanya pesan yang relevan (misalnya, pesan dari klien tertentu), atau tidak memesan apa pun sama sekali, maka opsi ini dapat diterima: lihat proyek saya penyeimbang ulang untuk membagi antrian (proyek masih dalam tahap awal).

Terakhir, jangan lupakan sejumlah bug dalam mekanisme pengelompokan dan replikasi RabbitMQ dan Kafka. Seiring berjalannya waktu, sistem menjadi lebih matang dan stabil, namun tidak ada pesan yang 100% aman dari kehilangan! Selain itu, kecelakaan skala besar terjadi di pusat data!

Jika saya melewatkan sesuatu, membuat kesalahan, atau Anda tidak setuju dengan salah satu poin, jangan ragu untuk menulis komentar atau menghubungi saya.

Saya sering ditanya: “Apa yang harus dipilih, Kafka atau RabbitMQ?”, “Platform mana yang lebih baik?”. Sebenarnya hal ini sangat bergantung pada situasi Anda, pengalaman saat ini, dll. Saya ragu untuk memberikan pendapat saya karena akan terlalu menyederhanakan jika merekomendasikan satu platform untuk semua kasus penggunaan dan kemungkinan batasannya. Saya menulis rangkaian artikel ini agar Anda dapat membentuk opini Anda sendiri.

Saya ingin mengatakan bahwa kedua sistem adalah pemimpin dalam bidang ini. Saya mungkin sedikit bias karena dari pengalaman saya dengan proyek, saya cenderung menghargai hal-hal seperti jaminan pemesanan pesan dan keandalan.

Saya melihat teknologi lain yang tidak memiliki keandalan dan jaminan pemesanan, lalu saya melihat RabbitMQ dan Kafka dan menyadari nilai luar biasa dari kedua sistem ini.

Sumber: www.habr.com

Tambah komentar