Lecția 41 a făcut mișcarea conceptuală de la date mărginite la nemărginite. Forma naturală de procesare pentru date nemărginite este streaming-ul, iar streaming-ul are nevoie de un substrat: un loc unde producătorii scriu evenimente și consumatorii le citesc, suficient de durabil încât să supraviețuiască eșecurilor, suficient de rapid încât să țină pasul cu firehose-ul, și rerulabil pentru ca consumatorii să poată derula înapoi când greșesc ceva. Răspunsul dominant în 2026, cu o marjă largă, este Apache Kafka. Această lecție acoperă ce este Kafka, ce garantează și de ce a ajuns peste tot.
TLDR-ul încape într-o singură propoziție. Kafka este un log distribuit, durabil, partiționat, append-only, în care producătorii scriu și din care consumatorii citesc în propriul ritm.
Fiecare dintre acele cuvinte face muncă reală, iar restul lecției le despachetează.
Modelul mental
Un cluster Kafka are șase concepte. Înțelege-le bine, iar restul e detaliu.
Topic. Un log denumit. Conceptual ca un tabel de bază de date, doar că înregistrările sunt adăugate, nu actualizate, iar consumatorii citesc dintr-o poziție în loc să ruleze query-uri. Un deployment Kafka are de obicei zeci până la mii de topic-uri, unul per stream logic de evenimente: orders.placed, payments.completed, users.signed-up, inventory.updated și așa mai departe.
Partition. Un sub-log în interiorul unui topic. Un topic cu douăsprezece partiții reprezintă douăsprezece log-uri append-only separate care împart un nume. Fiecare partiție este strict ordonată: înregistrările adăugate la partiția 3 vor fi citite în aceeași ordine în care au fost scrise. Între partiții nu există garanție de ordine. Partițiile sunt unitatea de paralelism: mai multe partiții, mai mulți consumatori paraleli, mai mulți writer-i paraleli.
Producer. Un client care scrie înregistrări într-un topic. Producer-ul fie alege explicit partiția, fie face hash pe o cheie ca să aleagă determinist (așa că toate evenimentele pentru user-42 ajung în aceeași partiție și rămân în ordine), fie lasă Kafka să facă round-robin între partiții când ordinea pe cheie nu contează.
Consumer. Un client care citește înregistrări din una sau mai multe partiții. Consumer-ul își urmărește poziția în fiecare partiție prin offset: un întreg monoton crescător care numește o înregistrare specifică. „Am citit până la offset-ul 1.847.392 al partiției 5 din topic-ul orders.placed” este o descriere completă a stării unui consumator. Offset-urile sunt stocate de Kafka însuși într-un topic special __consumer_offsets, nu de consumator.
Consumer group. Un set coordonat de consumatori care își împart sarcina de citire. Fiecare partiție a unui topic abonat este consumată de exact un membru al grupului la un moment dat. Dacă ai douăsprezece partiții și patru consumatori în grup, fiecare consumator citește trei partiții. Dacă scalezi grupul la doisprezece consumatori, fiecare citește una. Dacă scalezi la douăzeci, opt stau inactivi (nu poți avea mai mulți consumatori decât partiții într-un grup). Când un consumator moare, clusterul se rebalansează și un alt consumator din grup îi preia partițiile.
Broker. Un server Kafka. Un cluster are mulți brokeri (un deployment mic are trei, unul mare are sute). Fiecare partiție are mai multe replici răspândite între brokeri, una desemnată leader (gestionează scrierile și citirile) și celelalte followers (replică de la leader). Dacă un broker moare, clusterul alege un nou leader pentru partițiile ai căror lideri au murit, iar producătorii și consumatorii fac failover fără intervenție manuală.
flowchart LR
P1[Producer 1] --> T
P2[Producer 2] --> T
subgraph T[Topic: orders.placed]
direction TB
PA[Partition 0]
PB[Partition 1]
PC[Partition 2]
end
subgraph CG1[Consumer group: billing]
C1[Consumer 1]
C2[Consumer 2]
end
subgraph CG2[Consumer group: analytics]
C3[Consumer 3]
end
PA --> C1
PB --> C2
PC --> C2
PA --> C3
PB --> C3
PC --> C3
Diagram to create: a polished version showing producers on the left writing to a topic with three partitions in the middle, brokers replicating the partitions implicitly, and two consumer groups on the right reading the same topic independently. The key visual point is that partitions are the unit of parallelism within a group, but each consumer group reads the full topic independently.
Diagrama surprinde cea mai importantă proprietate a modelului: două consumer groups care citesc același topic sunt independente. Grupul de billing citește propria copie în propriul ritm; grupul de analytics citește propria copie în propriul ritm. Împart datele; nu împart poziția. Asta înseamnă în practică „decuplează producătorii de consumatori”.
Garanțiile
Kafka oferă un set mic și specific de garanții, iar multă confuzie mentală dispare odată ce știi exact care sunt acelea.
În interiorul unei partiții, ordine strictă. Dacă producătorul A scrie înregistrarea X și apoi înregistrarea Y în aceeași partiție, fiecare consumator citește X înainte de Y. Aceasta este cea mai puternică garanție de ordonare pe care o oferă Kafka și este motivul pentru care partiționarea pe cheie contează: dacă vrei ca evenimentele pentru user-42 să fie procesate în ordine, faci cheia după user ID astfel încât să aterizeze în aceeași partiție.
Între partiții, fără garanție de ordine. Dacă producătorul A scrie înregistrarea X la partiția 0 și înregistrarea Y la partiția 1, consumatorii pot să le citească în orice ordine. Nu este un bug; este prețul paralelismului. Dacă ai nevoie de ordonare globală, ai o singură partiție, ceea ce înseamnă un singur consumator, ceea ce înseamnă fără paralelism. Majoritatea echipelor aleg cu grijă cheile de partiționare și trăiesc cu ordonarea per-cheie.
Durabilitate prin replicare. O înregistrare este durabilă odată ce a fost replicată pe N noduri, unde N este nivelul acks configurat. Cu acks=all și factor de replicare 3, o înregistrare este confirmată producătorului doar după ce toate trei replicile o au pe disc. Dacă un broker moare după ack, înregistrarea supraviețuiește pe replicile rămase. Dacă toate trei replicile mor, înregistrarea se pierde; e rar dar posibil, și de aceea Kafka este configurat cu grijă în industriile reglementate.
Livrare at-least-once implicit. O înregistrare este livrată cel puțin o dată, posibil mai multe. Cazul „mai mult de o dată” se întâmplă când un consumator procesează o înregistrare, moare înainte să comită offset-ul, iar un înlocuitor citește de la ultimul offset comis (înainte de înregistrare). Înregistrarea este procesată de două ori. Consumatorii idempotenți (lecția 38 a acoperit pattern-ul în batch; versiunea de streaming este identică) sunt cum trăiești cu at-least-once.
Exactly-once în interiorul Kafka prin tranzacții. De la Kafka 0.11 (2017), tranzacțiile permit unui producător să scrie atomic în mai multe partiții și permit unui consumator să citească înregistrările doar din interiorul tranzacțiilor comise. Combinat cu producer-ul idempotent, asta dă semantici exactly-once pentru workflow-urile read-from-Kafka, process, write-to-Kafka. Exactly-once care traversează granița în afara Kafka este mai greu, iar lecția 45 îl acoperă.
Sumarul care încape pe un post-it: în interiorul unei partiții, ordine strictă; între partiții, niciuna; at-least-once dacă nu optezi pentru tranzacții; durabilitate ajustabilă prin acks și factorul de replicare.
De ce a devenit Kafka dominant
Kafka a început la LinkedIn în 2010, a fost open-source-uit în 2011, a devenit proiect Apache top-level în 2012, iar până în 2018 era substratul de streaming implicit la majoritatea companiilor care aveau unul. Motivele sunt structurale, nu de marketing.
Producătorii și consumatorii sunt decuplați. Un producător scrie; înregistrarea stă în log; consumatorii citesc când ajung la ea. Producătorul nu trebuie să știe cine citește; consumatorul nu trebuie să fie online când scrie producătorul. Compară asta cu RPC, unde apelantul și apelatul trebuie să fie online simultan, și vezi de ce arhitecturile event-driven (Modulul 7) merg pe Kafka, nu pe apeluri directe între servicii.
Replay-urile sunt ieftine. Kafka reține înregistrările pentru o perioadă configurabilă (adesea șapte zile, uneori săptămâni, uneori pentru totdeauna pentru topic-uri compactate). Un consumator poate să deruleze înapoi la orice offset și să reproceseze; un consumator nou poate porni de la offset zero și să citească toată istoria. Aceasta este proprietatea care face arhitectura Kappa (lecția 46) să funcționeze.
Scalarea pe partiții este mecanică. Un topic cu douăsprezece partiții poate fi consumat de până la doisprezece consumatori paraleli într-un grup. Ai nevoie de mai mult throughput? Adaugă partiții, adaugă consumatori. Compară asta cu scalarea unei baze de date relaționale, unde adăugarea de capacitate cere muncă arhitecturală reală.
Este coloana de integrare. Un sistem de microservicii are un serviciu de comenzi, un serviciu de plăți, un serviciu de inventar, un serviciu de notificări, un serviciu de analitice. Fără Kafka, fiecare pereche de servicii care trebuie să comunice trebuie să definească un API: o problemă N-pe-M. Cu Kafka, fiecare serviciu scrie evenimente în topic-uri și citește topic-urile care îl interesează. Forma de integrare se prăbușește dintr-o plasă de apeluri HTTP într-o stea în jurul Kafka. Acesta este cel mai mare singur motiv pentru care Kafka s-a extins de la „unealtă de data engineering” la „infrastructură generală” între 2015 și 2020.
Ecosistem puternic de clienți. Producători și consumatori există pentru fiecare limbaj pe care îl folosește o companie reală: Java, Python (confluent-kafka, kafka-python), Go, Rust, Node.js, .NET, Scala. Schema registries se integrează curat. Connect, framework-ul Kafka-către-alte-sisteme, are sute de conectori. Ecosistemul este în sine un șanț de apărare.
Alternativele 2026
Kafka este dominant; nu este singur. Patru concurenți contează suficient ca să-i numim.
Redpanda. O rescriere în C++ a protocolului Kafka, stabilă pentru producție din 2022. Vorbește protocolul de fir Kafka, deci clienții existenți funcționează, vine ca un singur binar fără JVM și fără ZooKeeper. Operațional mai simplu, latență de coadă mai mică, mai puține piese în mișcare. Compromisul este un ecosistem mai mic și un singur vendor în spatele distribuției open-source.
Apache Pulsar. A început la Yahoo, acum proiect Apache. Separă storage-ul (BookKeeper) de servire, oferind elasticitate mai bună și storage stratificat din cutie. Adoptarea este reală, dar mai mică decât a Kafka.
AWS Kinesis, Google Pub/Sub, Azure Event Hubs. Alternativele cloud-native gestionate. Fiecare operațional banal față de a rula Kafka singur, fiecare blocată în cloud-ul ei. Multe echipe aleg una dintre acestea și nu se mai uită înapoi. Multe altele rulează Kafka gestionat (Confluent Cloud, AWS MSK, Aiven) tocmai pentru că vor semantici Kafka cu operațiuni cloud.
Citirea onestă. Dacă pornești de la zero și ești angajat la un singur cloud, opțiunea nativă a cloud-ului este în regulă și probabil mai ușoară. Dacă vrei portabilitate și pârghie de ecosistem, Kafka (gestionat sau self-hosted, sau Redpanda ca drop-in) este încă implicit.
Când să NU folosești Kafka
Kafka este o unealtă puternică. Este și una grea, iar nu orice workload care implică „evenimente” are nevoie de el.
Cozi cu volum mic. Dacă ai câteva mii de joburi async pe zi (trimite un email, generează un PDF, declanșează o recalculare), nu ai nevoie de Kafka. Un tabel Postgres cu o coloană pending/done și un worker care face polling pe el funcționează bine până la volume surprinzător de mari. SQS, RabbitMQ și cozile bazate pe Redis (Sidekiq, Bull, Celery) sunt mai simple operațional și o potrivire mai bună.
Bucle de control cu adevărat în timp real. Latența Kafka este în zona milisecundelor. Unele workload-uri au nevoie de latență la nivel de microsecundă: high-frequency trading, control industrial, anumite robotici. Kafka nu este unealta corectă pentru acelea.
Seturi mici de date unde nu ai nevoie de un log. Dacă „stream-ul” tău este câteva sute de evenimente pe zi de la un singur producător la un singur consumator, un webhook plus un tabel de bază de date bate un cluster Kafka.
Regula de degetar: când ai mai multe servicii care produc evenimente, mai multe care consumă, nevoia de a rerula istoria sau throughput care depășește zeci de mii de evenimente pe secundă, Kafka începe să se merite. Sub asta, uneltele mai simple câștigă.
Unde duce asta
Kafka este substratul. Lecția 43 acoperă engine-urile care citesc din el și scriu înapoi în el: Apache Flink, Kafka Streams, Spark Structured Streaming. Alegerea engine-ului este următoarea decizie arhitecturală, iar compromisurile sunt diferite de alegerea Kafka-versus-alternative. Lecția 44 acoperă event time și watermarks, locul unde engine-urile încep să arate diferit unele de altele. Lecția 47 acoperă Change Data Capture, pattern-ul care transformă bazele de date relaționale în producători Kafka și permite sistemelor de streaming să se integreze curat cu lumea OLTP.
Tema recurentă prin restul Modulului 6 este că Kafka este partea ușoară. Partea grea este ce faci cu înregistrările odată ce curg.
Citări și lecturi suplimentare
- Documentația Apache Kafka,
https://kafka.apache.org/documentation/(consultat 2026-05-01). Referința canonică. Secțiunea „Design” este scurtă și merită citită cap-coadă; explică modelul de partiționare, replicare și consumer-group cu cuvintele autorilor originali. - Jay Kreps, Neha Narkhede, Jun Rao, „Kafka: a Distributed Messaging System for Log Processing”, workshop NetDB, 2011. Lucrarea originală a echipei LinkedIn. Scurtă și clară; designul nu s-a schimbat în esență.
- Jay Kreps, „The Log: What every software engineer should know about real-time data’s unifying abstraction”, LinkedIn Engineering, 2013,
https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying(consultat 2026-05-01). Eseul care a explicat de ce „log-ul” este abstracția corectă pentru date distribuite, și de ce Kafka s-a modelat în jurul ei. - „Kafka: The Definitive Guide” (Gwen Shapira, Todd Palino, Rajini Sivaram, Krit Petty, ediția a 2-a, O’Reilly, 2021). Cartea de referință standard.
- Documentația Redpanda,
https://docs.redpanda.com/(consultat 2026-05-01). Pentru alternativa C++ compatibilă Kafka. - „Designing Data-Intensive Applications” (Martin Kleppmann, O’Reilly, 2017), capitolul 11. Cadrul de context-de-sisteme al mesageriei bazate pe log, față de care Kafka este exemplul canonic.