RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás

В utolsó cikk a RabbitMQ klaszterezést vizsgáltuk a hibatűrés és a magas rendelkezésre állás érdekében. Most pedig ássunk bele az Apache Kafkába.

Itt a replikáció egysége a partíció. Minden témának egy vagy több szakasza van. Minden szekciónak van egy vezetője követőkkel vagy anélkül. Témakör létrehozásakor meg kell adni a partíciók számát és a replikációs együtthatót. A szokásos érték 3, ami három replikát jelent: egy vezetőt és két követőt.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 1. Négy szekció három bróker között van elosztva

Minden olvasási és írási kérés a vezetőhöz kerül. A követők időszakonként kéréseket küldenek a vezetőnek, hogy megkapják a legfrissebb üzeneteket. A fogyasztók soha nem fordulnak követőkhöz, ez utóbbiak csak a redundancia és a hibatűrés miatt léteznek.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás

Partíció hiba

Amikor egy bróker megbukik, gyakran több részleg vezetői is kudarcot vallanak. Mindegyikben egy másik csomópont követője lesz a vezető. Valójában ez nem mindig van így, hiszen a szinkronizálási tényező is befolyásolja: vannak-e szinkronizált követők, és ha nincs, akkor megengedett-e a váltás egy nem szinkronizált replikára. De egyelőre ne bonyolítsuk a dolgokat.

A 3. bróker elhagyja a hálózatot, és a 2. brókernél új vezetőt választanak a 2. szekcióba.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 2. A 3. bróker meghal, és követőjét a 2. brókernél megválasztják a 2. partíció új vezetőjének

Ekkor 1. bróker távozik, és az 1. szekció is elveszíti vezetőjét, akinek a szerepe átszáll a 2. brókerre.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 3. Egy bróker maradt. Minden vezető egyetlen brókernél dolgozik, nulla redundanciával

Amikor a bróker 1 újra online lesz, négy követőt ad hozzá, némi redundanciát biztosítva minden partíciónak. De az összes vezető továbbra is a 2. brókernél maradt.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 4. A vezetők a 2. brókernél maradnak

Amikor megjelenik a 3. broker, visszatérünk partíciónként három replikához. De az összes vezető továbbra is a 2. brókeren van.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 5. A vezetők kiegyensúlyozatlan elhelyezése az 1. és 3. brókerek visszaállítása után

A Kafka rendelkezik a RabbitMQ-nál jobb vezető-egyensúlyozási eszközzel. Ott egy harmadik féltől származó beépülő modult vagy szkriptet kellett használnia, amely megváltoztatta a főcsomópont áttelepítésének házirendjeit azáltal, hogy csökkentette a redundanciát az áttelepítés során. Ezenkívül nagy sorok esetén el kellett fogadnunk az elérhetetlenséget a szinkronizálás során.

Kafka az „előnyben részesített replikák” koncepcióját használja a vezető szerephez. A témapartíciók létrehozásakor a Kafka megpróbálja egyenletesen elosztani a vezetőket a csomópontok között, és ezeket az első vezetőket preferáltként jelöli meg. Idővel a szerver újraindítása, meghibásodása és a kapcsolat meghibásodása miatt a vezetők más csomópontokra kerülhetnek, mint a fent leírt szélsőséges esetben.

A probléma megoldására Kafka két lehetőséget kínál:

  • választási lehetőség auto.leader.rebalance.enable=true lehetővé teszi a vezérlő csomópont számára, hogy automatikusan visszarendelje a vezetőket a preferált replikákhoz, és ezáltal visszaállítsa az egységes elosztást.
  • A rendszergazda futtathatja a szkriptet kafka-preferred-replica-election.sh kézi átcsoportosításhoz.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 6. Replikák újraegyensúlyozás után

Ez a kudarc leegyszerűsített változata volt, de a valóság ennél összetettebb, bár itt semmi sem túl bonyolult. Mindez a szinkronizált replikákon múlik (In-Sync Replicas, ISR).

Szinkronizált replikák (ISR)

Az ISR egy partíció replikáinak halmaza, amely „szinkronizáltnak” (in-Sync) minősül. Van vezető, de lehet, hogy nincsenek követői. Egy követőt akkor tekintünk szinkronizáltnak, ha pontos másolatot készített a vezető összes üzenetéről az intervallum lejárta előtt replika.lag.time.max.ms.

Egy követő eltávolításra kerül az ISR-készletből, ha:

  • nem kért az intervallum kiválasztására replika.lag.time.max.ms (feltehetően halott)
  • nem sikerült frissíteni az intervallum alatt replika.lag.time.max.ms (lassúnak tekinthető)

A követők mintavételi kérelmet adnak az intervallumban replika.fetch.wait.max.ms, amely alapértelmezés szerint 500 ms.

Az ISR céljának világos magyarázatához meg kell vizsgálnunk a gyártó megerősítéseit és néhány meghibásodási forgatókönyvet. A gyártók választhatják, hogy a bróker mikor küldjön visszaigazolást:

  • acks=0, a megerősítés nem kerül elküldésre
  • acks=1, megerősítést küld, miután a vezető üzenetet írt a helyi naplójába
  • acks=all, megerősítést küld, miután az ISR összes replikája beírta az üzenetet a helyi naplókba

