RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība

В pēdējais raksts мы рассмотрели кластеризацию RabbitMQ для обеспечения отказоустойчивости и высокой доступности. Теперь глубоко покопаемся в Apache Kafka.

Šeit replikācijas vienība ir nodalījums. Katrai tēmai ir viena vai vairākas sadaļas. Katrai sadaļai ir vadītājs ar vai bez sekotājiem. Veidojot tēmu, jūs norādāt nodalījumu skaitu un replikācijas koeficientu. Parastā vērtība ir 3, kas nozīmē trīs kopijas: viens līderis un divi sekotāji.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 1. Četras sadaļas ir sadalītas starp trim brokeriem

Visi lasīšanas un rakstīšanas pieprasījumi nonāk vadītājam. Sekotāji periodiski nosūta vadītājam pieprasījumus saņemt jaunākās ziņas. Patērētāji nekad nevēršas pie sekotājiem; pēdējie pastāv tikai atlaišanas un kļūdu tolerances dēļ.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība

Sadalījuma kļūme

Kad brokeris neizdodas, nereti neizdodas izgāzties vairāku sadaļu vadītāji. Katrā no tiem par līderi kļūst sekotājs no cita mezgla. Faktiski tas ne vienmēr notiek, jo sinhronizācijas faktors arī ietekmē: vai ir sinhronizēti sekotāji, un, ja nē, tad vai ir atļauta pāreja uz nesinhronizētu repliku. Bet pagaidām nesarežģīsim lietas.

Brokeris 3 atstāj tīklu, un 2. sadaļā tiek ievēlēts jauns vadītājs.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 2. Brokeris 3 nomirst, un viņa sekotājs brokerim 2 tiek ievēlēts par jauno 2. nodalījuma vadītāju.

Tad brokeris 1 aiziet un arī 1. sadaļa zaudē savu līderi, kura loma pāriet 2. brokerim.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 3. Palicis viens brokeris. Visi vadītāji ir pie viena brokera ar nulles atlaišanu

Kad brokeris 1 atgriežas tiešsaistē, tas pievieno četrus sekotājus, nodrošinot zināmu atlaišanu katram nodalījumam. Bet visi līderi joprojām palika uz 2. brokera.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Рис. 4. Лидеры остаются на брокере 2

Kad parādās brokeris 3, mēs atgriežamies pie trim replikām katrā nodalījumā. Bet visi līderi joprojām ir brokeris 2.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 5. Nesabalansēts līderu izvietojums pēc brokeru 1. un 3. atjaunošanas

Kafkai ir rīks labākai līderu līdzsvara atjaunošanai nekā RabbitMQ. Tur bija jāizmanto trešās puses spraudnis vai skripts, kas mainīja galvenā mezgla migrēšanas politikas, samazinot dublēšanu migrācijas laikā. Turklāt lielām rindām mums bija jāpieņem nepieejamība sinhronizācijas laikā.

У Kafka есть концепция «предпочтительных реплик» на роль лидера. Когда создаются разделы топика, Kafka пытается равномерно распределить лидеров по узлам и отмечает этих первых лидеров как предпочтительных. Со временем из-за перезагрузки серверов, сбоев и нарушения связности лидеры могут оказаться на других узлах, как в вышеописанном крайнем случае.

Lai to labotu, Kafka piedāvā divas iespējas:

  • Opcija auto.leader.rebalance.enable=true ļauj kontrollera mezglam automātiski atkārtoti piešķirt līderus atpakaļ vēlamajām replikām un tādējādi atjaunot vienotu sadalījumu.
  • Administrators var palaist skriptu kafka-preferred-replica-election.sh manuālai pārcelšanai.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 6. Replikas pēc balansēšanas

Это была упрощенная версия сбоя, но реальность более сложна, хотя ничего слишком сложного здесь нет. Все сводится к синхронизированным репликам (In-Sync Replicas, ISR).

Sinhronizētās kopijas (ISR)

ISR — это набор реплик раздела, который считается «синхронизированным» (in-sync). Тут есть лидер, а фолловеров может не быть. Фолловер считается синхронизированным, если он сделал точные копии всех сообщений лидера до истечения интервала replica.lag.time.max.ms.

Sekotājs tiek noņemts no ISR kopas, ja:

  • neiesniedza pieprasījumu atlasīt intervālu replica.lag.time.max.ms (считается мертвым)
  • intervālā neizdevās atjaunināt replica.lag.time.max.ms (tiek uzskatīts par lēnu)

Sekotāji veic izlases pieprasījumus intervālā replica.fetch.wait.max.ms, kas pēc noklusējuma ir 500 ms.

Чтобы четко объяснить цель ISR, нужно посмотреть на подтверждения от производителя (producer) и некоторые сценарии отказа. Производители могут выбрать, когда брокер отправляет подтверждение:

  • acks=0, apstiprinājums nav nosūtīts
  • acks=1, подтверждение отправляется после того, как лидер записал сообщение в свой локальный лог
  • acks=all, подтверждение отправляется после того, как все реплики в ISR записали сообщение в локальные логи

Pēc Kafkas terminoloģijas, ja ISR ir saglabājis ziņojumu, tas ir “apņēmies”. Acks=all ir drošākā iespēja, taču tā arī pievieno papildu aizkavi. Apskatīsim divus neveiksmju piemērus un to, kā dažādas “ack” iespējas mijiedarbojas ar ISR koncepciju.

Acks=1 un ISR

