RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster

Toleransi kesalahan dan ketersediaan tinggi adalah topik besar, jadi kami akan menyediakan artikel terpisah untuk RabbitMQ dan Kafka. Artikel ini tentang RabbitMQ, dan artikel berikutnya tentang Kafka, dibandingkan dengan RabbitMQ. Ini artikel yang panjang, jadi buatlah diri Anda nyaman.

Mari kita lihat strategi toleransi kesalahan, konsistensi, dan ketersediaan tinggi (HA) serta pengorbanan yang dilakukan setiap strategi. RabbitMQ dapat berjalan pada sekelompok node - dan kemudian diklasifikasikan sebagai sistem terdistribusi. Ketika berbicara tentang sistem terdistribusi, kita sering berbicara tentang konsistensi dan ketersediaan.

Konsep-konsep ini menggambarkan bagaimana suatu sistem berperilaku ketika gagal. Kegagalan koneksi jaringan, kegagalan server, kegagalan hard drive, tidak tersedianya server sementara karena pengumpulan sampah, kehilangan paket, atau koneksi jaringan yang lambat. Semua ini dapat menyebabkan hilangnya data atau konflik. Ternyata hampir tidak mungkin untuk membuat sistem yang benar-benar konsisten (tidak ada kehilangan data, tidak ada perbedaan data) dan tersedia (akan menerima baca dan tulis) untuk semua skenario kegagalan.

Kita akan melihat bahwa konsistensi dan ketersediaan berada pada ujung spektrum yang berlawanan, dan Anda harus memilih cara mana yang akan dioptimalkan. Kabar baiknya adalah dengan RabbitMQ pilihan ini dimungkinkan. Anda memiliki tuas β€œkutu buku” semacam ini untuk menggeser keseimbangan menuju konsistensi yang lebih besar atau aksesibilitas yang lebih besar.

Kami akan memberikan perhatian khusus pada konfigurasi mana yang menyebabkan hilangnya data karena catatan yang dikonfirmasi. Ada rantai tanggung jawab antara penerbit, broker dan konsumen. Setelah pesan dikirimkan ke broker, tugasnya adalah tidak kehilangan pesan tersebut. Ketika broker mengakui penerimaan pesan oleh penerbit, kami tidak berharap pesan itu hilang. Namun kita akan melihat bahwa hal ini sebenarnya dapat terjadi tergantung pada konfigurasi broker dan penerbit Anda.

Primitif Ketahanan Node Tunggal

Antrian/Perutean yang Tangguh

Ada dua jenis antrian di RabbitMQ: tahan lama dan tidak tahan lama. Semua antrian disimpan di database Mnesia. Antrean yang tahan lama diiklankan kembali saat startup node dan dengan demikian bertahan saat restart, sistem crash, atau server crash (selama data tetap ada). Artinya selama Anda menyatakan perutean (pertukaran) dan antrean tangguh, maka infrastruktur antrean/perutean akan kembali online.

Antrean dan perutean yang mudah berubah akan dihapus ketika node di-restart.

Pesan yang terus-menerus

Hanya karena antrian tahan lama tidak berarti bahwa semua pesannya akan bertahan saat node dihidupkan ulang. Hanya pesan yang ditetapkan oleh penerbit sebagai ulet (gigih). Pesan yang terus-menerus memang menimbulkan beban tambahan pada broker, namun jika kehilangan pesan tidak dapat diterima, maka tidak ada pilihan lain.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 1. Matriks keberlanjutan

Pengelompokan dengan pencerminan antrian

Untuk bertahan dari hilangnya seorang broker, kita memerlukan redundansi. Kita dapat menggabungkan beberapa node RabbitMQ ke dalam sebuah cluster, dan kemudian menambahkan redundansi tambahan dengan mereplikasi antrian di antara beberapa node. Dengan cara ini, jika satu node gagal, kami tidak kehilangan data dan tetap tersedia.

Pencerminan antrian:

  • satu antrian utama (master), yang menerima semua perintah tulis dan baca
  • satu atau lebih mirror yang menerima semua pesan dan metadata dari antrian utama. Cermin ini tidak ada untuk penskalaan, tetapi murni untuk redundansi.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 2. Pencerminan antrian