Kafka terminológiája szerint, ha az ISR elmentett egy üzenetet, az „elkötelezett”. Az Acks=all a legbiztonságosabb lehetőség, de további késleltetést is ad. Nézzünk meg két példát a kudarcokra, és azt, hogy a különböző „acks” opciók hogyan hatnak egymásra az ISR koncepcióval.

Acks=1 és ISR

Ebben a példában látni fogjuk, hogy ha a vezető nem várja meg az összes követő minden üzenetének mentését, akkor adatvesztés lehetséges, ha a vezető meghibásodik. A nem szinkronizált követőhöz való navigálás beállítással engedélyezhető vagy letiltható unclean.leader.election.enable.

Ebben a példában a gyártó értéke acks=1. A szekció mindhárom bróker között megoszlik. A Broker 3 lemaradt, nyolc másodperce szinkronizált a vezetővel, és most 7456 üzenettel van lemaradva. Az 1. bróker mindössze egy másodperccel maradt el. Producerünk üzenetet küld, és gyorsan visszajelzést kap, a lassú vagy halott követők ráfordítása nélkül, akikre a vezető nem vár.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 7. ISR három replikával

A Broker 2 meghibásodik, és a gyártó kapcsolódási hibát kap. Miután a vezetés átkerült az 1. brókerhez, 123 üzenetet veszítünk el. Az 1. bróker követője az ISR része volt, de nem volt teljesen szinkronban a vezetővel, amikor az esett.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 8. Az üzenetek elvesznek, ha összeomlik

Konfigurációban bootstrap.servers A gyártó több brókert is felsorolt, és megkérdezhet egy másik brókert, aki az új szekcióvezető. Ezután kapcsolatot létesít az 1. közvetítővel, és folytatja az üzenetek küldését.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 9. Az üzenetek küldése rövid szünet után folytatódik

A Broker 3 még hátrébb van. Lekérést ad, de nem tud szinkronizálni. Ennek oka lehet a brókerek közötti lassú hálózati kapcsolat, a tárolási probléma stb. Eltávolítják az ISR-ből. Most az ISR egyetlen másolatból áll - a vezetőből! A gyártó továbbra is küld üzeneteket és fogad visszaigazolásokat.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 10. A 3. bróker követője eltávolítva az ISR-ből

Az 1. bróker megszűnik, a vezető szerep pedig a 3. brókerhez kerül 15286 üzenet elvesztésével! A gyártó csatlakozási hibaüzenetet kap. Az ISR-en kívüli vezetővé való átmenet csak a beállítás miatt volt lehetséges unclean.leader.election.enable=true. Ha be van szerelve hamis, akkor az átállás nem történik meg, és minden olvasási és írási kérés elutasításra kerül. Ebben az esetben megvárjuk, amíg az 1. közvetítő visszatér sértetlen adataival a replikában, amely ismét átveszi a vezetést.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 11. Bróker 1 elesik. Hiba esetén nagyszámú üzenet elveszik

A producer kapcsolatot létesít az utolsó brókerrel, és látja, hogy most ő a szekció vezetője. Elkezd üzeneteket küldeni a 3-as brókernek.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 12. Rövid szünet után az üzenetek ismét a 0-s szekcióba kerülnek

Láttuk, hogy az új kapcsolatok kialakítása és az új vezető keresése miatti rövid megszakítások mellett a gyártó folyamatosan üzent. Ez a konfiguráció a konzisztencia (adatbiztonság) rovására biztosítja a rendelkezésre állást. Kafka üzenetek ezreit veszítette el, de továbbra is fogadott új írásokat.

Acks=all és ISR

Ismételjük meg ezt a forgatókönyvet, de azzal acks=all. A Broker 3 átlagos késleltetése négy másodperc. A gyártó üzenetet küld a acks=all, és most nem kap gyors választ. A vezető arra vár, hogy az üzenetet az ISR összes replikája elmentse.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 13. ISR három replikával. Az egyik lassú, ami felvételi késést eredményez

Négy másodperc további késleltetés után a 2. bróker nyugtázást küld. Az összes replika teljesen frissült.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 14. Minden replika elmenti az üzeneteket és visszaigazolást küld

A Broker 3 most még jobban lemaradt, és eltávolították az ISR-ből. A késleltetés jelentősen csökken, mivel nem maradnak lassú replikák az ISR-ben. A 2. bróker most csak az 1. brókerre vár, és átlagosan 500 ms késéssel rendelkezik.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 15. A 3. bróker replikáját eltávolítják az ISR-ből

Ezután a 2. közvetítő elesik, és a vezetés üzenetvesztés nélkül átszáll az 1. közvetítőre.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 16. Bróker 2 elesik

A gyártó új vezetőt talál, és üzeneteket küld neki. A késleltetés tovább csökken, mert az ISR most egyetlen replikából áll! Ezért a lehetőség acks=all nem növeli a redundanciát.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 17. Az 1. közvetítő replikája átveszi a vezetést üzenetek elvesztése nélkül

Ezután az 1. bróker összeomlik, és a vezetés a 3. brókerhez kerül 14238 üzenet veszteséggel!

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 18. A Broker 1 elhal és a vezetői átállás tisztátalan beállítással jelentős adatvesztést eredményez

Nem tudtuk telepíteni az opciót unclean.leader.election.enable jelentésbe igaz. Alapértelmezés szerint egyenlő hamis. Beállítások acks=all с unclean.leader.election.enable=true hozzáférést biztosít némi fokozott adatbiztonsággal. De amint látja, még mindig elveszíthetjük az üzeneteket.