Šajā piemērā mēs redzēsim, ka, ja vadītājs negaida, līdz tiks saglabāts katrs ziņojums no visiem sekotājiem, tad ir iespējams datu zudums, ja vadītājs neizdodas. Pārvietošanos uz nesinhronizētu sekotāju var iespējot vai atspējot, iestatot netīrs.vadītājs.vēlēšanas.iespējot.

Šajā piemērā ražotāja vērtība ir acks=1. Sadaļa ir sadalīta starp visiem trim brokeriem. Broker 3 ir aiz muguras, tas sinhronizējās ar līderi pirms astoņām sekundēm un tagad atpaliek par 7456 ziņojumiem. Brokeris 1 atpalika tikai par sekundi. Mūsu producents nosūta ziņu un ātri saņem atbildi, bez lēniem vai mirušiem sekotājiem, kurus līderis negaida.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 7. ISR ar trim replikām

Broker 2 neizdodas, un ražotājs saņem savienojuma kļūdu. Pēc tam, kad vadība tiek nodota brokerim 1, mēs zaudējam 123 ziņojumus. 1. brokera sekotājs bija daļa no ISR, bet nebija pilnībā sinhronizēts ar līderi, kad tas kritās.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 8. Ziņojumi tiek zaudēti, kad tas avarē

Konfigurācijā bootstrap.servers у производителя перечислено несколько брокеров, и он может спросить другого брокера, кто стал новым лидером раздела. Затем он устанавливает соединение с брокером 1 и продолжает отправлять сообщения.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 9. Ziņojumu sūtīšana tiek atsākta pēc neliela pārtraukuma

Брокер 3 отстает еще больше. Он делает запросы на выборку, но не может синхронизироваться. Это может быть связано с медленным сетевым соединением между брокерами, проблемой хранения и т. д. Он удаляется из ISR. Теперь ISR состоит из одной реплики — лидера! Производитель продолжает отправлять сообщения и получать подтверждения.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 10. Brokera 3 sekotājs tiek noņemts no ISR

Брокер 1 падает, и роль лидера переходит к брокеру 3 с потерей 15286 сообщений! Производитель получает сообщение об ошибке подключения. Переход к лидеру за пределами ISR был возможен только из-за настройки unclean.leader.election.enable=true. Если она установлена в nepatiess, tad pāreja nenotiktu un visi lasīšanas un rakstīšanas pieprasījumi tiktu noraidīti. Šajā gadījumā mēs gaidām, kamēr brokeris 1 atgriezīsies ar neskartiem datiem replikā, kas atkal pārņems vadību.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 11. Brokeris 1 krīt. Ja rodas kļūme, tiek zaudēts liels skaits ziņojumu

Producents nodibina saikni ar pēdējo brokeri un redz, ka tagad ir sadaļas vadītājs. Viņš sāk sūtīt ziņojumus brokerim 3.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Рис. 12. После краткого перерыва сообщения снова отправляются в раздел 0

Mēs redzējām, ka, neskaitot īsus pārtraukumus, lai izveidotu jaunus savienojumus un meklētu jaunu vadītāju, ražotājs nepārtraukti sūtīja ziņojumus. Šī konfigurācija nodrošina pieejamību uz konsekvences (datu drošības) rēķina. Kafka pazaudēja tūkstošiem ziņojumu, bet turpināja pieņemt jaunus rakstus.

Acks=all un ISR

Atkārtosim šo scenāriju vēlreiz, bet ar acks=viss. Broker 3 vidējais latentums ir četras sekundes. Ražotājs nosūta ziņojumu ar acks=viss, un tagad nesaņem ātru atbildi. Vadītājs gaida, līdz ziņojums tiks saglabāts visās ISR replikās.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 13. ISR ar trim replikām. Viens ir lēns, kā rezultātā ierakstīšana aizkavējas

Pēc četru sekunžu papildu kavēšanās brokeris 2 nosūta apstiprinājumu. Visas kopijas tagad ir pilnībā atjauninātas.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 14. Visas kopijas saglabā ziņas un nosūta apstiprinājumu

Brokeris 3 tagad atpaliek un tiek noņemts no ISR. Latentums ir ievērojami samazināts, jo ISR nav palicis lēnas kopijas. Brokeris 2 tagad gaida tikai brokeri 1, un viņam ir vidējā nobīde 500 ms.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 15. Brokera 3 kopija tiek noņemta no ISR

Pēc tam 2. brokeris krīt un vadība pāriet 1. brokerim, nezaudējot ziņojumus.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 16. Brokeris 2 krīt

Ražotājs atrod jaunu vadītāju un sāk viņam sūtīt ziņojumus. Latentums ir vēl vairāk samazināts, jo ISR tagad sastāv no vienas kopijas! Tāpēc iespēja acks=viss nepievieno atlaišanu.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 17. Broker 1 replika uzņemas vadību, nezaudējot ziņojumus

Pēc tam brokeris 1 avarē, un pārsvars nonāk brokerim 3, zaudējot 14238 ziņojumus!

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Рис. 18. Брокер 1 умирает, а переход лидерства с настройкой unclean приводит к обширной потере данных

Mēs nevarējām instalēt opciju netīrs.vadītājs.vēlēšanas.iespējot nozīmē patiess. Pēc noklusējuma tas ir vienāds nepatiess. Iestatījumi acks=viss с unclean.leader.election.enable=true nodrošina pieejamību ar papildu datu drošību. Bet, kā redzat, mēs joprojām varam zaudēt ziņojumus.