Mirroring diatur oleh kebijakan yang sesuai. Di dalamnya Anda dapat memilih koefisien replikasi dan bahkan node tempat antrian harus ditempatkan. Contoh:

  • ha-mode: all
  • ha-mode: exactly, ha-params: 2 (satu master dan satu cermin)
  • ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2

Konfirmasi penerbit

Untuk mencapai pencatatan yang konsisten, Konfirmasi Penerbit diperlukan. Tanpanya, ada risiko pesan hilang. Konfirmasi dikirim ke penerbit setelah pesan ditulis ke disk. RabbitMQ menulis pesan ke disk bukan setelah diterima, tetapi secara berkala, dalam waktu beberapa ratus milidetik. Ketika antrian dicerminkan, pengakuan dikirim hanya setelah semua mirror juga menulis salinan pesan mereka ke disk. Artinya, penggunaan konfirmasi menambah latensi, namun jika keamanan data penting, maka konfirmasi diperlukan.

Antrean kegagalan

Ketika broker berhenti atau crash, semua pemimpin antrian (master) pada node tersebut ikut crash. Cluster kemudian memilih mirror tertua dari setiap master dan mempromosikannya sebagai master baru.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 3. Beberapa antrian cermin dan kebijakannya

Pialang 3 turun. Perhatikan bahwa mirror Antrian C pada Broker 2 sedang dipromosikan menjadi master. Perhatikan juga bahwa mirror baru telah dibuat untuk Antrean C di Broker 1. RabbitMQ selalu berupaya mempertahankan faktor replikasi yang ditentukan dalam kebijakan Anda.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 4. Broker 3 gagal sehingga menyebabkan antrian C gagal

Broker 1 berikutnya jatuh! Kami hanya memiliki satu broker yang tersisa. Cermin Antrean B dipromosikan menjadi master.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Gambar. 5

Kami telah mengembalikan Broker 1. Terlepas dari seberapa baik data bertahan dari kehilangan dan pemulihan broker, semua pesan antrian yang dicerminkan akan dibuang saat restart. Hal ini penting untuk diperhatikan karena akan ada konsekuensinya. Kami akan segera melihat implikasinya. Jadi Broker 1 kini menjadi anggota klaster lagi, dan klaster tersebut mencoba mematuhi kebijakan tersebut sehingga membuat mirror pada Broker 1.

Dalam hal ini, hilangnya Broker 1 telah selesai, begitu pula datanya, sehingga Antrean B yang tidak dicerminkan telah hilang sepenuhnya.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 6. Broker 1 kembali beroperasi

Broker 3 kembali online, jadi antrian A dan B mendapatkan kembali mirror yang dibuat untuk memenuhi kebijakan HA mereka. Tapi sekarang semua antrian utama ada di satu node! Ini tidak ideal, pemerataan antar node lebih baik. Sayangnya, tidak banyak pilihan di sini untuk menyeimbangkan kembali master. Kami akan membahas masalah ini lagi nanti karena kami perlu melihat sinkronisasi antrian terlebih dahulu.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 7. Broker 3 kembali beroperasi. Semua antrian utama di satu node!

Jadi sekarang Anda harus memiliki gambaran tentang bagaimana mirror memberikan redundansi dan toleransi kesalahan. Hal ini memastikan ketersediaan jika terjadi kegagalan satu node dan melindungi terhadap kehilangan data. Tapi kita belum selesai, karena kenyataannya ini jauh lebih rumit.

Sinkronisasi

Saat membuat mirror baru, semua pesan baru akan selalu direplikasi ke mirror ini dan mirror lainnya. Sedangkan untuk data yang ada di antrian master, kita bisa mereplikasinya ke mirror baru, yang menjadi salinan lengkap dari master tersebut. Kita juga dapat memilih untuk tidak mereplikasi pesan yang ada dan membiarkan antrean utama dan cermin baru bertemu pada waktunya, dengan pesan baru tiba di bagian belakang dan pesan yang ada meninggalkan antrean utama.

Sinkronisasi ini dilakukan secara otomatis atau manual dan dikelola menggunakan kebijakan antrian. Mari kita lihat sebuah contoh.

