Kafka processing pipeline mogao je iznova da zastaje kada neispravan poison-pill zapis izazove grešku pri parsiranju timestamp-a. Putanja obrade greške pozivala je sinhroni udaljeni API za konfiguraciju partnera, čiji je odgovor mogao da prekorači max.poll.interval.ms. To je izazivalo rebalance consumer grupe i ponovnu isporuku istog zapisa, pa je jedna neispravna poruka mogla da ometa inače ispravnu obradu. Greška nije bila dovoljno izolovana na nivou pojedinačnog zapisa, zbog čega je neispravan payload mogao da izazove širu nestabilnost konzumenata i ponavljane pokušaje obrade.
REŠENJE
Pipeline je redizajniran tako da validira zapise na granici obrade i izoluje neispravne payload-e od uobičajene putanje konzumenta. Poison-pill poruke preusmeravane su u transaction.dlq zajedno sa originalnim payload-om i dijagnostičkim informacijama, dok su zasebna consumer grupa i workflow za oporavak preuzimali istragu i ponovnu obradu. Stanje oporavka evidentirano je u PostgreSQL-u kroz PENDING_REVIEW, čime je sačuvana sledljivost bez blokiranja ispravne putanje sinhronim udaljenim pozivima.
KLJUČNI ARHITEKTONSKI POMAK
OD
ponovljena isporuka poison-pill zapisa koja iznova ometa glavnu consumer grupu
→
KA
izolacija neispravnih zapisa i nezavisan oporavak bez blokiranja ispravne obrade
ZAKLJUČAK
Neispravni zapisi mogli su da budu izolovani radi provere bez ponovljenog ometanja glavne consumer grupe. Dizajn je razdvojio greške na nivou zapisa od grešaka konzumenta, consumer grupe i cele platforme, omogućavajući da se oporavak odvija nezavisno od redovne obrade. Rezultat je bila bolje izolovana putanja greške uz očuvane originalne payload-e i dijagnostiku, umesto ponovljene isporuke poison-pill zapisa kroz primarni pipeline.
ARHITEKTONSKA ANALIZA
KONTEKST I POSLOVNI UTICAJ
Platforma obrađuje finansijske događaje u okruženju za poravnanje koje obuhvata više jurisdikcija. Kroz 8–12 Kafka particija svakodnevno prolazi približno 1.5M–2.5M finansijskih događaja.
U normalnim uslovima, saobraćaj iznosi približno 20–30 poruka u sekundi po aktivnoj particiji. Tokom perioda naglog porasta opterećenja, ukupan protok kroz aktivne particije dostiže približno 350–500 poruka u sekundi.
Vremenski prozori za obradu operativno su osetljivi: prekogranična poravnanja, partnerske paketne datoteke, preuzimanje podataka iz S3, finansijske transakcije u realnom vremenu i T+0 obrada podležu strogim rokovima za obradu i usklađivanje. Aktivnosti poravnanja i usklađivanja mogu se odvijati u vremenskim prozorima od 15–30 minuta.
Ponavljajuće zamrzavanje toka obrade stoga je predstavljalo više od greške pri obradi pojedinačne poruke. Kada je ista neispravna poruka iznova izazivala ponovno uravnotežavanje Kafka potrošačke grupe, prekid je ugrožavao mogućnost toka obrade da nastavi obradu ostalih, ispravnih finansijskih događaja.
Finansijski događaji dnevno
BEFORE
1.5M–2.5M
AFTER
1.5M–2.5M
Kontinuirana obrada velikog broja finansijskih događaja
Kafka particije
BEFORE
8–12
AFTER
8–12
Particionisana topologija obrade događaja
Normalan protok
BEFORE
20–30 msg/sec po aktivnoj particiji
AFTER
20–30 msg/sec po aktivnoj particiji
Uobičajeni operativni saobraćaj
Protok pri naglom porastu opterećenja
BEFORE
350–500 msg/sec agregirano
AFTER
350–500 msg/sec agregirano
Očekivani zbirni saobraćaj kroz aktivne particije
UZROK I MEHANIZAM GREŠKE
Problem su izazivale poruke sa neispravnim ili dvosmislenim vremenskim oznakama (timestamp). Njihovo tumačenje moglo je da zahteva sinhroni poziv udaljenog API-ja za preuzimanje partnerske konfiguracije kada lokalne informacije nisu bile dovoljne.
Taj poziv je uveo blokirajuću zavisnost od eksternog servisa direktno u obradu Kafka potrošača. Ako bi partnerski servis prestao da odgovara, obrada jedne poruke mogla je da ostane blokirana dovoljno dugo da prekorači vrednost max.poll.interval.ms za tog potrošača.
Kafka koordinator grupe tada je mogao da zaključi da je potrošač neaktivan i pokrene ponovno uravnotežavanje grupe (rebalance). Pošto trenutna poruka nije bila uspešno obrađena i potvrđena (commit), ista nepotvrđena poruka mogla je da bude dodeljena drugom potrošaču.
Novi potrošač nailazio je na istu neispravnu poruku i ponavljao isti blokirajući postupak. Problem tako više nije bio ograničen na jednu poruku, već je prerastao u ponavljajući obrazac otkazivanja potrošačke grupe.
KASKADA PONOVNIH URAVNOTEŽAVANJA ZBOG NEISPRAVNE PORUKE
NEISPRAVNA / DVOSMISLENA PORUKA
|
v
TUMAČENJE VREMENSKE OZNAKE
|
v
SINHRONI POZIV PARTNERSKOM API-JU
|
ZASTOJ SERVISA
|
v
OBRADA DUŽA OD max.poll.interval.ms
|
v
POTROŠAČ SE SMATRA NEAKTIVNIM
|
v
PONOVNO URAVNOTEŽAVANJE GRUPE
|
v
ISTA NEPOTVRĐENA PORUKA
|
v
NOVI POTROŠAČ PREUZIMA PORUKU
|
v
ISTA GREŠKA SE PONAVLJA
|
v
KASKADA PONOVNIH URAVNOTEŽAVANJA
|
v
ZAMRZAVANJE TOKA OBRADE
DVE GRANICE IZOLACIJE GREŠAKA
Redizajnirana arhitektura uvodi dve eksplicitne granice izolacije grešaka. Prva se nalazi na ulazu u sistem (edge ingestion), gde se neispravan ulazni podatak izdvaja pre nego što može da dospe u kritičnu putanju obrade.
Provera i sanitizacija na ulazu: proveriti strukturnu šemu, format vremenske oznake, obavezna polja i pravila specifična za partnera. Neispravne poruke izdvajaju se u karantin (quarantine), umesto da im se dozvoli da ugroze obradu toka podataka.
Izolacija pojedinačne poruke u dead-letter toku (DLQ): ako obrada poruke ipak ne uspe, izdvojiti je u zaseban topic transaction.dlq, bez izvršavanja blokirajućeg oporavka na primarnoj putanji Kafka potrošača.
GRANICE IZOLACIJE GREŠAKA
EKSTERNI ULAZ
|
v
+----------------------------+
| SANITIZACIJA NA ULAZU |
| |
| Provera šeme |
| Provera vremenske oznake |
| Obavezna polja |
| Pravila za partnera |
+----------------------------+
|
+----------+----------+
| |
ISPRAVNO NEISPRAVNO
| |
v v
PRIMARNI TOK KARANTIN
OBRADE
|
v
OBRADA PORUKE
|
+-----+-----+
| |
USPEH GREŠKA
| |
v v
POTVRDA transaction.dlq
|
v
TOK OPORAVKA
NEBLOKIRAJUĆA IZOLACIJA NEUSPEŠNIH PORUKA
Putanja za oporavak pojedinačne poruke ne izvršava sinhroni udaljeni oporavak niti preuzimanje konfiguracije iz primarnog Kafka potrošača. Neuspešna poruka usmerava se u zaseban topic transaction.dlq, čime se primarnoj putanji obrade omogućava da nastavi rad.
Poruka u DLQ-u čuva informacije potrebne za precizno utvrđivanje uzroka greške i porekla originalnog događaja. Na taj način greška može da se otkloni nezavisno, bez ponavljanja istog problema u primarnoj Kafka potrošačkoj grupi.
x-error-class
x-original-topic
x-original-partition
x-original-offset
x-partner-id
x-trace-id
x-exception-message
Primer dijagnostičkog zapisa identifikuje grešku kao InvalidTimestampException za topic payment.transactions.v1, particiju 3 i offset 48190241. Zapis je povezan sa partnerom PARTNER_EU_904 i identifikatorom praćenja tr_b891a-89f4-421c. Dijagnostička poruka sačuvana je kao 'Unparseable timestamp'.
IZOLACIJA POJEDINAČNE PORUKE
PRIMARNI KAFKA POTROŠAČ
|
v
OBRADA PORUKE
|
+----------+----------+
| |
USPEH GREŠKA
| |
v v
POTVRDA transaction.dlq
| |
v v
NASTAVAK RADA GRUPA ZA OPORAVAK
|
v
PENDING_REVIEW
|
v
KONTROLISANI REPLAY
KONTROLISANI OPORAVAK I PONOVNA OBRADA
Poruke iz DLQ-a obrađuje zasebna potrošačka grupa, a ne primarna grupa za obradu događaja. Time se kapacitet oporavka i njegovi potencijalni propusti odvajaju od produkcione putanje za obradu.
PostgreSQL čuva stanje oporavka pod oznakom PENDING_REVIEW. Zapis sadrži originalni sadržaj poruke (payload), izvorni topic, particiju i offset, identitet partnera, klasifikaciju greške, dijagnostičke podatke i vremenske oznake.
Originalni sadržaj događaja
Izvorni Kafka topic
Izvorna particija
Izvorni offset
Identitet partnera
Klasifikacija greške
Dijagnostički podaci o grešci
Relevantne vremenske oznake
Stanje oporavka: PENDING_REVIEW
Kada se uzrok problema razume ili otkloni, poruka može ponovo da se obradi kroz kontrolisani tok oporavka. Oporavak je tako eksplicitan operativni postupak, a ne slučajna posledica ponovnog uravnotežavanja Kafka potrošačke grupe.
TOK OPORAVKA
transaction.dlq
|
v
ZASEBNA GRUPA ZA OPORAVAK
|
v
POSTGRESQL
PENDING_REVIEW
|
v
DIJAGNOSTIKA / ISPRAVKA
|
v
KONTROLISANI REPLAY
|
v
PRIMARNA PUTANJA OBRADE
KLJUČNE INŽENJERSKE ODLUKE
Proveravati i sanitizovati ulazne podatke na ulazu u sistem pre nego što neispravne poruke dospeju u primarnu putanju obrade.
Ne izvršavati blokirajuće udaljene I/O operacije kao deo obrade greške poruke u primarnom Kafka potrošaču.
Koristiti izolaciju pojedinačne poruke u dead-letter toku (DLQ) umesto dozvoljavanja da neuspešna poruka iznova izaziva ponovno uravnotežavanje potrošačke grupe.
Posle izolacije neuspešne poruke omogućiti primarnom potrošaču da nastavi obradu.
Koristiti zaseban topic transaction.dlq za neispravne poruke koje ponavljanjem izazivaju greške.
Koristiti zasebnu potrošačku grupu i tok rada za oporavak.
Čuvati stanje oporavka PENDING_REVIEW u PostgreSQL-u.
Koristiti kontrolisanu ponovnu obradu umesto implicitnog ponavljanja izazvanog ponovnom dodelom poruke u potrošačkoj grupi.
Arhitektura namerno razlikuje četiri nivoa greške: grešku pojedinačne poruke, grešku potrošača, grešku potrošačke grupe i grešku platforme. Pojedinačna poruka može da ne uspe, a da nijedan od viših nivoa ne mora da otkaže zajedno sa njom.
ARHITEKTONSKI ISHOD
Rezultujuća arhitektura tretira neispravne poruke kao izolovane greške kvaliteta podataka ili obrade, a ne kao događaje kojima je dozvoljeno da određuju životni ciklus procesora toka podataka.
PRE
NEISPRAVNA PORUKA
|
v
BLOKIRAJUĆA OBRADA
|
v
ZASTOJ UDALJENOG SERVISA
|
v
PREKORAČEN max.poll.interval.ms
|
v
GREŠKA POTROŠAČA
|
v
PONOVNO URAVNOTEŽAVANJE
|
v
ISTA NEPOTVRĐENA PORUKA
|
v
PONOVLJENA GREŠKA
|
v
ZAMRZAVANJE TOKA OBRADE
POSLE
ULAZ
|
v
SANITIZACIJA NA ULAZU
|
+--------+--------+
| |
ISPRAVNO NEISPRAVNO
| |
v v
PRIMARNA KARANTIN
OBRADA
|
+-----+-----+
| |
USPEH GREŠKA
| |
v v
POTVRDA transaction.dlq
|
v
ZASEBAN OPORAVAK
|
v
PENDING_REVIEW
|
v
KONTROLISANI REPLAY
Suština arhitektonske promene nije samo uvođenje dead-letter topica. Ključna promena je razdvajanje životnih ciklusa grešaka: neispravna poruka može da ne uspe, bude izdvojena u karantin i zahteva ručni ili kontrolisani oporavak, a da pritom ne izazove otkazivanje Kafka potrošača, potrošačke grupe ili cele platforme za obradu.
KVANTIFIKOVANI REZULTATI
Zamrzavanja toka obrade
PRE
1–2 značajna zamrzavanja mesečno
POSLE
0 zabeleženih
Tokom validacije nisu zabeležena ponavljajuća zamrzavanja izazvana neispravnim porukama
Odluka o izolaciji i rutiranju
PRE
Blokirajuća putanja obrade greške
POSLE
<10 ms
Izmereno vreme odluke o izolaciji i rutiranju pojedinačne poruke, a ne ukupno vreme obrade od početka do kraja
Ponovna uravnotežavanja potrošačke grupe
PRE
Ponavljajuća tokom grešaka izazvanih neispravnim porukama
POSLE
0 zabeleženih
Tokom validacije neispravne poruke nisu izazivale ponovno uravnotežavanje grupe
Blokirajuća obrada potrošača
PRE
>300,000 ms
POSLE
Neblokirajuća
Primarni potrošač više ne čeka na blokirajuću putanju oporavka od greške
Oporavak
PRE
Ad hoc oporavak
POSLE
Kontrolisana ponovna obrada
Poruke iz DLQ-a oporavljaju se kroz eksplicitan tok rada
Redizajn izdvaja neispravne poruke pre nego što mogu da destabilizuju primarnu potrošačku grupu i premešta oporavak u nezavisan tok rada.
U prethodnom scenariju greške obrada potrošača mogla je da ostane blokirana duže od 300,000 ms, čime je mogla da prekorači konfigurisan max.poll.interval.ms. Redizajnirana putanja omogućava primarnom potrošaču da nastavi rad bez čekanja na oporavak poruke iz DLQ-a.
Platforma je prešla sa implicitnog ponavljanja obrade i nestabilnosti potrošačke grupe na eksplicitnu izolaciju poruka, neblokirajuću primarnu obradu i kontrolisani oporavak. Greška izazvana neispravnom porukom više se ne prenosi automatski na životni ciklus procesora toka podataka.
INŽENJERSKI DOPRINOS
SWARCS je analizirao uzroke grešaka kroz ceo sistem i redizajnirao granice obrade u Kafki kako bi se neispravne poruke izolovale bez destabilizacije primarne potrošačke grupe.
ODGOVORNOSTI
Analiza ponašanja Kafka potrošača i ponavljajućih grešaka izazvanih neispravnim porukama.
Identifikacija blokirajućeg poziva udaljenog servisa za preuzimanje partnerske konfiguracije kao rizika za životni ciklus potrošača.
Definisanje sanitizacije na ulazu radi provere šeme, vremenskih oznaka, obaveznih polja i pravila specifičnih za partnera.
Uvođenje izolacije pojedinačnih poruka u dead-letter tok korišćenjem transaction.dlq.
Obezbeđivanje da primarni potrošač ne izvršava blokirajuće I/O operacije u okviru oporavka od greške.
Definisanje metapodataka DLQ poruka, uključujući klasu greške, izvorni topic, particiju, offset, identitet partnera, identifikator praćenja i dijagnostičke podatke o izuzetku.
Uvođenje stanja PENDING_REVIEW za oporavak u PostgreSQL-u.
Izdvajanje obrade oporavka u zasebnu potrošačku grupu i tok rada.
Definisanje kontrolisane ponovne obrade umesto oslanjanja na ponovno dodeljivanje poruke pri uravnotežavanju grupe.
Provera ponašanja izolacione putanje i potrošačke grupe u scenarijima sa neispravnim porukama.
KLJUČNA PORUKA
NEISPRAVAN ULAZ NE SME DA KONTROLIŠE ŽIVOTNI CIKLUS PROCESORA TOKA PODATAKA.
Sanitizacija na ulazu
Izolacija greške pojedinačne poruke
Neblokirajuća obrada potrošača
Dead-letter tok (DLQ)
Zasebni tokovi oporavka
Kontrolisana ponovna obrada
Razdvajanje opsega grešaka
Stabilnost Kafka potrošača
Loša poruka treba da proizvede neuspešnu poruku, a nikada neuspešnu platformu. Suštinska razlika postoji između greške poruke, greške potrošača, greške potrošačke grupe i greške platforme. Uvođenjem eksplicitnih granica izolacije, izdvajanjem neispravnih poruka i premeštanjem oporavka izvan primarne putanje obrade, neispravan ulaz postaje operativna stavka za oporavak umesto izvora lančanog širenja greške kroz distribuirani sistem.