Bet ko darīt, ja mēs vēlamies palielināt datu drošību? Var likt unclean.leader.election.enable = false, taču tas mūs ne vienmēr pasargās no datu zuduma. Ja vadītājs smagi nokrita un paņēma datus līdzi, tad ziņojumi joprojām tiek zaudēti, kā arī tiek zaudēta pieejamība, līdz administrators atjauno situāciju.

Labāk ir nodrošināt, lai visi ziņojumi būtu lieki, un citādi atmest ierakstu. Tad, vismaz no brokera viedokļa, datu zudums ir iespējams tikai divu vai vairāku vienlaicīgu kļūmju gadījumā.

Acks=all, min.insync.replicas un ISR

Ar tēmas konfigurāciju min.insync.replicas Mēs paaugstinām datu drošības līmeni. Vēlreiz iziesim cauri iepriekšējā scenārija pēdējai daļai, bet šoreiz ar min.insync.replicas=2.

Tātad 2. brokerim ir replikas līderis, un 3. brokera sekotājs tiek noņemts no ISR.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 19. ISR no divām replikām

Brokeris 2 krīt, un vadība pāriet brokerim 1, nezaudējot ziņojumus. Bet tagad ISR sastāv tikai no vienas kopijas. Tas neatbilst minimālajam ierakstu saņemšanas skaitam, un tāpēc brokeris uz rakstīšanas mēģinājumu reaģē ar kļūdu NotEnoughReplicas.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 20. ISR skaits ir par vienu mazāks, nekā norādīts failā min.insync.replicas

Šī konfigurācija upurē pieejamību konsekvences dēļ. Pirms ziņojuma apstiprināšanas mēs nodrošinām, ka tas ir ierakstīts vismaz divās replikās. Tas dod ražotājam daudz lielāku pārliecību. Šeit ziņojuma zudums ir iespējams tikai tad, ja divas replikas vienlaikus neizdodas īsā intervālā, līdz ziņojums tiek replicēts papildu sekotājam, kas ir maz ticams. Bet, ja esat ļoti paranoisks, varat iestatīt replikācijas koeficientu uz 5 un min.insync.replicas ar 3. Šeit trīs brokeriem ir jākrīt vienlaikus, lai zaudētu rekordu! Protams, jūs maksājat par šo uzticamību papildu latentumā.

Kad pieejamība ir nepieciešama datu drošībai

Kā iekšā случае с RabbitMQ, dažkārt pieejamība ir nepieciešama datu drošībai. Lūk, par ko jums jāpadomā:

  • Vai izdevējs var vienkārši atgriezt kļūdu un likt augšējam pakalpojumam vai lietotājam vēlāk mēģināt vēlreiz?
  • Vai izdevējs var saglabāt ziņojumu lokāli vai datu bāzē, lai vēlāk mēģinātu vēlreiz?

Ja atbilde ir nē, pieejamības optimizēšana uzlabo datu drošību. Jūs zaudēsiet mazāk datu, ja izvēlēsieties pieejamību, nevis neierakstīsit. Tādējādi viss ir līdzsvara atrašana, un lēmums ir atkarīgs no konkrētās situācijas.

Смысл ISR

ISR komplekts ļauj izvēlēties optimālo līdzsvaru starp datu drošību un latentumu. Piemēram, nodrošiniet pieejamību lielākās daļas kopiju atteices gadījumā, samazinot mirušo vai lēno kopiju ietekmi latentuma ziņā.

Мы сами выбираем значение replica.lag.time.max.ms atbilstoši jūsu vajadzībām. Būtībā šis parametrs nozīmē, cik lielu kavēšanos mēs esam gatavi pieņemt, kad acks=viss. Noklusējuma vērtība ir desmit sekundes. Ja tas jums ir pārāk garš, varat to samazināt. Tad ISR izmaiņu biežums palielināsies, jo sekotāji tiks noņemti un pievienoti biežāk.

RabbitMQ ir vienkārši spoguļu komplekts, kas ir jāatkārto. Lēni spoguļi ievieš papildu latentumu, un mirušie spoguļi var gaidīt, līdz paketes, kas pārbauda katra mezgla pieejamību (tīkla atzīme), atbild. ISR ir interesants veids, kā izvairīties no šīm latentuma problēmām. Bet mēs riskējam zaudēt atlaišanu, jo ISR var sarukt tikai līdz līderim. Lai izvairītos no šī riska, izmantojiet iestatījumu min.insync.replicas.

Klienta savienojuma garantija

Iestatījumos bootstrap.servers ražotājs un patērētājs var norādīt vairākus brokerus klientu savienošanai. Ideja ir tāda, ka, kad viens mezgls pazūd, paliek vairāki rezerves, ar kurām klients var atvērt savienojumu. Tie nav obligāti sekciju līderi, bet vienkārši tramplīns sākotnējai iekraušanai. Klients var jautāt, kurš mezgls mitina lasīšanas/rakstīšanas nodalījuma vadītāju.

Programmā RabbitMQ klienti var izveidot savienojumu ar jebkuru mezglu, un iekšējā maršrutēšana nosūta pieprasījumu uz vietu, kur tam jānonāk. Tas nozīmē, ka RabbitMQ priekšā varat uzstādīt slodzes balansētāju. Kafka pieprasa klientiem izveidot savienojumu ar mezglu, kurā atrodas atbilstošais nodalījuma vadītājs. Šādā situācijā jūs nevarat instalēt slodzes balansētāju. Saraksts bootstrap.servers Ir ļoti svarīgi, lai klienti pēc kļūmes varētu piekļūt un atrast pareizos mezglus.