Kami memiliki dua antrian cermin. Antrean A tersinkronisasi secara otomatis, dan Antrian B tersinkronisasi secara manual. Kedua antrian berisi sepuluh pesan.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 8. Dua antrian dengan mode sinkronisasi berbeda

Sekarang kita kehilangan Broker 3.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 9. Broker 3 tumbang

Broker 3 kembali beroperasi. Cluster membuat cermin untuk setiap antrian pada node baru dan secara otomatis menyinkronkan Antrean A baru dengan master. Namun, cermin Antrean B yang baru tetap kosong. Dengan cara ini kita memiliki redundansi penuh pada Antrean A dan hanya satu mirror untuk pesan Antrean B yang ada.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 10. Mirror baru dari Queue A menerima semua pesan yang ada, namun mirror baru dari Queue B tidak.

Sepuluh pesan lagi tiba di kedua antrean. Broker 2 kemudian crash dan Queue A kembali ke mirror terlama, yaitu di Broker 1. Tidak ada data yang hilang ketika gagal. Di Antrian B, ada dua puluh pesan di master dan hanya sepuluh di mirror karena antrean ini tidak pernah mereplikasi sepuluh pesan asli.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 11. Antrean A dikembalikan ke Broker 1 tanpa kehilangan pesan

Sepuluh pesan lagi tiba di kedua antrean. Sekarang Broker 1 crash. Antrian A dengan mudah beralih ke mirror tanpa kehilangan pesan. Namun Antrian B mengalami kendala. Pada titik ini kami dapat mengoptimalkan ketersediaan atau konsistensi.

Jika kita ingin mengoptimalkan aksesibilitas, maka kebijakannya ha-promosikan-kegagalan harus dipasang di selalu. Ini adalah nilai default, jadi Anda tidak bisa menentukan kebijakan sama sekali. Dalam hal ini, kami pada dasarnya mengizinkan kegagalan pada mirror yang tidak disinkronkan. Hal ini akan menyebabkan pesan hilang, namun antrian akan tetap dapat dibaca dan ditulis.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 12. Antrian A dikembalikan ke Broker 3 tanpa kehilangan pesan. Antrean B kembali ke Broker 3 dengan sepuluh pesan hilang

Kami juga dapat menginstal ha-promote-on-failure ke dalam makna when-synced. Dalam hal ini, alih-alih memutar kembali ke mirror, antrian akan menunggu hingga Broker 1 dengan datanya kembali ke mode online. Setelah kembali, antrian utama kembali ke Broker 1 tanpa kehilangan data. Ketersediaan dikorbankan demi keamanan data. Namun ini adalah mode berisiko yang bahkan dapat menyebabkan hilangnya data sepenuhnya, yang akan segera kita bahas.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 13. Antrian B tetap tidak tersedia setelah kehilangan Broker 1

Anda mungkin bertanya, β€œApakah lebih baik tidak menggunakan sinkronisasi otomatis?” Jawabannya adalah sinkronisasi adalah operasi pemblokiran. Selama sinkronisasi, antrian utama tidak dapat melakukan operasi baca atau tulis apa pun!

Mari kita lihat sebuah contoh. Sekarang kami memiliki antrian yang sangat panjang. Bagaimana mereka bisa tumbuh sebesar itu? Untuk beberapa alasan:

  • Antrian tidak digunakan secara aktif
  • Ini adalah antrian berkecepatan tinggi, dan saat ini konsumen sedang lambat
  • Ini antrian berkecepatan tinggi, ada kesalahan dan konsumen mulai mengejar

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 14. Dua antrian besar dengan mode sinkronisasi berbeda

Sekarang Broker 3 tumbang.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 15. Broker 3 gugur, meninggalkan satu master dan mirror di setiap antrian

Broker 3 kembali online dan mirror baru dibuat. Antrian Utama A mulai mereplikasi pesan yang ada ke mirror baru, dan selama waktu ini Antrean tidak tersedia. Diperlukan waktu dua jam untuk mereplikasi data, yang mengakibatkan waktu henti selama dua jam untuk Antrean ini!

