IZVRŠNI SAŽETAK

PROBLEM

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.

  1. 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.
  2. 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.
  • Sačuvati originalni topic, particiju, offset, identitet partnera, sadržaj poruke, klasifikaciju greške, dijagnostiku i vremenske oznake.
  • 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.