De mi van akkor, ha növelni akarjuk az adatbiztonságot? Teheted unclean.leader.election.enable = false, de ez nem feltétlenül véd meg minket az adatvesztéstől. Ha a vezető nagyot bukott és magával vitte az adatokat, akkor az üzenetek továbbra is elvesznek, plusz a rendelkezésre állás mindaddig, amíg az adminisztrátor vissza nem állítja a helyzetet.

Jobb, ha gondoskodik arról, hogy minden üzenet redundáns legyen, egyébként pedig dobja el a felvételt. Ekkor legalábbis a bróker szempontjából adatvesztés csak két vagy több egyidejű meghibásodás esetén lehetséges.

Acks=all, min.insync.replicas és ISR

Témakonfigurációval min.insync.replicas Növeljük az adatbiztonság szintjét. Nézzük meg újra az előző forgatókönyv utolsó részét, de ezúttal ezzel min.insync.replicas=2.

Tehát a 2. közvetítőnek van egy replika vezetője, és a 3. közvetítő követője eltávolítva az ISR-ből.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 19. ISR két másolatból

A 2. bróker elesik, és a vezetés üzenetvesztés nélkül száll át az 1. brókerre. De most az ISR csak egy másolatból áll. Ez nem éri el a rekordok fogadásához szükséges minimális számot, ezért a közvetítő hibával válaszol az írási kísérletre NotEnoughReplicas.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 20. Az ISR-ek száma eggyel alacsonyabb a min.insync.replicas fájlban megadottnál

Ez a konfiguráció feláldozza a rendelkezésre állást a konzisztencia érdekében. Az üzenet nyugtázása előtt gondoskodunk arról, hogy az legalább két replikára legyen írva. Ez sokkal nagyobb önbizalmat ad a gyártónak. Itt az üzenetvesztés csak akkor lehetséges, ha két replika egyidejűleg meghiúsul rövid időn belül, amíg az üzenetet egy további követőre replikálják, ami nem valószínű. De ha szuper paranoiás vagy, beállíthatod a replikációs tényezőt 5-re és min.insync.replicas 3. Itt három brókernek kell egyszerre buknia, hogy elveszítse a rekordot! Természetesen ezért a megbízhatóságért további késleltetésben kell fizetnie.

Amikor az adatbiztonság érdekében a hozzáférhetőség szükséges

Mint a tok RabbitMQ-val, időnként a hozzáférhetőség szükséges az adatbiztonság érdekében. A következőkre kell gondolnia:

  • A kiadó egyszerűen hibaüzenetet küldhet, és az upstream szolgáltatás vagy a felhasználó megpróbálhatja újra később?
  • Mentheti-e a kiadó az üzenetet helyileg vagy adatbázisba, hogy később újra próbálkozzon?

Ha a válasz nem, akkor az elérhetőség optimalizálása javítja az adatbiztonságot. Kevesebb adatot veszít, ha a rögzítés leállítása helyett a rendelkezésre állást választja. Így minden az egyensúly megtalálásán múlik, és a döntés az adott helyzettől függ.

Az ISR jelentése

Az ISR programcsomag lehetővé teszi az adatbiztonság és a késleltetés közötti optimális egyensúly kiválasztását. Például biztosítsa a rendelkezésre állást a replikák többségének meghibásodása esetén, minimalizálva az elhalt vagy lassú replikák hatását a várakozási idő tekintetében.

A jelentést mi magunk választjuk ki replika.lag.time.max.ms az Ön igényei szerint. Lényegében ez a paraméter azt jelenti, hogy mennyi késleltetést vagyunk hajlandók elfogadni, mikor acks=all. Az alapértelmezett érték tíz másodperc. Ha ez túl hosszú számodra, csökkentheted. Ekkor az ISR változásainak gyakorisága megnő, mivel a követőket gyakrabban eltávolítják és hozzáadják.

A RabbitMQ egyszerűen tükrök halmaza, amelyet le kell replikálni. A lassú tükrök további késleltetést eredményeznek, és a halott tükrök megvárhatják, amíg az egyes csomópontok elérhetőségét ellenőrző csomagok (net tick) válaszolnak. Az ISR érdekes módja a késleltetési problémák elkerülésének. De kockáztatjuk a redundancia elvesztését, mivel az ISR csak a vezetővé zsugorodik. A kockázat elkerülése érdekében használja a beállítást min.insync.replicas.

Ügyfélkapcsolati garancia

Beállítások bootstrap.servers A gyártó és a fogyasztó több közvetítőt is megadhat az ügyfelek összekapcsolásához. Az ötlet az, hogy amikor egy csomópont leáll, több tartalék marad, amellyel a kliens kapcsolatot tud nyitni. Ezek nem feltétlenül szakaszvezetők, hanem egyszerűen ugródeszka a kezdeti terheléshez. Az ügyfél megkérdezheti, hogy melyik csomópont tárolja az olvasási/írási partícióvezetőt.

A RabbitMQ-ban az ügyfelek bármely csomóponthoz kapcsolódhatnak, és a belső útválasztás elküldi a kérést oda, ahová kell. Ez azt jelenti, hogy telepíthet egy terheléselosztót a RabbitMQ elé. A Kafka megköveteli az ügyfelektől, hogy csatlakozzanak ahhoz a csomóponthoz, amely a megfelelő partícióvezetőt tárolja. Ilyen helyzetben nem telepíthet terheléselosztót. Lista bootstrap.servers Nagyon fontos, hogy az ügyfelek elérjék és megtalálhassák a megfelelő csomópontokat egy hiba után.

