Kafka forklart: Logg, topics, partisjoner, produsenter og konsumenter

- Det er ryggraden i viktige systemer hos store internasjonale selskaper som Netflix, LinkedIn og Spotify, skriver Brage Allum. Men hva er egentlig Kafka?

Artikkelen om Kafka er basert på en presentasjon Brage Allum hadde på Ynes årlige internkonferanse. 📸: Privat
Artikkelen om Kafka er basert på en presentasjon Brage Allum hadde på Ynes årlige internkonferanse. 📸: Privat Vis mer

Kafka er et av de beste verktøyene for systemer som må være skalerbare, robuste og fleksible. Det er ryggraden i viktige systemer hos store internasjonale selskaper som Netflix, LinkedIn og Spotify og sentrale Norske selskaper som NAV, Telenor og Finn.no.

Enten du er en systemarkitekt som utforsker løsninger for skalerbare systemer eller en nysgjerrig utvikler på utkikk etter et nytt verktøy, håper jeg denne artikkelen vil gi deg et verdifullt innblikk i hva Kafka handler om.

Apache Kafka er en mye brukt og veldig skalerbar plattform for asynkron datadeling. Den skiller seg fra andre verktøy som for eksempel RabbitMQ og AWS EventBridge ved at den beholder rekkefølgen på eventene og lagrer eventer til disk slik at de kan leses når som helst.

«Det er ryggraden i viktige systemer hos store internasjonale selskaper som Netflix, LinkedIn og Spotify.»

Selskaper velger å bruke Kafka nettopp på grunn av hvor skalerbart og robust det er. I tillegg kan det ikke bare brukes til å implementere publisher-subscriber arkitektur, men også til å håndtere strømmer av data som skal sendes og prosesseres på tvers av applikasjoner. Dette kan man ikke med verktøy som mangler garanti for at eventene kommer i samme rekkefølge som de ble publisert.

I denne artikkelen vil jeg gå gjennom de mest sentrale konseptene i Kafka og hva de har for arkitekturen i ditt system:

#1: Logg

Det viktigste konseptet for å forstå hvordan Kafka fungerer, er noe som kalles en logg. For oss utviklere, er “logg” vanligvis assosiert med konsoll-loggen fra en applikasjon. I Kafka er en logg noe lignende, men mer generelt - en datastruktur.

Den kan beskrives som en liste med én enkelt skriveoperasjon: å legge til en ny enhet av data, kalt et event, på slutten av listen. Eventer kan verken endres eller slettes etter at de er blitt skrevet i loggen. De kan heller ikke legges til på andre steder enn i slutten av listen. Senere er det mulig å lese ut eventene i loggen og dermed få en tidslinje av eventene som har blitt lagt til i loggen.

Ser man på Kafka “under panseret”, så lagres dataen i logger. Loggene i Kafka lever inne i hver sin partisjon. Det vil si at lesing og skriving fra en partisjon (den minste oppdelingen av data i Kafka) følger samme regler som lesing og skriving fra en logg.

#2: Dataorganisering

Data i Kafka organiseres i kategorier som kalles topics. Et topic representerer en spesifikk strøm av data.

Et topic er også delt opp i en eller flere partisjoner, noe som er viktig for skaleringen av systemet. Eventer blir publisert til et topic, som gjør at det legges til i en eventlogg under ett av partisjonene i det gitte topicet.

Topics kan sammenlignes med hvordan data er organisert i tabeller i relasjonsdatabaser, med den viktige forskjellen at et topic holder på eventhistorikk, mens tabeller holder på tilstanden til et system.

💡 Systemene som sender eventer til Kafka-topicer kalles produsenter, mens de som leser fra et topic kalles konsumenter.

«Blant annet brukes Kafka til å samle og behandle brukeraktivitet-data hos LinkedIn.»

#3: Bruksområder for Kafka

Før vi dykker dypere inn i de tekniske aspektene ved Kafka tenker jeg det er lurt å snakke mer om hva Kafka kan brukes til. Man kan dele de vanligste bruksområdene til Kafka opp i to kategorier: Behandling av datastrømmer og implementering av mikrotjenestearkitektur.

  • Behandling av datastrømmer: Kafkas evne til å beholde rekkefølgen av eventer og samtidig håndtere stor gjennomstrømning av data gjør den spesielt egnet til behandling av strømmer av data som går på tvers av applikasjoner. Blant annet brukes Kafka til å samle og behandle brukeraktivitetsdata hos LinkedIn og til sanntidsmonitorering og analyse av logger hos CloudFlare.
  • Implementering av mikrotjenestearkitektur: Kafka kan også brukes til å implementere såkalt publisher-subscriber arkitektur, noe som ofte brukes for asynkron kommunikasjon mellom mikrotjenester. På denne måten kan Kafka gjøre at tjenestene i systemet blir mindre direkte avhengig av hverandre, spesielt med tanke på oppetid og responsivitet. Her kan Kafka ta plassen til meldingsbrokere, men da med en litt annen tilnærming til problemet. Istedenfor å ha garantier for at hver melding blir lest og behandlet før de slettes, så lagres meldingene slik at hvilken som helst konsument kan lese meldingen når det passer for dem.

#4: Skalering

For å kunne skalere bedre partisjonerer Kafka data innenfor hvert topic. Det gjør det mulig å skalere horisontalt ved å fordele partisjonene på flere maskiner i en Kafka-cluster. Slik kan data og arbeidsbyrden fordeles på flere maskiner.

Partisjonering av dataen gjør det mulig å lese et topic i parallell, gjennom at flere konsumenter samles i en konsumentgruppe. Når dette gjøres vil hver partisjon bli tildelt til en konsument.

Det er viktig å få med seg at en konsument kan lese fra flere partisjoner (dersom det er flere partisjoner enn konsumenter), men en partisjon kan alltid bare leses av en konsument. Det betyr at hvor mye som maksimalt kan leses i parallell er bestemt av hvor mange partisjoner som er i et topic.

Hvor mange partisjoner som brukes burde derfor konfigureres basert på forventet load (selv om det er mulig å legge til partisjoner senere).

«I Kafka er løsningen på dette å bruke partisjonsnøkler.»

#5: Datahistorikk

Å dele opp topics i partisjoner har også konsekvenser for hvilken rekkefølge eventer leses i.

Du husker kanskje at jeg nevnte at loggen lever inne i en partisjon? En konsekvens av dette er at rekkefølgen av eventer i utgangspunktet bare er bevart innad i partisjonen. Hva gjør du da, dersom du ønsker at visse eventer alltid skal leses i samme rekkefølge?

I Kafka er løsningen på dette å bruke partisjonsnøkler. Dette er nøkler som du kan legge til hvert event, og som så bestemmer hvilken partisjon eventet havner i. Da vil alle eventer med samme partisjonsnøkkel være garantert å havne i samme partisjon. Hva som passer å bruke som partisjonsnøkkel er avhengig av use case, og kan for eksempel være ID’en til objektet som er lagret i eventet, eposten til brukeren som eier objektet eller noe annet som binder sammen eventene.

Forhåpentligvis har denne artikkelen gitt deg et godt grunnlag for å utforske Kafka videre og forstå hvorfor det er så populært i dagens datadrevne verden. Med begrepene logg, topics, partisjoner, produsenter og konsumenter friskt i minnet, er du klar til å utforske Kafka-landskapet i dybden og dra nytte av dens kraftige funksjonalitet. Videre anbefaler jeg å prøve å sette opp Kafka selv og publisere noen enkle meldinger og å utforske Kafka’s store økosystem av hjelpeverktøy.