Namun, Antrean B tetap tersedia sepanjang periode. Dia mengorbankan beberapa redundansi untuk aksesibilitas.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 16. Antrian tetap tidak tersedia selama sinkronisasi

Setelah dua jam, Antrean A juga tersedia dan dapat mulai menerima baca dan tulis lagi.

Update

Perilaku pemblokiran selama sinkronisasi ini mempersulit pembaruan klaster dengan antrean yang sangat besar. Pada titik tertentu, node master perlu di-restart, yang berarti beralih ke mirror atau menonaktifkan antrian saat server sedang ditingkatkan. Jika kita memilih untuk melakukan transisi, kita akan kehilangan pesan jika mirror tidak disinkronkan. Secara default, selama penghentian broker, failover ke mirror yang tidak disinkronkan tidak dilakukan. Artinya segera setelah broker kembali, kami tidak kehilangan pesan apa pun, satu-satunya kerusakan adalah antrian sederhana. Aturan perilaku ketika koneksi broker terputus ditentukan oleh kebijakan ha-promote-on-shutdown. Anda dapat menetapkan salah satu dari dua nilai:

  • always= transisi ke mirror yang tidak disinkronkan diaktifkan
  • when-synced= transisi ke mirror tersinkronisasi saja, jika tidak, antrian menjadi tidak dapat dibaca dan ditulis. Antrian kembali berfungsi segera setelah broker kembali

Dengan satu atau lain cara, dengan antrian yang besar Anda harus memilih antara kehilangan data dan tidak tersedianya.

Ketika Ketersediaan Meningkatkan Keamanan Data

Ada satu komplikasi lagi yang perlu dipertimbangkan sebelum mengambil keputusan. Meskipun sinkronisasi otomatis lebih baik untuk redundansi, bagaimana pengaruhnya terhadap keamanan data? Tentu saja, dengan redundansi yang lebih baik, RabbitMQ cenderung tidak kehilangan pesan yang sudah ada, namun bagaimana dengan pesan baru dari penerbit?

Di sini Anda perlu mempertimbangkan hal berikut:

  • 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 penerbit hanya dapat membuang pesan tersebut, sebenarnya meningkatkan aksesibilitas juga meningkatkan keamanan data.

Oleh karena itu, keseimbangan harus dicari, dan solusinya bergantung pada situasi spesifik.

Masalah dengan ha-promote-on-failure=saat-disinkronkan

Ide ha-promosikan-kegagalan= saat disinkronkan adalah kami mencegah peralihan ke cermin yang tidak disinkronkan dan dengan demikian menghindari kehilangan data. Antrian tetap tidak dapat dibaca atau ditulis. Sebaliknya, kami mencoba memulihkan broker yang mogok tersebut dengan data utuh sehingga dapat kembali berfungsi sebagai master tanpa kehilangan data.

Tapi (dan ini masalah besar) jika broker kehilangan datanya, maka kita punya masalah besar: antriannya hilang! Semua data hilang! Bahkan jika Anda memiliki mirror yang sebagian besar mengejar antrian utama, mirror tersebut juga akan dibuang.

Untuk menambahkan kembali node dengan nama yang sama, kita memberitahu cluster untuk melupakan node yang hilang (dengan perintah kelincimqctl forget_cluster_node) dan mulai broker baru dengan nama host yang sama. Saat cluster mengingat node yang hilang, cluster mengingat antrian lama dan mirror yang tidak disinkronkan. Ketika sebuah cluster diberitahu untuk melupakan sebuah node yatim piatu, antrian tersebut juga akan dilupakan. Sekarang kita perlu mendeklarasikannya kembali. Kami kehilangan semua data, meskipun kami memiliki mirror dengan sebagian kumpulan data. Akan lebih baik untuk beralih ke cermin yang tidak disinkronkan!

Oleh karena itu, sinkronisasi manual (dan kegagalan sinkronisasi) dikombinasikan dengan ha-promote-on-failure=when-synced, menurut saya, cukup berisiko. Dokumen mengatakan opsi ini ada untuk keamanan data, tapi ini adalah pisau bermata dua.

Kuasai penyeimbangan kembali