Kafka konszenzusos építészet

Eddig nem foglalkoztunk azzal, hogy a klaszter honnan szerez tudomást a bróker bukásáról és az új vezető megválasztásáról. Ahhoz, hogy megértse, hogyan működik a Kafka a hálózati partíciókkal, először meg kell értenie a konszenzusos architektúrát.

Minden Kafka-fürt egy Zookeeper-fürttel együtt kerül telepítésre, amely egy elosztott konszenzusszolgáltatás, amely lehetővé teszi a rendszer számára, hogy konszenzusra jusson egy adott állapotról, prioritást adva a konszenzusnak a rendelkezésre állás helyett. Az olvasási és írási műveletek jóváhagyásához a Zookeeper csomópontok többségének beleegyezése szükséges.

A Zookeeper tárolja a klaszter állapotát:

  • Témák listája, szakaszok, konfiguráció, aktuális vezető replikák, preferált replikák.
  • Klaszter tagjai. Minden közvetítő pingeli a Zookeeper klasztert. Ha nem kap ping-et meghatározott időn belül, akkor a Zookeeper nem elérhetőként rögzíti a közvetítőt.
  • A vezérlő fő és tartalék csomópontjainak kiválasztása.

A vezérlő csomópont az egyik Kafka-bróker, amely felelős a replika vezetők megválasztásáért. A Zookeeper értesítést küld a vezérlőnek a fürttagságról és a témakörök változásairól, és a vezérlőnek intézkednie kell ezekkel a változásokkal.

Vegyünk például egy új témát tíz partícióval és 3-as replikációs tényezővel. A vezérlőnek minden partícióhoz meg kell választania egy vezetőt, hogy a vezetőket optimálisan eloszthassa a brókerek között.

Minden szakaszvezérlőhöz:

  • frissíti a Zookeeper-ben található információkat az ISR-ről és a vezetőről;
  • LeaderAndISRCommandot küld minden brókernek, amely a partíció másolatát tárolja, tájékoztatva a brókereket az ISR-ről és a vezetőről.

Ha egy vezetővel rendelkező bróker elesik, a Zookeeper értesítést küld a kontrollernek, és az új vezetőt választ. Ismét a vezérlő először frissíti a Zookeepert, majd parancsot küld minden brókernek, értesítve őket a vezetőváltásról.

Minden vezető felelős az ISR-ek toborzásáért. Beállítások replika.lag.time.max.ms meghatározza, hogy ki lép be oda. Amikor az ISR megváltozik, a vezető új információkat továbbít a Zookeepernek.

A Zookeeper mindig értesül az esetleges változásokról, hogy hiba esetén a vezetőség zökkenőmentesen új vezetőt kapjon.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 21. Kafka konszenzus

Replikációs protokoll

A replikáció részleteinek megértése segít jobban megérteni a lehetséges adatvesztési forgatókönyveket.

Mintavételi lekérdezések, Log End Offset (LEO) és Highwater Mark (HW)

Úgy gondoltuk, hogy a követők rendszeresen küldenek lekérési kérelmet a vezetőnek. Az alapértelmezett intervallum 500 ms. Ez abban különbözik a RabbitMQ-tól, hogy a RabbitMQ-ban a replikációt nem a sortükör, hanem a mester kezdeményezi. A mester váltókat tol a tükrökhöz.

A vezető és az összes követő elmenti a Log End Offset (LEO) és a Highwater (HW) címkét. A LEO jelzés az utolsó üzenet eltolását tárolja a helyi replikában, a HW pedig az utolsó véglegesítés eltolását. Ne feledje, hogy a véglegesítés állapotához az üzenetnek meg kell maradnia az összes ISR-replikán. Ez azt jelenti, hogy a LEO általában kissé megelőzi a HW-t.

Amikor a vezető üzenetet kap, azt helyben tárolja. A követő lekérést küld a LEO-jának továbbításával. A vezető ezután egy köteg üzenetet küld ettől a LEO-tól kezdve, és továbbítja az aktuális HW-t is. Amikor a vezető információt kap arról, hogy az összes replika eltárolta az üzenetet az adott eltoláson, elmozdítja a HW jelölést. Csak a vezető mozgathatja a HW-t, így minden követő tudni fogja az aktuális értéket a kérésére adott válaszokban. Ez azt jelenti, hogy a követők mind üzenetben, mind HW tudásban lemaradhatnak a vezető mögött. A fogyasztók csak az aktuális HW-ig kapnak üzeneteket.

Vegye figyelembe, hogy a „persisted” azt jelenti, hogy a memóriába írták, nem a lemezre. A teljesítmény érdekében a Kafka meghatározott időközönként szinkronizálja a lemezt. A RabbitMQ-nál is van ilyen intervallum, de csak akkor küld visszaigazolást a kiadónak, ha a master és az összes tükör lemezre írta az üzenetet. A Kafka fejlesztői teljesítményi okokból úgy döntöttek, hogy azonnali visszajelzést küldenek, amint az üzenetet a memóriába írják. Kafka arra fogad, hogy a redundancia ellensúlyozza annak kockázatát, hogy a nyugtázott üzeneteket csak a memóriában tárolják rövid időre.

Vezetői kudarc