Kafkas konsensa arhitektūra

Līdz šim neesam apsvēruši, kā klasteris uzzina par brokera krišanu un kā tiek ievēlēts jauns vadītājs. Lai saprastu, kā Kafka darbojas ar tīkla nodalījumiem, vispirms ir jāsaprot vienprātības arhitektūra.

Каждый кластер Kafka развертывается вместе с кластером Zookeeper — это служба распределенного консенсуса, которая позволяет системе достичь консенсуса у некоторого заданного состояния с приоритетом согласованности над доступностью. Для одобрения операций чтения и записи требуется согласие большинства узлов Zookeeper.

Zookeeper saglabā klastera stāvokli:

  • Список топиков, разделов, конфигурацию, текущие реплики лидера, предпочтительные реплики.
  • Klastera dalībnieki. Katrs brokeris pings Zookeeper klasterim. Ja noteiktā laika periodā tas nesaņem ping, Zookeeper reģistrē brokeri kā nepieejamu.
  • Kontroliera galveno un rezerves mezglu izvēle.

Узел контроллера — один из брокеров Kafka, который отвечает за избрание лидеров реплик. Zookeeper отправляет контроллеру уведомления о членстве в кластере и изменениях топика, и контроллер должен действовать в соответствии с этими изменениями.

Piemēram, ņemsim jaunu tēmu ar desmit nodalījumiem un replikācijas koeficientu 3. Kontrolierim ir jāievēl vadītājs katram nodalījumam, cenšoties optimāli sadalīt līderus starp brokeriem.

Katram sekcijas kontrollerim:

  • atjaunina informāciju Zookeeper par ISR un vadītāju;
  • Nosūta LeaderAndISRCommand katram brokerim, kas mitina šī nodalījuma kopiju, informējot brokerus par ISR un vadītāju.

Kad brokeris ar vadītāju krīt, Zookeeper nosūta paziņojumu kontrolierim, un tas ievēl jaunu vadītāju. Atkal kontrolieris vispirms atjaunina Zookeeper un pēc tam nosūta komandu katram brokerim, informējot par vadības maiņu.

Katrs vadītājs ir atbildīgs par ISR pieņemšanu darbā. Iestatījumi replica.lag.time.max.ms nosaka, kas tur ienāks. Kad ISR mainās, vadītājs nosūta jaunu informāciju Zookeeper.

Zookeeper vienmēr tiek informēts par jebkurām izmaiņām, lai neveiksmes gadījumā vadība vienmērīgi pārietu uz jaunu vadītāju.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 21. Kafkas konsenss

Replikācijas protokols

Izpratne par replikācijas detaļām palīdz labāk izprast iespējamos datu zuduma scenārijus.

Izlases vaicājumi, žurnāla beigu nobīde (LEO) un Highwater Mark (HW)

Mēs uzskatījām, ka sekotāji periodiski nosūta vadītājam pieprasījumus nolasīt. Noklusējuma intervāls ir 500 ms. Tas atšķiras no RabbitMQ ar to, ka RabbitMQ replikāciju ierosina nevis rindas spogulis, bet gan galvenais. Meistars piespiež izmaiņas uz spoguļiem.

Vadītājs un visi sekotāji saglabā žurnāla beigu nobīdi (LEO) un Highwater (HW) etiķeti. LEO atzīme saglabā pēdējā ziņojuma nobīdi vietējā replikā, un HW saglabā pēdējās saistības nobīdi. Atcerieties, ka, lai nodrošinātu izpildes statusu, ziņojumam ir jābūt saglabātam visās ISR replikās. Tas nozīmē, ka LEO parasti ir nedaudz priekšā HW.

Kad vadītājs saņem ziņojumu, tas to saglabā lokāli. Sekotājs veic ienešanas pieprasījumu, nosūtot savu LEO. Pēc tam vadītājs nosūta ziņojumu sēriju, sākot no šī LEO, kā arī pārsūta pašreizējo HW. Kad vadītājs saņem informāciju, ka visas replikas ir saglabājušas ziņojumu norādītajā nobīdē, tas pārvieto HW atzīmi. Tikai vadītājs var pārvietot HW, un tāpēc visi sekotāji atbildēs uz viņu pieprasījumu zinās pašreizējo vērtību. Tas nozīmē, ka sekotāji var atpalikt no līdera gan vēstījumā, gan HW zināšanās. Patērētāji saņem ziņas tikai līdz pašreizējam HW.

Обратите внимание, что «сохраненный» (persisted) означает записанный в память, а не на диск. Для производительности, Kafka выполняет синхронизацию на диск с определенным интервалом. У RabbitMQ тоже есть такой интервал, но он отправит подтверждение паблишеру только после того, как мастер и все зеркала записали сообщение на диск. Разработчики Kafka по соображениям производительности приняли решение отправлять ack, как только сообщение записано в память. Kafka делает ставку на то, что избыточность компенсирует риск краткосрочного хранения подтвержденных сообщений только в памяти.

Līdera neveiksme

Kad līderis krīt, Zookeeper par to informē kontrolieri, un tas izvēlas jaunu līdera kopiju. Jaunais vadītājs nosaka jaunu HW atzīmi saskaņā ar savu LEO. Pēc tam sekotāji saņem informāciju par jauno vadītāju. Atkarībā no Kafkas versijas sekotājs izvēlēsies vienu no diviem scenārijiem:

  1. Tas saīsinās vietējo žurnālu uz zināmu HW un nosūtīs jaunajam vadītājam pieprasījumu pēc ziņojumiem pēc šīs atzīmes.
  2. Отправит лидеру запрос, чтобы узнать HW на момент его избрания лидером, а затем усечет лог до этого смещения. Затем начнет делать периодические запросы на выборку, начиная с этого смещения.