Seperti yang dijanjikan, kita kembali ke masalah akumulasi semua master pada satu atau beberapa node. Hal ini bahkan dapat terjadi sebagai akibat dari pembaruan klaster yang bergulir. Dalam cluster tiga node, semua antrian master akan terakumulasi pada satu atau dua node.

Menyeimbangkan kembali master dapat menjadi masalah karena dua alasan:

  • Tidak ada alat yang baik untuk melakukan penyeimbangan kembali
  • Sinkronisasi antrian

Ada pihak ketiga yang melakukan penyeimbangan kembali plugin, yang tidak didukung secara resmi. Mengenai plugin pihak ketiga di manual RabbitMQ dikatakan: β€œPlugin ini menyediakan beberapa konfigurasi tambahan dan alat pelaporan, tetapi tidak didukung atau diverifikasi oleh tim RabbitMQ. Gunakan dengan risiko Anda sendiri."

Ada trik lain untuk memindahkan antrian utama melalui kebijakan HA. Manual menyebutkan naskah untuk ini. Cara kerjanya seperti ini:

  • Menghapus semua mirror menggunakan kebijakan sementara yang memiliki prioritas lebih tinggi daripada kebijakan HA yang ada.
  • Mengubah kebijakan sementara HA untuk menggunakan mode node, menentukan node ke mana antrian master harus ditransfer.
  • Menyinkronkan antrian untuk migrasi push.
  • Setelah migrasi selesai, hapus kebijakan sementara. Kebijakan HA awal berlaku dan jumlah mirror yang diperlukan dibuat.

Kelemahannya adalah pendekatan ini mungkin tidak berhasil jika Anda memiliki antrian yang besar atau persyaratan redundansi yang ketat.

Sekarang mari kita lihat bagaimana cluster RabbitMQ bekerja dengan partisi jaringan.

Hilangnya konektivitas

Node-node dari sistem terdistribusi dihubungkan oleh tautan jaringan, dan tautan jaringan dapat dan akan terputus. Frekuensi pemadaman bergantung pada infrastruktur lokal atau keandalan cloud yang dipilih. Bagaimanapun, sistem terdistribusi harus mampu mengatasinya. Sekali lagi kita mempunyai pilihan antara ketersediaan dan konsistensi, dan sekali lagi kabar baiknya adalah RabbitMQ menyediakan kedua opsi tersebut (hanya saja tidak pada saat yang bersamaan).

Dengan RabbitMQ kami memiliki dua opsi utama:

  • Izinkan pembagian logis (split-brain). Hal ini menjamin ketersediaan, namun dapat menyebabkan hilangnya data.
  • Nonaktifkan pemisahan logis. Dapat mengakibatkan hilangnya ketersediaan jangka pendek tergantung pada bagaimana klien terhubung ke klaster. Dapat juga menyebabkan tidak tersedianya cluster dua node.

Tapi apakah pemisahan logis itu? Ini terjadi ketika sebuah cluster terbagi menjadi dua karena hilangnya koneksi jaringan. Di setiap sisi, mirror dipromosikan menjadi master, sehingga pada akhirnya terdapat beberapa master per antrian.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 17. Antrian utama dan dua mirror, masing-masing pada node terpisah. Kemudian terjadi kegagalan jaringan dan satu mirror terlepas. Node yang terpisah melihat bahwa dua node lainnya telah jatuh dan mempromosikan cerminnya ke master. Kami sekarang memiliki dua antrian utama, keduanya dapat ditulis dan dibaca.

Jika penerbit mengirimkan data ke kedua master, kami akan mendapatkan dua salinan antrean yang berbeda.

Mode RabbitMQ yang berbeda memberikan ketersediaan atau konsistensi.

Mode abaikan (default)

Mode ini memastikan aksesibilitas. Setelah hilangnya konektivitas, terjadi pemisahan logis. Setelah konektivitas dipulihkan, administrator harus memutuskan partisi mana yang akan diprioritaskan. Sisi yang kalah akan dimulai ulang dan semua data yang terakumulasi di sisi tersebut akan hilang.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 18. Tiga penerbit berhubungan dengan tiga broker. Secara internal, cluster merutekan semua permintaan ke antrian utama di Broker 2.