Ha egy vezér elesik, a Zookeeper értesíti a vezérlőt, és kiválaszt egy új vezérmásolatot. Az új vezető új HW-jegyet állít fel LEO-ja szerint. A követők ezután tájékoztatást kapnak az új vezetőről. A Kafka verziójától függően a követő két forgatókönyv egyikét választja:

  1. Ez csonkolja a helyi naplót egy ismert HW-re, és kérést küld az új vezetőnek a jelölés utáni üzenetekre.
  2. Kérést küld a vezetőnek, hogy derítse ki a HW-t abban az időben, amikor vezetőnek választották, majd csonkolja a naplót ehhez az eltoláshoz. Ezután rendszeres lekérési kéréseket indít el ettől az eltolástól kezdve.

Előfordulhat, hogy a követőknek le kell csonkolniuk a naplót a következő okok miatt:

  • Ha egy vezető kudarcot vall, az ISR-készlet első követője, akit a Zookeeper regisztrált, megnyeri a választást, és ő lesz a vezető. Bár az ISR összes követője „szinkronban van”, előfordulhat, hogy nem kapta meg az összes üzenet másolatát a korábbi vezetőtől. Teljesen lehetséges, hogy a kiemelt követőnek nem a legfrissebb példánya van. A Kafka gondoskodik arról, hogy ne legyen eltérés a replikák között. Így az eltérések elkerülése érdekében minden követőnek le kell csonkolnia a naplóját az új vezető megválasztásakori HW értékére. Ez egy másik ok a beállításra acks=all annyira fontos a következetesség szempontjából.
  • Az üzenetek rendszeres időközönként lemezre kerülnek. Ha az összes fürtcsomópont egyszerre meghibásodik, akkor a különböző eltolásokkal rendelkező replikák a lemezeken kerülnek tárolásra. Lehetséges, hogy amikor a brókerek visszatérnek az internetre, a megválasztott új vezető a követői mögé kerül, mert őt a többiek előtt mentették lemezre.

Újraegyesülés a klaszterrel

Amikor újra csatlakozik a fürthöz, a replikák ugyanazt teszik, mint amikor egy vezető megbukik: ellenőrzik a vezér replikáját, és lecsonkolják a naplójukat a HW-re (a megválasztáskor). Ehhez képest a RabbitMQ teljesen újként kezeli az újraegyesített csomópontokat. A bróker mindkét esetben elveti a meglévő állapotokat. Ha automatikus szinkronizálást használunk, akkor a mesternek abszolút az összes aktuális tartalmat replikálnia kell az új tükörre a „várjon az egész világ” módszerrel. A mester nem fogad el semmilyen olvasási vagy írási műveletet a művelet során. Ez a megközelítés problémákat okoz a nagy sorokban.

A Kafka egy elosztott napló, és általában több üzenetet tárol, mint a RabbitMQ várólista, ahol az adatok az olvasás után törlődnek a sorból. Az aktív soroknak viszonylag kicsinek kell maradniuk. De a Kafka egy napló saját megőrzési politikával, amely napokat vagy heteket határozhat meg. A sorblokkoló és a teljes szinkronizálási megközelítés abszolút elfogadhatatlan egy elosztott napló esetében. Ehelyett Kafka követői egyszerűen lecsonkolják a naplójukat a vezető HW-jére (a megválasztásakor), ha az ő példányuk megelőzi a vezetőt. Valószínűbb esetben, amikor a követő lemaradt, egyszerűen elkezd lekérni az aktuális LEO-val kezdve.

Az új vagy újracsatlakozott követők az ISR-en kívül kezdődnek, és nem vesznek részt a kötelezettségvállalásokban. Egyszerűen a csoport mellett dolgoznak, amilyen gyorsan csak tudnak, üzeneteket kapnak, amíg utolérik a vezetőt és belépnek az ISR-be. Nincs bezárás, és nincs szükség az összes adat kidobására.

Kapcsolat elvesztése

A Kafka több összetevőt tartalmaz, mint a RabbitMQ, így bonyolultabb viselkedési készlettel rendelkezik, amikor a fürt megszakad. De a Kafka eredetileg klaszterekhez készült, így a megoldások nagyon jól átgondoltak.

Az alábbiakban bemutatunk néhány csatlakozási hiba forgatókönyvet:

  • 1. forgatókönyv: A követő nem látja a vezetőt, de látja az állatkerti gondozót.
  • 2. forgatókönyv: A vezető nem lát követőket, de látja a Zookeepert.
  • 3. forgatókönyv: A követő látja a vezetőt, de nem látja az állatkerti gondozót.
  • 4. forgatókönyv: A vezető látja a követőket, de nem látja az állatkerti gondozót.
  • 5. forgatókönyv: A követő teljesen elkülönül a többi Kafka csomóponttól és a Zookeepertől.
  • 6. forgatókönyv: A vezető teljesen elkülönül a többi Kafka csomóponttól és a Zookeepertől.
  • 7. forgatókönyv: A Kafka vezérlő csomópont nem lát egy másik Kafka csomópontot.
  • 8. forgatókönyv: A Kafka vezérlő nem látja a Zookeepert.

Minden forgatókönyvnek megvan a maga viselkedése.

1. forgatókönyv: A követő nem látja a vezetőt, de látja a Zookeepert

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 22. 1. forgatókönyv: három replika ISR-je

