Jak funguje replikace v Kafce
Co se stane, když nám server s Kafka Brokerem shoří? Není Kafka Broker single point of failure? Asi všichni tušíme, že není… Pro každý topic totiž lze nastavit počet replikací. Pokud pro topic nastavíme replikaci na hodnotu tři, znamená to, že všechny zprávy, které do topicu pošleme, se zkopírují na další dva servery (respektive Kafka brokery) a jedna zpráva se bude celkem nacházet na třech serverech.
Důležité je, že se o replikaci nemusí starat producer – ten stále odesílá zprávy na jeden server a Kafka cluster už si sám řeší replikaci dat na další servery. Flow vypadá takto:
Producer pošle zprávu brokerovi #1, ten zprávu zapíše k sobě na disk a zároveň se zpráva replikuje u brokerů #2 a #3, které si ji také zapíší na disk. Tím dojde k záloze a pokud Broker #1 vypadne, provoz se automaticky přesměruje na jeden ze zbývajících brokerů:
Replikací nicméně nezvýšíme propustnost služby. Máme-li nastavenou replikaci 3, neznamená to, že když budeme číst zprávy z tohoto topicu, že budeme číst zprávy paralelně ze všech tří brokerů. Vždy se zvolí jeden broker jako leader, z něj se čtou zprávy a zbylé dva servery se pro čtení nepoužijí. V předchozím obrázku například consumer čte zprávy z brokeru #2 a z brokeru #3 žádné zprávy nedostává, přestože tento broker má zprávy z daného topicu uložené u sebe na disku.
ISR
Teď trochu detailněji o tom, jak replikce funguje. Tímto příkazem založíme topic:
1 | bin/kafka-topics.sh --create --zookeeper zookeeper01:2181 \ |
Leader by od této chvíle čekal na potvrzení jen od kafka02. Pokud by spadnul leader, stala by se leaderem kafka02:
1 | $ get /brokers/topics/bidrequests/partitions/0/state {"leader":2, "version":1, "isr":[2]} |
Všechny zprávy by v tuto chvíli tekly jen přes kafka02 a docházelo by k nulové záloze. Je přitom jedno, že vedle máme stroje kafka03, kafka04 a kafka05, které žijí – partition 0 má nastaveno, že poběží na strojích kafka00, kafka01 a kafka02, takže dokud tyto stroje neoživíme, nebude docházet k žádné replikaci. Nemusí to být samozřejmě stejné servery, stačí spustit Kafka broker se stejným ID.
Pokud jakýmkoliv způsobem přivedeme k životu kafka01, ta zjistí, že by měla obsluhovat partition 0 topicu bidrequests, takže si začne z leaderu tahat chybějící data. Až je natáhne, stane se zase ISR, což se uloží do ZooKeeperu. Leader se nezmění.
$ get /brokers/topics/bidrequests/partitions/0/state
{"leader":2, "version":1, "isr":[2,1]}
Máme-li nastavenou replikaci r
, náš systém bude tolerovat až r-1
nedostupných ISR. Pokud vypadne všech r
strojů, máme samozřejmě smůlu.
Nastavení Kafky týkající se replikace
Kafka umožňuje více specifikovat, jak se v určitých situacích týkajících se replikace chovat:
request.required.acks
určuje, jestli bude producer čekat na potvrzení doručení zprávy. Možné hodnoty:0
: Producer nečeká na žádné potvrzení, rychlost odesílání je nejvyšší.1
: Producer čeká na potvrzení leadera.-1
: Producer čeká na potvrzení leadera a všech replik v ISR. Při tomto nastavení bue producer nejpomalejší, protože bude relativně dlouho čekat na potvrzení doručení zpráv, ale zase máte největší jistotu, že o žádnou zprávu nepřijdete.
min.insync.replicas
určuje minimální počet ISR. Pokud například nastavíterequest.required.acks
na-1
, tj. producer bude čekat na potvrzení od všech ISR, může se stejně stát, že všechny replicy spadnou a ISR bude obsahovat pouze leadera. Tímto nastavením můžete říci, že pokud je velikost ISR menší nežmin.insync.replicas
, začne producer vyhazovat při odesílání výjimky.