Sekarang kita kehilangan Broker 3. Dia melihat broker lain telah jatuh dan mempromosikan cerminnya kepada master. Ini adalah bagaimana pemisahan logis terjadi.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 19. Pembagian logis (split-otak). Catatan masuk ke dalam dua antrian utama, dan kedua salinannya berbeda.

Konektivitas dipulihkan, namun pemisahan logis tetap ada. Administrator harus memilih pihak yang kalah secara manual. Dalam kasus di bawah ini, administrator me-reboot Broker 3. Semua pesan yang tidak berhasil dia kirimkan akan hilang.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 20. Administrator menonaktifkan Broker 3.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 21. Administrator memulai Broker 3 dan bergabung dengan cluster, kehilangan semua pesan yang tertinggal di sana.

Selama hilangnya konektivitas dan setelah pemulihannya, cluster dan antrean ini tersedia untuk membaca dan menulis.

Mode penyembuhan otomatis

Cara kerjanya mirip dengan mode Abaikan, hanya saja cluster itu sendiri secara otomatis memilih pihak yang kalah setelah memisahkan dan memulihkan konektivitas. Sisi yang kalah kembali ke cluster dalam keadaan kosong, dan antrian kehilangan semua pesan yang dikirim hanya ke sisi tersebut.

Jeda Mode Minoritas

Jika kita tidak ingin mengizinkan partisi logis, maka satu-satunya pilihan kita adalah membuang operasi baca dan tulis pada sisi yang lebih kecil setelah partisi cluster. Ketika broker melihat bahwa ia berada di sisi yang lebih kecil, ia menghentikan pekerjaan, yaitu menutup semua koneksi yang ada dan menolak koneksi baru. Sekali per detik, ia memeriksa pemulihan konektivitas. Setelah konektivitas pulih, ia melanjutkan operasi dan bergabung dengan cluster.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 22. Tiga penerbit berhubungan dengan tiga broker. Secara internal, cluster merutekan semua permintaan ke antrian utama di Broker 2.

Broker 1 dan 2 kemudian berpisah dari Broker 3. Alih-alih mempromosikan mirror mereka ke master, Broker 3 ditangguhkan dan menjadi tidak tersedia.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 23. Broker 3 menjeda, memutus semua klien, dan menolak permintaan koneksi.

Setelah konektivitas pulih, ia kembali ke cluster.

Mari kita lihat contoh lain dimana antrian utama ada di Broker 3.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 24. Antrian utama pada Broker 3.

Kemudian hilangnya konektivitas yang sama terjadi. Broker 3 berhenti sejenak karena berada di sisi yang lebih kecil. Di sisi lain, node melihat bahwa Broker 3 telah jatuh, sehingga mirror lama dari Broker 1 dan 2 dipromosikan menjadi master.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 25. Transisi ke Broker 2 apabila Broker 3 tidak tersedia.

Ketika konektivitas pulih, Broker 3 akan bergabung dengan cluster.

RabbitMQ vs Kafka: Toleransi Kesalahan dan Ketersediaan Tinggi di Cluster
Beras. 26. Cluster telah kembali beroperasi normal.

Hal yang penting untuk dipahami di sini adalah kita mendapatkan konsistensi, namun kita juga bisa mendapatkan ketersediaan, jika Kami akan berhasil mentransfer klien ke sebagian besar bagian. Untuk sebagian besar situasi, saya pribadi akan memilih mode Jeda Minoritas, tetapi itu sangat bergantung pada kasus individu.

Untuk memastikan ketersediaan, penting untuk memastikan bahwa klien berhasil terhubung ke host. Mari kita lihat pilihan kita.

Memastikan Konektivitas Pelanggan

Kami memiliki beberapa opsi tentang cara mengarahkan klien ke bagian utama cluster atau ke node yang berfungsi (setelah satu node gagal) setelah kehilangan konektivitas. Pertama, ingatlah bahwa antrean tertentu dihosting di node tertentu, namun perutean dan kebijakan direplikasi di semua node. Klien dapat terhubung ke node mana pun, dan perutean internal akan mengarahkan mereka ke tempat yang mereka tuju. Namun ketika sebuah node ditangguhkan, ia menolak koneksi, sehingga klien harus terhubung ke node lain. Jika simpulnya jatuh, dia tidak bisa berbuat apa-apa.