A csatlakozási hiba elválasztja a 3. közvetítőt az 1. és 2. közvetítőtől, de nem választja el a Zookeepert. A Broker 3 már nem tud lekérést küldeni. Miután eltelt az idő replika.lag.time.max.ms eltávolítják az ISR-ből, és nem vesz részt az üzenet véglegesítésében. A kapcsolat helyreállítása után folytatja a kérések lekérését, és csatlakozik az ISR-hez, amikor utoléri a vezetőt. A Zookeeper továbbra is megkapja a pingeket, és feltételezi, hogy a bróker él és jól van.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 23. 1. forgatókönyv: A közvetítő eltávolításra kerül az ISR-ből, ha nem érkezik tőle lekérési kérelem a replica.lag.time.max.ms intervallumon belül

Nincs megosztott agy vagy csomópont felfüggesztés, mint a RabbitMQ-ban. Ehelyett a redundancia csökken.

2. forgatókönyv: A vezető nem lát követőket, de látja a Zookeepert

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 24. 2. forgatókönyv. Vezető és két követő

A hálózati kapcsolat meghibásodása elválasztja a vezetőt a követőktől, de a bróker továbbra is láthatja a Zookeepert. Az első forgatókönyvhöz hasonlóan az ISR csökken, de ezúttal csak a vezetőhöz, mivel az összes követő leállítja a lekérési kérések küldését. Megint nincs logikai felosztás. Ehelyett az új üzenetek redundanciája megszűnik, amíg a kapcsolat vissza nem áll. A Zookeeper továbbra is megkapja a pingeket, és úgy véli, hogy a bróker él és jól van.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 25. 2. forgatókönyv. Az ISR csak a vezetőig zsugorodott

3. forgatókönyv. A követő látja a vezetőt, de nem látja az állatkerti gondozót

A követőt elválasztják a Zookeepertől, de nem a vezetővel rendelkező brókertől. Ennek eredményeként a követő továbbra is kér lekérést, és tagja az ISR-nek. A Zookeeper már nem kap pingeket és regisztrálja a bróker összeomlását, de mivel csak egy követő, a gyógyulás után nincs következménye.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 26. 3. forgatókönyv: A követő továbbra is lekérési kéréseket küld a vezetőnek

4. forgatókönyv. A vezető lát követőket, de nem látja a Zookeepert

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 27. 4. forgatókönyv. Vezető és két követő

A vezető elkülönül a Zookeepertől, de nem a követőkkel rendelkező brókerektől.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 28. 4. forgatókönyv: A vezetőt elszigetelték a Zookeepertől

Egy idő után a Zookeeper regisztrálja a közvetítői hibát, és értesíti erről a vezérlőt. Követői közül új vezetőt választ. Az eredeti vezető azonban továbbra is úgy gondolja, hogy ő a vezető, és továbbra is elfogadja a bejegyzéseket acks=1. A követők már nem küldenek neki lekérési kéréseket, ezért halottnak tekinti őket, és megpróbálja magára zsugorítani az ISR-t. De mivel nincs kapcsolata a Zookeeperrel, ezt nem fogja tudni megtenni, és ezen a ponton megtagadja a további bejegyzések fogadását.

Сообщения acks=all nem kap nyugtát, mert az ISR először bekapcsol minden replikát, és az üzenetek nem jutnak el hozzájuk. Amikor az eredeti vezető megpróbálja eltávolítani őket az ISR-ből, nem tudja megtenni, és egyáltalán nem fogad üzeneteket.

Az ügyfelek hamarosan észreveszik a vezető változását, és elkezdik a rekordokat az új szerverre küldeni. A hálózat visszaállítása után az eredeti vezető látja, hogy az már nem vezető, és lecsonkítja a naplóját arra a HW értékre, amely az új vezetőnek volt a hiba idején, hogy elkerülje a napló eltérését. Ezután elkezdi lekérési kéréseket küldeni az új vezetőnek. Az eredeti vezetőtől származó minden olyan rekord elveszik, amely nem replikálódik az új vezetőre. Vagyis azok az üzenetek, amelyeket az eredeti vezető nem vett tudomásul abban a néhány másodpercben, amikor két vezető dolgozott, elvesznek.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 29. 4. forgatókönyv. Az 1. közvetítő vezetője a hálózat visszaállítása után követővé válik

5. forgatókönyv: A követő teljesen elkülönül a többi Kafka csomóponttól és a Zookeepertől

A követő teljesen el van szigetelve a többi Kafka csomóponttól és a Zookeepertől. Egyszerűen eltávolítja magát az ISR-ből, amíg a hálózat helyre nem áll, majd utoléri a többieket.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 30. 5. forgatókönyv: Az izolált követőt eltávolítják az ISR-ből

6. forgatókönyv: A vezető teljesen elkülönül a többi Kafka csomóponttól és a Zookeepertől

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 31. 6. forgatókönyv. Vezető és két követő

A vezető teljesen el van szigetelve követőitől, az irányítótól és az állatkerti gondozótól. Rövid ideig továbbra is fogad nevezéseket a következőről: acks=1.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 32. 6. forgatókönyv: A vezető elkülönítése más Kafka és Zookeeper csomópontoktól

Miután nem kaptak kéréseket a lejárat után replika.lag.time.max.ms, megpróbálja magára zsugorítani az ISR-t, de nem tudja megtenni, mert nincs kommunikáció a Zookeeperrel, akkor abbahagyja az írások fogadását.

Eközben a Zookeeper halottként jelöli meg az elszigetelt brókert, és az irányító új vezetőt választ.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 33. 6. forgatókönyv. Két vezető