Sekotājam, iespējams, būs jāsaīsina žurnāls šādu iemeslu dēļ:

  • Ja līderim neizdodas, pirmais sekotājs ISR komplektā, kas reģistrēts Zookeeper, uzvar vēlēšanās un kļūst par līderi. Lai gan visi ISR ​​sekotāji tiek uzskatīti par “sinhronizētiem”, iespējams, nav saņēmuši visu ziņojumu kopijas no bijušā vadītāja. Pilnīgi iespējams, ka piedāvātajam sekotājam nav visjaunākās kopijas. Kafka nodrošina, ka starp replikām nav atšķirību. Tādējādi, lai izvairītos no neatbilstībām, katram sekotājam ir jāsaīsina savs žurnāls līdz jaunā līdera HW vērtībai viņa ievēlēšanas brīdī. Tas ir vēl viens iemesls, kāpēc iestatīt acks=viss tik svarīgi konsekvencei.
  • Ziņojumi periodiski tiek ierakstīti diskā. Ja visi klastera mezgli neizdodas vienlaikus, diskos tiks saglabātas kopijas ar dažādām nobīdēm. Iespējams, ka tad, kad brokeri atgriezīsies tiešsaistē, jaunais ievēlētais līderis būs aiz saviem sekotājiem, jo ​​viņš tika saglabāts diskā pirms citiem.

Воссоединение c кластером

Atkārtoti pievienojoties klasterim, kopijas rīkojas tāpat kā tad, ja līderim neizdodas: tās pārbauda līdera kopiju un saīsina savu žurnālu uz tā HW (ievēlēšanas laikā). Salīdzinājumam, RabbitMQ atkārtoti apvienotos mezglus uzskata par pilnīgi jauniem. Abos gadījumos brokeris atmet jebkuru esošo stāvokli. Ja tiek izmantota automātiskā sinhronizācija, kapteinim ir jāreplicē pilnīgi viss pašreizējais saturs jaunajā spogulī, izmantojot metodi “ļaujiet visai pasaulei gaidīt”. Šīs darbības laikā kapteinis nepieņem nekādas lasīšanas vai rakstīšanas darbības. Šī pieeja rada problēmas lielās rindās.

Kafka ir izplatīts žurnāls, un kopumā tajā tiek saglabāts vairāk ziņojumu nekā RabbitMQ rindā, kurā dati tiek noņemti no rindas pēc to nolasīšanas. Aktīvajām rindām jāpaliek salīdzinoši mazām. Bet Kafka ir žurnāls ar savu saglabāšanas politiku, kas var noteikt dienu vai nedēļu periodu. Rindas bloķēšanas un pilnīgas sinhronizācijas pieeja izplatītam žurnālam ir absolūti nepieņemama. Tā vietā Kafkas sekotāji vienkārši saīsina savu žurnālu līdz vadītāja HW (viņa ievēlēšanas laikā), ja viņu kopija ir priekšā vadītājam. Visticamākajā gadījumā, kad sekotājs atpaliek, tas vienkārši sāk veikt ienešanas pieprasījumus, sākot ar pašreizējo LEO.

Jauni vai atkārtoti pievienotie sekotāji sāk darboties ārpus ISR un nepiedalās saistībās. Viņi vienkārši strādā kopā ar grupu, saņemot ziņas, cik ātri vien iespējams, līdz panāk vadītāju un ieiet ISR. Nav bloķēšanas un nav jāizmet visi jūsu dati.

Savienojuma zudums

Kafka ir vairāk komponentu nekā RabbitMQ, tāpēc tai ir sarežģītāks darbību kopums, kad klasteris tiek atvienots. Taču Kafka sākotnēji bija paredzēta klasteriem, tāpēc risinājumi ir ļoti pārdomāti.

Tālāk ir norādīti vairāki savienojuma kļūmju scenāriji.

  • 1. scenārijs: sekotājs neredz vadītāju, bet joprojām redz Zoodārza sargu.
  • 2. scenārijs: līderis neredz nevienu sekotāju, bet joprojām redz Zookeeper.
  • 3. scenārijs: sekotājs redz vadītāju, bet neredz zoodārza sargu.
  • 4. scenārijs: vadītājs redz sekotājus, bet neredz Zoodārza sargu.
  • 5. scenārijs: sekotājs ir pilnībā nošķirts gan no citiem Kafka mezgliem, gan no Zookeeper.
  • 6. scenārijs: vadītājs ir pilnībā nošķirts no abiem Kafkas mezgliem un Zookeeper.
  • 7. scenārijs: Kafka kontrollera mezgls nevar redzēt citu Kafka mezglu.
  • 8. scenārijs: Kafka kontrolieris neredz Zookeeper.

Katram scenārijam ir sava uzvedība.

1. scenārijs: sekotājs neredz vadītāju, bet joprojām redz Zookeeper

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 22. 1. scenārijs: trīs kopiju ISR