Pilihan kami:

  • Kluster diakses menggunakan penyeimbang beban yang hanya menggilir node dan klien mencoba menghubungkan kembali hingga berhasil. Jika sebuah node sedang down atau ditangguhkan, maka upaya untuk menyambung ke node tersebut akan gagal, namun upaya selanjutnya akan dialihkan ke server lain (dengan cara round-robin). Ini cocok untuk kehilangan konektivitas jangka pendek atau server yang down yang akan segera dihidupkan kembali.
  • Akses klaster melalui penyeimbang beban dan hapus node yang ditangguhkan/gagal dari daftar segera setelah terdeteksi. Jika kami melakukan ini dengan cepat, dan jika klien dapat mencoba kembali koneksi, maka kami akan mencapai ketersediaan yang konstan.
  • Berikan setiap klien daftar semua node, dan klien secara acak memilih salah satunya saat menghubungkan. Jika menerima kesalahan saat mencoba menyambung, ia akan berpindah ke node berikutnya dalam daftar hingga tersambung.
  • Hapus lalu lintas dari node yang gagal/ditangguhkan menggunakan DNS. Ini dilakukan dengan menggunakan TTL kecil.

Temuan

Pengelompokan RabbitMQ memiliki kelebihan dan kekurangan. Kerugian yang paling serius adalah:

  • saat bergabung dengan sebuah cluster, node membuang datanya;
  • memblokir sinkronisasi menyebabkan antrian menjadi tidak tersedia.

Semua keputusan sulit berasal dari dua fitur arsitektur ini. Jika RabbitMQ dapat menyimpan data saat cluster bergabung kembali, maka sinkronisasi akan lebih cepat. Jika mampu melakukan sinkronisasi non-pemblokiran, akan lebih baik mendukung antrian besar. Memperbaiki kedua masalah ini akan sangat meningkatkan kinerja RabbitMQ sebagai teknologi perpesanan yang toleran terhadap kesalahan dan ketersediaan tinggi. Saya ragu untuk merekomendasikan RabbitMQ dengan pengelompokan dalam situasi berikut:

  • Jaringan tidak dapat diandalkan.
  • Penyimpanan tidak dapat diandalkan.
  • Antrian yang sangat panjang.

Terkait pengaturan ketersediaan tinggi, pertimbangkan hal berikut:

  • ha-promote-on-failure=always
  • ha-sync-mode=manual
  • cluster_partition_handling=ignore (Atau autoheal)
  • pesan yang persisten
  • memastikan klien terhubung ke node aktif ketika beberapa node gagal

Untuk konsistensi (keamanan data), perhatikan pengaturan berikut:

  • Konfirmasi Penerbit dan Ucapan Terima Kasih Manual di sisi konsumen
  • ha-promote-on-failure=when-synced, jika penerbit dapat mencoba lagi nanti dan jika Anda memiliki penyimpanan yang sangat andal! Jika tidak, masukkan =always.
  • ha-sync-mode=automatic (tetapi untuk antrean besar yang tidak aktif, mode manual mungkin diperlukan; pertimbangkan juga apakah ketidaktersediaan akan menyebabkan pesan hilang)
  • Jeda mode Minoritas
  • pesan yang persisten

Kami belum membahas semua masalah toleransi kesalahan dan ketersediaan tinggi; misalnya, cara menjalankan prosedur administratif dengan aman (seperti pembaruan berkelanjutan). Kita juga perlu membicarakan tentang federasi dan plugin Shovel.

Jika saya melewatkan hal lain, beri tahu saya.

Lihat juga milikku pos, di mana saya melakukan kekacauan pada cluster RabbitMQ menggunakan Docker dan Blockade untuk menguji beberapa skenario kehilangan pesan yang dijelaskan dalam artikel ini.

Artikel sebelumnya dalam seri:
Nomor 1 - habr.com/ru/company/itsumma/blog/416629
Nomor 2 - habr.com/ru/company/itsumma/blog/418389
Nomor 3 - habr.com/ru/company/itsumma/blog/437446

Sumber: www.habr.com

Tambah komentar