Az eredeti vezető néhány másodpercig elfogadhat bejegyzéseket, de ezután nem fogad semmilyen üzenetet. Az ügyfelek 60 másodpercenként frissülnek a legújabb metaadatokkal. Tájékoztatást kapnak a vezetőváltásról, és megkezdik a bejegyzések küldését az új vezetőnek.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 34. 6. forgatókönyv: A gyártók új vezetőre váltanak

Az eredeti vezető által a kapcsolat megszűnése óta tett összes megerősített bejegyzés elvész. A hálózat helyreállítása után az eredeti vezető a Zookeeper-en keresztül felfedezi, hogy már nem ő a vezető. Ezután csonkolja a naplóját az új vezető HW-jére a megválasztáskor, és elkezdi a kérések küldését követőként.

RabbitMQ vs Kafka: Hibatűrés és magas rendelkezésre állás
Rizs. 35. 6. forgatókönyv: Az eredeti vezető a hálózati kapcsolat helyreállítása után követővé válik

Ebben a helyzetben a logikai elválasztás rövid ideig megtörténhet, de csak akkor, ha acks=1 и min.insync.replicas továbbá 1. A logikai szétválasztás automatikusan véget ér vagy a hálózat visszaállítása után, amikor az eredeti vezető rájön, hogy már nem ő a vezető, vagy amikor minden kliens rájön, hogy a vezető megváltozott, és elkezdenek írni az új vezetőnek – amelyik előbb történik. Mindenesetre néhány üzenet elveszik, de csak ezzel acks=1.

Ennek a forgatókönyvnek van egy másik változata is, ahol közvetlenül a hálózat felosztása előtt a követők lemaradtak, és a vezető saját magára tömörítette az ISR-t. Ezután a kapcsolat elvesztése miatt elszigetelődik. Új vezetőt választanak, de az eredeti vezető továbbra is elfogadja a nevezéseket acks=all, mert rajta kívül nincs más az ISR-ben. Ezek a rekordok a hálózat visszaállítása után elvesznek. Az egyetlen módja annak, hogy elkerüljük ezt a lehetőséget min.insync.replicas = 2.

7. forgatókönyv: A Kafka vezérlő csomópont nem lát egy másik Kafka csomópontot

Általában, ha a kapcsolat megszakad egy Kafka-csomóponttal, a vezérlő nem tud továbbítani semmilyen vezető-módosítási információt. A legrosszabb esetben ez rövid távú logikai szétváláshoz vezet, mint a 6. forgatókönyvben. Leggyakrabban a bróker egyszerűen nem válik vezetőjelöltté, ha az utóbbi kudarcot vall.

8. forgatókönyv: A Kafka vezérlő nem látja a Zookeepert

A Zookeeper nem kap pinget a bukott vezérlőtől, és egy új Kafka csomópontot választ ki vezérlőnek. Az eredeti vezérlő továbbra is ilyennek mutatkozhat be, de nem kap értesítést a Zookeeper-től, így nem lesz feladata. A hálózat helyreállítása után rájön, hogy már nem vezérlő, hanem egy rendes Kafka csomópont lett.

Következtetések a forgatókönyvekből

Azt látjuk, hogy a követő kapcsolat elvesztése nem eredményez üzenetvesztést, hanem egyszerűen átmenetileg csökkenti a redundanciát, amíg a hálózat vissza nem áll. Ez természetesen adatvesztéshez vezethet, ha egy vagy több csomópont elveszik.

Ha a vezető elválik a Zookeeper-től a kapcsolat megszakadása miatt, az üzenetek elvesztéséhez vezethet acks=1. A Zookeeperrel való kommunikáció hiánya rövid logikai szakadást okoz a két vezető között. Ezt a problémát a paraméter oldja meg acks=all.

Paraméter min.insync.replicas két vagy több replikába további biztosítékot nyújt arra vonatkozóan, hogy az ilyen rövid távú forgatókönyvek nem eredményeznek elveszett üzeneteket, mint a 6. forgatókönyvben.

Az elveszett üzenetek összefoglalása

Soroljuk fel az összes adatvesztési módot a Kafkában:

  • Bármilyen vezető hibája, ha az üzeneteket a használatával erősítették meg acks=1
  • Bármilyen tisztátalan átmenet a vezetésben, vagyis az ISR-en kívüli követőhöz, még vele együtt is acks=all
  • A vezető elkülönítése a Zookeeper-től, ha az üzenetek megerősítésre kerültek acks=1
  • A vezető teljes elszigetelése, aki már önmagára zsugorította az ISR-csoportot. Minden üzenet elveszik, még akkor is acks=all. Ez csak akkor igaz, ha min.insync.replicas=1.
  • Az összes partíciós csomópont egyidejű meghibásodása. Mivel a rendszer a memóriából nyugtázza az üzeneteket, előfordulhat, hogy egyes üzenetek még nincsenek lemezre írva. A szerverek újraindítása után előfordulhat, hogy néhány üzenet hiányzik.

A tisztátalan vezetői átállások vagy tiltással, vagy legalább két elbocsátással elkerülhetők. A legtartósabb konfiguráció a kombináció acks=all и min.insync.replicas több mint 1.

A RabbitMQ és a Kafka megbízhatóságának közvetlen összehasonlítása