Savienojuma kļūme atdala brokeri 3 no starpniekiem 1 un 2, bet ne no Zookeeper. Brokeris 3 vairs nevar nosūtīt izgūšanas pieprasījumus. Pēc tam, kad pagājis laiks replica.lag.time.max.ms tas tiek noņemts no ISR un nepiedalās ziņojumu apņemšanā. Kad savienojums ir atjaunots, tas atsāks pieprasījumu ienesšanu un pievienosies ISR, kad tas sasniegs līderi. Zookeeper turpinās saņemt ping un pieņems, ka brokeris ir dzīvs un vesels.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 23. 1. scenārijs: starpnieks tiek noņemts no ISR, ja intervālā replica.lag.time.max.ms no tā netiek saņemts neviens izgūšanas pieprasījums.

Nav dalītu smadzeņu vai mezglu apturēšanas, piemēram, RabbitMQ. Tā vietā tiek samazināta atlaišana.

Сценарий 2. Лидер не видит ни одного фолловера, но все еще видит Zookeeper

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 24. Scenārijs 2. Vadītājs un divi sekotāji

Нарушение сетевой связности отделяет лидера от фолловеров, но брокер все еще видит Zookeeper. Как и в первом сценарии, ISR сжимается, но на этот раз только до лидера, поскольку все фолловеры перестают отправлять запросы на выборку. Опять же, нет никакого логического разделения. Вместо этого происходит потеря избыточности для новых сообщений, пока связность не восстановится. Zookeeper продолжает получать пинги и считает, что брокер жив и здоров.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 25. Scenārijs 2. ISR ir sarucis tikai līdz līderim

Scenārijs 3. Sekotājs redz vadītāju, bet neredz Zoodārza sargu

Sekotājs ir atdalīts no Zookeeper, bet ne no brokera ar līderi. Rezultātā sekotājs turpina iesniegt pieprasījumus un būt ISR dalībnieks. Zookeeper vairs nesaņem pingus un reģistrē brokera avāriju, bet tā kā tas ir tikai sekotājs, tad pēc atveseļošanās nekādu seku nav.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 26. 3. scenārijs: sekotājs turpina sūtīt ieneses pieprasījumus vadītājam

Scenārijs 4. Vadītājs redz sekotājus, bet neredz Zookeeper

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 27. Scenārijs 4. Vadītājs un divi sekotāji

Līderis ir atdalīts no Zookeeper, bet ne no brokeriem ar sekotājiem.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 28. 4. scenārijs: vadītājs izolēts no Zookeeper

Pēc kāda laika Zookeeper reģistrēs brokera kļūdu un paziņos par to kontrolierim. Viņš no saviem sekotājiem izvēlēsies jaunu līderi. Tomēr sākotnējais vadītājs turpinās domāt, ka tas ir vadītājs, un turpinās pieņemt ierakstus no acks=1. Sekotāji viņam vairs nesūta atnešanas pieprasījumus, tāpēc viņš uzskatīs tos par mirušiem un mēģinās samazināt ISR. Bet, tā kā tam nav savienojuma ar Zookeeper, tas nevarēs to izdarīt un tajā brīdī atsakās pieņemt citus ierakstus.

Сообщения acks=viss nesaņems apstiprinājumu, jo ISR vispirms ieslēdz visas kopijas un ziņojumi tos nesasniedz. Kad sākotnējais vadītājs mēģinās tos noņemt no ISR, tas to nevarēs izdarīt un vispār pārtrauks pieņemt ziņojumus.

Klienti drīz pamana līdera izmaiņas un sāk sūtīt ierakstus uz jauno serveri. Kad tīkls ir atjaunots, sākotnējais vadītājs redz, ka tas vairs nav līderis, un saīsina savu žurnālu līdz HW vērtībai, kas jaunajam vadītājam bija neveiksmes brīdī, lai izvairītos no žurnāla novirzēm. Pēc tam tas sāks sūtīt ielādes pieprasījumus jaunajam vadītājam. Tiek zaudēti visi sākotnējā līdera ieraksti, kas nav replicēti jaunajam līderim. Tas nozīmē, ka tiks zaudēti ziņojumi, kurus sākotnējais vadītājs neatzina tajās dažās sekundēs, kad strādāja divi vadītāji.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 29. 4. scenārijs. 1. brokera līderis kļūst par sekotāju pēc tīkla atjaunošanas

5. scenārijs: sekotājs ir pilnībā nošķirts gan no citiem Kafka mezgliem, gan no Zookeeper

Sekotājs ir pilnībā izolēts gan no citiem Kafkas mezgliem, gan no Zookeeper. Viņš vienkārši noņem sevi no ISR, līdz tīkls tiek atjaunots, un pēc tam panāk pārējos.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 30. 5. scenārijs: no ISR tiek noņemts izolēts sekotājs

6. scenārijs: vadītājs ir pilnībā nošķirts no abiem Kafkas mezgliem un Zookeeper

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 31. Scenārijs 6. Vadītājs un divi sekotāji

Vadītājs ir pilnībā izolēts no saviem sekotājiem, kontroliera un zoodārza uzrauga. Īsu laiku tas turpinās pieņemt ierakstus no acks=1.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 32. 6. scenārijs: līdera izolēšana no citiem Kafka un Zookeeper mezgliem

Nav saņemti pieprasījumi pēc derīguma termiņa beigām replica.lag.time.max.ms, tas mēģinās samazināt ISR uz sevi, bet nevarēs to izdarīt, jo nav saziņas ar Zookeeper, tad tas pārtrauks pieņemt rakstus.

Tikmēr Zookeeper atzīmēs izolēto brokeri kā mirušu un kontrolieris ievēlēs jaunu vadītāju.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Рис. 33. Сценарий 6. Два лидера

