ano i ne.
Celá kafka je založena na tom, že broker drží offsety posledních zpracovaných zpráv pro každou partition a každou consumer group. Consumer je pak odpovědný za to, aby poslal ve správný okamžit "ack" a tím posunul offset a tady je to úskalí a rozdíl jednotlivých implementací a použití.
MM2 posílá ack asynchronně vzhledem ke zpracování, pokud zpracovává hodně zpráv, vynechává ack (to se ale nedávno změnilo v nové verzi již nevynechává tak extrémně). Oři jakémkoliv výpadku tedy hrozí situace, kdy poslední zprávy mohou být zpracované, ale offset neposunutý. Existuje riziko tedy dvojitého zpracování, s tím chce počítat a při replikaci to tolik nemusí vadit.
Pokud jde jen o výpadek tcp spojení, tak to se zkouší navazovat opakovaně a pokud je doba dostatečně krátká, bez problémů pokračuje v práci.
správně, pokud mají uniq ID. To kafka sama neřeší, používá message id jen jako vstup pro hash, z kterého jí vypadne partition (což je ale opět na straně producera, takže to může být jakkoliv).
Samotný kafka broker identifikuje zprávu jako kombinaci partition a offset, to je dost alibistické, ale dostatečně funkční.
Ke kafce musíš (můj názor) vždy mít nějakou formu deduplikace a to si musíš řešit vlastní cestou ideálně uvnitř dat. Kafka udělá vše, aby ti to nějak doručila.
Stejně tak je velký problém na straně producera, nemusí totiž vůbec dojít k řádnému odeslání do kafky (referenční implementaci producera třeba spoustu věcí bufferuje a nemusí se stihnout vše odeslat než ukončíš samotná proces).
MM2 celý problém duplicitních zpráv znásobuje. Bohužel jsem už viděl, že někdo posílá kafkou changesety (např. přičti 1), jak je zvyklý z event systémů. To nedělejte.
Bohužel někoho přes to napadlo dělat dokonce vyúčtování lidem.
Pořadí zpráv zaručuje pouze na úrovni partition, to ale často raději zamlčuji, protože pak následuje řešení, kdy začnou data strkat do partition podle domény/zákazníka, aby byla pěkně pohromadě. Následky jsou také zřejmé.
Použít kafku na cokoliv jiného než silnou předbíhající se pumpu vede vždy ke katastrofě, někdy bohužel ta katastrofa funguje pár let v produkci.
"broker drží offsety posledních zpracovaných zpráv pro každou partition a každou consumer group" je zcela pravda, ale je možné si je ukládat i "bokem", protože offsety jsou starostí konzumenta (nebo jeho skupiny). Viděl jsem takové řešení, že offsety šly někam do Redisu, ale už si nevzpomínám přesný důvod. Resp. bylo to v době, kdy se offsety ukládaly na Zookepera, tak jestli tehdy nebyly problémy tady.
To už je pěknou řádku let, kdy offsety byly plně na starosti konzumenta, od kafky 0.8 je práce s offsety součástí consumer api. Kafka je občas obětí neskutečné zpětné kompatibility.
Consumer api poskytuje možnost skákat po offsetech, takže i dnes mám možnost si offsety držet bokem a dává to občas smysl, zejména, když potřebuji přecházet mezi více stavy (např. načteno, zařazeno do fronty, zpracováno, dokončeno). Skákání by ale mělo být lineární, broker vyloženě nesnáží náhodný přístup.
Zookeeper je pořád jediná spolehlivá cesta jak provozovat kafku a Confluent má stále ještě v jeho revoluční změně zásadní nedostatky.
Zookeeper je pro hodně lidí velice složitý na provoz, je to java svět s kerberosem, na kterém si kdokoliv mimo javistů vyláme zuby. V téhle konstelaci bych čekal použití redisu a už jsem to i tak viděl, nikdy jsem ale nepřišel na obhajitelnou výhodu, to už raději použiji sql databázi.