A megbízhatóság és a magas rendelkezésre állás biztosítása érdekében mindkét platform egy elsődleges és másodlagos replikációs rendszert valósít meg. A RabbitMQ-nak azonban Achilles-sarka van. Hiba utáni újracsatlakozáskor a csomópontok elvetik az adataikat, és a szinkronizálás le van tiltva. Ez a kettős csapás megkérdőjelezi a RabbitMQ-ban a nagy sorok hosszú élettartamát. El kell fogadnia vagy csökkentett redundanciát vagy hosszú blokkolási időt. A redundancia csökkentése növeli a hatalmas adatvesztés kockázatát. De ha kicsik a sorok, akkor a redundancia érdekében a rövid (néhány másodperces) elérhetetlenségi időszakok ismételt csatlakozási kísérletekkel kezelhetők.

Kafkának nincs ilyen problémája. Csak a vezető és a követő közötti eltérés pontjáról veti el az adatokat. Minden megosztott adat mentésre kerül. Ezenkívül a replikáció nem blokkolja a rendszert. A vezető továbbra is fogad bejegyzéseket, míg az új követő utoléri, így a devops számára a klaszterhez való csatlakozás vagy újracsatlakozás triviális feladattá válik. Természetesen továbbra is vannak problémák, például a hálózati sávszélesség a replikáció során. Ha egyszerre több követőt ad hozzá, sávszélesség-korlátba ütközhet.

A RabbitMQ megbízhatóbb a Kafkánál, ha egy fürtben egyszerre több szerver is meghibásodik. Ahogy már említettük, a RabbitMQ csak azután küld visszaigazolást a kiadónak, miután az üzenetet a mester és az összes tükör lemezre írta. Ez azonban további késleltetést jelent két okból:

  • fsync néhány száz ezredmásodpercenként
  • A tükör meghibásodását csak az egyes csomópontok (net tick) elérhetőségét ellenőrző csomagok élettartamának lejárta után lehet észrevenni. Ha a tükör lelassul vagy leesik, ez késleltetést okoz.

Kafka fogadása az, hogy ha egy üzenetet több csomóponton tárolnak, akkor azonnal nyugtázni tudja az üzeneteket, amint elérik a memóriát. Emiatt fennáll a veszélye annak, hogy bármilyen típusú üzenetet elveszítenek (akár acks=all, min.insync.replicas=2) egyidejű meghibásodás esetén.

Összességében a Kafka jobb szoftverteljesítményt mutat, és az alapoktól kezdve fürtökhöz készült. A követők száma 11-re növelhető, ha a megbízhatóság érdekében szükséges. 5. replikációs faktor és a replikák minimális száma a szinkronizálásban min.insync.replicas=3 az üzenetvesztés nagyon ritka esemény lesz. Ha az infrastruktúra támogatja ezt a replikációs arányt és a redundancia szintjét, akkor választhatja ezt a lehetőséget.

A RabbitMQ fürtözés kis sorokhoz jó. De még a kis sorok is gyorsan növekedhetnek, ha nagy a forgalom. Ha a sorok megnövekednek, nehéz döntéseket kell hoznia a rendelkezésre állás és a megbízhatóság között. A RabbitMQ klaszterezés a nem tipikus helyzetekben a legalkalmasabb, ahol a RabbitMQ rugalmasságának előnyei felülmúlják a klaszterezés minden hátrányát.

A RabbitMQ nagy várólistákkal szembeni sebezhetőségének egyik ellenszere az, hogy azokat sok kisebb sorra bontja. Ha nem a teljes várólista teljes sorrendjét igényli, hanem csak a vonatkozó üzeneteket (például egy adott ügyféltől érkező üzeneteket), vagy egyáltalán nem rendel semmit, akkor ez a lehetőség elfogadható: nézze meg a projektemet Kiegyensúlyozó felosztani a sort (a projekt még korai szakaszban van).

Végül ne feledkezzünk meg a RabbitMQ és a Kafka klaszterezési és replikációs mechanizmusainak számos hibájáról sem. Az idő múlásával a rendszerek érettebbé és stabilabbá váltak, de egyetlen üzenet sem lesz 100%-ban biztonságban az elvesztéstől! Ráadásul az adatközpontokban nagyszabású balesetek történnek!

Ha valamit kihagytam, hibáztam, vagy valamelyik ponttal nem értesz egyet, nyugodtan írj megjegyzést vagy fordulj hozzám.

Gyakran kérdezik tőlem: „Mit válasszak, Kafka vagy RabbitMQ?”, „Melyik platform a jobb?”. Az igazság az, hogy ez valóban az Ön helyzetétől, jelenlegi tapasztalataitól stb. függ. Habozok elmondani a véleményemet, mert túlzott leegyszerűsítés lenne egyetlen platformot ajánlani minden felhasználási esetre és lehetséges korlátozásokra. Ezt a cikksorozatot azért írtam, hogy kialakíthasd a saját véleményedet.

Azt akarom mondani, hogy mindkét rendszer vezető szerepet tölt be ezen a területen. Lehet, hogy kissé elfogult vagyok, mert a projektekkel kapcsolatos tapasztalataim alapján általában értékelem az olyan dolgokat, mint a garantált üzenetrendezés és a megbízhatóság.

Látok más technológiákat, amelyekből hiányzik ez a megbízhatóság és a garantált rendelés, aztán megnézem a RabbitMQ-t és a Kafkát, és rájövök mindkét rendszer hihetetlen értékére.

Forrás: will.com

Hozzászólás