Sākotnējais vadītājs var pieņemt ierakstus dažas sekundes, bet pēc tam pārstāj pieņemt jebkādus ziņojumus. Klienti tiek atjaunināti ik pēc 60 sekundēm ar jaunākajiem metadatiem. Viņi tiks informēti par vadītāja maiņu un sāks sūtīt ierakstus jaunajam vadītājam.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 34. 6. scenārijs: ražotāji pāriet uz jaunu līderi

Visi apstiprinātie ieraksti, ko sākotnējais vadītājs veicis kopš savienojuma zaudēšanas, tiks zaudēti. Kad tīkls ir atjaunots, sākotnējais vadītājs ar Zookeeper starpniecību atklās, ka tas vairs nav vadītājs. Pēc tam tas saīsinās savu žurnālu uz jaunā vadītāja HW ievēlēšanas laikā un sāks sūtīt pieprasījumus kā sekotājs.

RabbitMQ vs Kafka: kļūdu tolerance un augsta pieejamība
Rīsi. 35. 6. scenārijs: sākotnējais līderis kļūst par sekotāju pēc tīkla savienojuma atjaunošanas

Šādā situācijā loģiska atdalīšana var notikt uz īsu laiku, bet tikai tad, ja acks=1 и min.insync.replicas arī 1. Loģiskā atdalīšana automātiski beidzas vai nu pēc tīkla atjaunošanas, kad sākotnējais vadītājs saprot, ka viņš vairs nav vadītājs, vai arī tad, kad visi klienti saprot, ka vadītājs ir mainījies un sāk rakstīt jaunajam vadītājam – atkarībā no tā, kas notiek pirmais. Jebkurā gadījumā daži ziņojumi tiks zaudēti, bet tikai ar acks=1.

Ir vēl viens šī scenārija variants, kad tieši pirms tīkla sadalīšanas sekotāji atpalika un līderis saspieda ISR tikai sev. Pēc tam tas kļūst izolēts savienojuma zuduma dēļ. Tiek ievēlēts jauns vadītājs, bet sākotnējais vadītājs turpina pieņemt ierakstus, pat acks=viss, jo ISR nav neviena cita, izņemot viņu. Šie ieraksti tiks zaudēti, tiklīdz tīkls tiks atjaunots. Vienīgais veids, kā izvairīties no šīs iespējas, ir min.insync.replicas = 2.

7. scenārijs: Kafka kontrollera mezgls nevar redzēt citu Kafka mezglu

Parasti, kad savienojums ar Kafka mezglu tiek zaudēts, kontrolieris nevarēs pārsūtīt tam informāciju par līderu izmaiņām. Sliktākajā gadījumā tas novedīs pie īslaicīgas loģiskas atdalīšanas, kā tas ir 6. scenārijā. Biežāk brokeris vienkārši nekļūs par kandidātu līdera amatam, ja pēdējais neizdosies.

Сценарий 8. Контроллер Kafka не видит Zookeeper

Zookeeper nesaņems ping no kritušā kontroliera un kā kontrolieri izvēlēsies jaunu Kafka mezglu. Sākotnējais kontrolieris var turpināt sevi parādīt kā tādu, taču tas nesaņem paziņojumus no Zookeeper, tāpēc tam nebūs jāveic nekādi uzdevumi. Kad tīkls būs atjaunots, viņš sapratīs, ka vairs nav kontrolieris, bet kļuvis par parastu Kafkas mezglu.

Secinājumi no scenārijiem

Mēs redzam, ka sekotāju savienojuma zudums neizraisa ziņojumu zudumu, bet vienkārši īslaicīgi samazina dublēšanu, līdz tīkls tiek atjaunots. Tas, protams, var izraisīt datu zudumu, ja tiek zaudēts viens vai vairāki mezgli.

Ja vadītājs tiek atdalīts no Zookeeper savienojuma zuduma dēļ, var tikt zaudēti ziņojumi acks=1. Saziņas trūkums ar Zookeeper izraisa īsu loģisku šķelšanos ar abiem vadītājiem. Šo problēmu atrisina parametrs acks=viss.

Parametrs min.insync.replicas divās vai vairākās replikās nodrošina papildu pārliecību, ka šādi īstermiņa scenāriji neizraisīs ziņojumu nozaudēšanu, kā tas ir 6. scenārijā.

Резюме по потере сообщений

Uzskaitīsim visus veidus, kā varat zaudēt datus programmā Kafka:

  • Любой сбой лидера, если сообщения подтверждались с помощью acks=1
  • Jebkura netīra vadības pāreja, tas ir, uz sekotāju ārpus ISR, pat ar acks=viss
  • Изоляция лидера от Zookeeper, если сообщения подтверждались с помощью acks=1
  • Pilnīga līdera izolācija, kurš jau ir samazinājis ISR grupu līdz pašam sev. Visi ziņojumi tiks zaudēti, pat acks=viss. Это верно только в том случае, если min.insync.replicas=1.
  • Visu nodalījumu mezglu vienlaicīgas atteices. Tā kā ziņojumi tiek apstiprināti no atmiņas, daži, iespējams, vēl nav ierakstīti diskā. Pēc serveru pārstartēšanas dažu ziņojumu var nebūt.

No netīrām vadības pārejām var izvairīties, tos aizliedzot vai nodrošinot vismaz divas atlaišanas. Visizturīgākā konfigurācija ir kombinācija acks=viss и min.insync.replicas virs 1.

Прямое сравнение надёжности RabbitMQ и Kafka

Для обеспечения надёжности и высокой доступности обе платформы реализуют систему первичной и вторичной репликации. Однако у RabbitMQ есть ахиллесова пята. При воссоединении после сбоя узлы отбрасывают свои данные, а синхронизация блокируется. Этот двойной удар ставит под вопрос долговечность больших очередей в RabbitMQ. Вам придётся смириться либо с сокращением избыточности, либо с длительными блокировками. Снижение избыточности увеличивает риск массовой потери данных. Но если очереди небольшие, то ради обеспечения избыточности с краткими периодами недоступности (несколько секунд) можно справиться с помощью повторных попыток подключения.

Kafkam šīs problēmas nav. Tas izmet datus tikai no līdera un sekotāja atšķirības punkta. Visi koplietotie dati tiek saglabāti. Turklāt replikācija nebloķē sistēmu. Vadītājs turpina pieņemt amatus, kamēr jaunais sekotājs panāk, tāpēc devops gadījumā pievienošanās klasterim vai atkārtota pievienošanās klasterim kļūst par nenozīmīgu uzdevumu. Protams, joprojām pastāv problēmas, piemēram, tīkla joslas platums replikācijas laikā. Ja vienlaikus pievienosit vairākus sekotājus, var rasties joslas platuma ierobežojums.

RabbitMQ ir pārāks par Kafka uzticamības ziņā, ja vairāki serveri klasterī vienlaikus neizdodas. Kā jau teicām, RabbitMQ nosūta apstiprinājumu izdevējam tikai pēc tam, kad galvenais un visi spoguļi ir ierakstījuši ziņojumu diskā. Bet tas palielina latentumu divu iemeslu dēļ:

  • fsync ik pēc dažiem simtiem milisekundēm
  • Spoguļa kļūmi var pamanīt tikai pēc tam, kad ir beidzies to pakešu kalpošanas laiks, kas pārbauda katra mezgla pieejamību (neto ķeksītis). Ja spogulis palēninās vai nokrīt, tas palielina kavēšanos.

Kafkas likme ir tāda, ka, ja ziņojums tiek saglabāts vairākos mezglos, tas var apstiprināt ziņojumus, tiklīdz tie nonāk atmiņā. Šī iemesla dēļ pastāv risks pazaudēt jebkāda veida ziņojumus (pat acks=viss, min.insync.реплики=2) vienlaicīgas atteices gadījumā.

В целом Kafka демонстрирует более высокую производительность по и изначально спроектирована для кластеров. Количество фолловеров можно увеличить до 11-ти, если это нужно для надёжности. Коэффициент репликации 5 и минимальное число реплик в синхронизированном состоянии min.insync.replicas=3 padarīs ziņojumu zaudēšanu par ļoti retu notikumu. Ja jūsu infrastruktūra var atbalstīt šo replikācijas attiecību un dublēšanas līmeni, varat izvēlēties šo opciju.

RabbitMQ klasterizācija ir piemērota nelielām rindām. Bet pat nelielas rindas var ātri augt, ja ir intensīva satiksme. Kad rindas kļūs lielas, jums būs jāizdara grūta izvēle starp pieejamību un uzticamību. RabbitMQ klasterizācija ir vislabāk piemērota netipiskām situācijām, kad RabbitMQ elastības priekšrocības atsver visus klasterizācijas trūkumus.

Viens pretlīdzeklis RabbitMQ ievainojamībai pret lielām rindām ir to sadalīšana daudzās mazākās rindās. Ja neprasa pilnu visas rindas pasūtīšanu, bet tikai attiecīgos ziņojumus (piemēram, ziņas no konkrēta klienta), vai arī nepasūtat vispār neko, tad ir pieņemama šāda iespēja: paskaties uz manu projektu Līdzsvarotājs для разбиения очереди (проект пока на ранней стадии).

Visbeidzot, neaizmirstiet par vairākām kļūdām gan RabbitMQ, gan Kafka klasterizācijas un replikācijas mehānismos. Laika gaitā sistēmas ir kļuvušas nobriedušākas un stabilākas, taču neviens ziņojums nekad nebūs 100% pasargāts no zuduma! Turklāt datu centros notiek liela mēroga avārijas!

Ja esmu kaut ko palaidis garām, kļūdījies vai jūs nepiekrītat kādam no punktiem, droši rakstiet komentāru vai sazinieties ar mani.

Man bieži jautā: “Ko izvēlēties, Kafka vai RabbitMQ?”, “Kura platforma ir labāka?”. Patiesība ir tāda, ka tas tiešām ir atkarīgs no jūsu situācijas, pašreizējās pieredzes utt. Es vilcinos sniegt savu viedokli, jo būtu pārāk daudz vienkāršot ieteikt vienu platformu visiem lietošanas gadījumiem un iespējamiem ierobežojumiem. Es rakstīju šo rakstu sēriju, lai jūs varētu izveidot savu viedokli.

Es gribu teikt, ka abas sistēmas ir līderes šajā jomā. Es varu būt nedaudz neobjektīvs, jo no savas pieredzes ar projektiem es mēdzu novērtēt tādas lietas kā garantēta ziņojumu secība un uzticamība.

Es redzu citas tehnoloģijas, kurām trūkst šīs uzticamības un garantētas pasūtīšanas, tad skatos uz RabbitMQ un Kafka un saprotu abu šo sistēmu neticamo vērtību.

Avots: www.habr.com

Pievieno komentāru