Wat is Kafka?

In onze laatste blog schreven we hoe we Kafka hebben toegepast voor SAP data injectie. In deze blog zullen we de werking van Kafka uitleggen en vertellen waarom het een belangrijk onderdeel is in de infrastructuur van een modern groot data landschap.

Kafka is een gedistribueerd betrouwbaar berichten systeem voor real-time verwerking van een continue berichtenstromen. Een betrouwbaar berichten systeem speelt een belangrijke rol in het verplaatsen van data tussen systemen.

Een data pijplijn zonder betrouwbaar berichten systeem lijdt tot intercommunicatie tussen verschillende data systemen over meerdere kanalen waarbij elk kanaal zijn eigen protocol en communicatie benodigd om data te verplaatsen tussen deze systemen. In kort kunnen we zeggen dat dit tot een chaos lijdt van point to point verbindingen  als we veel verschillende data systemen hebben, een dergelijk systeem is moeilijk te bouwen, te onderhouden en operationeel in de lucht te houden. Hieronder vindt u een simpele visualisatie van dit scenario als we op deze manier data zouden willen laden vanuit verschillende bronnen in een Hadoop systeem.

Om dit scenario te structureren benodigen we een centraal berichten systeem bijvoorbeeld Kafka om de man in het midden te zijn tussen deze verschillende data systemen. Dit betekend dat deze data systemen niet meer met elkaar communiceren over verschillende protocollen maar alleen met het berichten systeem communiceren over één protocol, in ons geval met Kafka. Dit reduceerd de complixiteit van de oplossing aanzienlijk omdat we ons slechts zorgen hoeven te maken over het connecteren van de data systemen aan het berichten systeem en ons geen zorgen hoeven te maken of mogelijke afhankelijkheden met andere data systemen. Dit geeft ons meer flexibiliteit omdat we eenvoudig data systemen kunnen aansluiten en afsluiten vanwege het ontbreken van afhankelijkheden.

 

Wat is Kafka ?

Kafka is een gedistribueerd berichten systeem dat voorziet in snelle, hoog schaalbare en redundante berichtenafhandeling middels een publish en subscribe model. Dit kan vergeleken worden met een abonnement op een tijdschrift waarbij er elke week of elke maand een tijdschrift bij ons thuis wordt afgeleverd. Dit is de reden waarom we spreken over een berichten systeem, immers het bericht in dit geval een tijdschrift met berichten wordt automatisch op gezette tijdstippen bij ons afgeleverd.

Kafka staat een grote hoeveelheid permante of ad-hoc consumenten of geabonneerden toe en is hoog beschikbaar en bestand tegen node fouten wanneer opgezet in een cluster en ondersteund automatisch herstel.

In de praktijk zijn deze eigenschappen van Kafka een ideaal uitgangspunt voor de communicatie en integratie van verschillende componenten van grootschalige data systemen. Kafka is in productie geimplementeerd bij duizenden bedrijven.

Terminologie

Als we spreken over Kafka wordt vaak de volgende terminologie gebruikt: topics, producers, consumers, subscribers, messaging broker, partitions en offset. Voor de eenvoud hebben we deze engelstalige terminologie hier niet direct vertaald naar het Nederlands om misverstanden te voorkomen.

Berichten in Kafka zijn georganiseerd in topics (onderwerpen)Producers (producenten) schrijven)berichten van zekere data systemen naar een topic (onderwerp)Consumers (consumenten) zijn in staat berichten te lezen van een zeker topic nadat zijn zich subscriben (aanmelden) voor dit topic, er kunnen meerdere subscribers zijn voor één topic. Kafka als een gedistribueerd berichten systeem wordt uitgevaardigd in een cluster. Elke node in een cluster wordt een messaging broker (berichten broker) genoemd.

Kafka topics kunnen verdeeld worden over partitions (partities). Deze partitions stellen ons in staat om een topic te parallellizeren door de data op te splitsen in een topic over meerdere message brokers waarbij elke partition geplaatst kan worden op een andere machine om het lezen van data door meerdere consumers van een topic in parallel mogelijk te maken.

Consumers kunnen tevens worden geparallellizeerd zodat meerdere consumers in parallel kunnen lezen van meerdere partitions in een topic voor een zeer hoge berichten doorvoer.

Voor elk bericht dat bij Kafka arriveerd wordt een unique niet muteerbare volgnummer uitgedeeld ook wel offset genoemd, dit is in principe de volgorde waarin de berichten arriveren en de offset wordt door Kafka onderhouden.

Consumers kunnen berichten lezen vanaf een specifieke offset en kunnen lezen vanaf elke offset die zij kiezen, hiermee kunnen ze zich op elk punt in tijd bij het cluster aanmelden. Gegeven deze uitgangspunten, kan elk bericht in een Kafka cluster unique geidentificeerd worden middels een tuple bestaande uit bericht topic, partition en offset binnen de partition.

Het lezen van en schrijven naar een Kafka partition kan worden worden gezien alsof het een log bestand is, nieuwe data wordt toegevoegd aan het einde van de log en consumers kunnen informatie lezen vanaf een een bepaald punt in de tijd of wel offset.

Kafka bewaard berichten voor een in te stellen periode van tijd, deze kan worden gespecificeerd worden middels de parameter log.retention.hours in de broker configuratie. Bij het verstrijken van deze periode worde de berichten gemarkeerd als verwijdert. In zo'n geval zal de consumer deze berichten verliezen als het probeerd berichten te lezen vanaf de offset die gemarkeerd is als verwijdert, er wordt verder gelezen vanaf het eerste bericht dat niet is gemarkeerd als verwijdert.

Partitions en Brokers

Elke broker kan meerdere partitions hebben en deze partitions kunnen een leader of een replica zijn voor een gegeven topic. Alle schrijf en leesacties voor een gegeven topic gaan via de leader en de leader coördineert het bijwerk proces van de replicas met nieuwe data. Als de leader faalt zal een replica deze verantwoordelijkheid overnemen en de nieuwe leader worden. 

Producers schrijven naar een enkele leader, dit voorzit in load balancing omdat elke schrijf actie kan worden gefaciliteerd door een enkele broker machine in het cluster. Sinds elke individuele machine verantwoordelijk is deze schrijf actie, wordt de doorvoersnelheid als geheel verhoogd.

Consumer groepen

Consumers kunnen lezen van een enkele partition, dit maakt het mogelijk om de doorvoersnelheid vergelijkbaar als bij de berichten producer. Consumers kunnen worden verenigd in consumer groepen for een gegeven topic, elke consumer binnen de groep leest van een unieke partittion en de groep als geheel consumeerd alle berichten voor het gehele topic.

Er zijn drie scenarios van toepassing voor een consumer groep:

  1. Aantal consumers = Aantal partitions - elke consumer leest berichten van exact één partition
  2. Aantal consumers > Aantal partitions - elke consumers zullen idle zijn omdat er voor hen geen partition is om van te lezen
  3. Aantal consumers < Aantal partitions - consumers zullen berichten lezen van meerdere partitions

Scenario 1 en 3 zijn hierboven afgebeeld. Consumer groep B heeft het zelde aantal consumers als partitions, elke consumer leest van exact één partition. Consumer group A heeft twee consumers met 4 partitions, elke consumer leest van 2 partitions.

Data consistentie en beschikbaarheid

Kafka garandeerd de volgende situaties ten aanzien van data consistentie en beschikbaarheid:

  1. berichten verzonden naar een topic partition worden toegevoegd aan de commit log in de volgorde waarin ze ontvangen zijn
  2. een enkele consumer instance zal berichten lezen in de volgorde waarin ze in de log zijn opgeslagen
  3. een bericht is verwerkt wanneer alle in sync replicas zijn toegepast op hun log
  4. elk verwerkt bericht kan niet verloren gaan, wanneer tenminste één replica in leven is

1 & 2 garanderen dat de berichtvolgorde wordt gehandhaafd voor elke partitie. Let op dat de bericht volgorde voor het gehele topic niet wordt gegarandeerd. 3 & 4 garanderen dat verwerkte berichten kunnen worden gelezen.

Alle garanties door Kafka gemaakt ten aanzien van data consistentie en beschikbaarheid zijn van toepassing voor de situatie waarin we de producer berichten afleverd voor één partition en een consumer berichten leest van één partition, in het geval waar we lezen vanaf dezelfde partition met twee consumers of schrijven naar dezelfde partition met twee producers zijn alle garanties van tafel.

De partition leader is verantwoordelijk voor het schrijven van het bericht naar zijn eigen replica en op het moment dat het bericht is verwerkt is hij verantwoordelijk om het bericht te door te zetten naar de additionele replicas op de overige brokers. Elke replica antwoord dat zij het bericht hebben ontvangen en kunnen nu in sync genoemd worden. Wanneer elke broker in het cluster beschikbaar is kunnen consumers en producers lezen van en schrijven naar de leading partition van een topic. Helaas is dit het zonnige scenario, leaders alswel replicas kunnen falen in de praktij en we moeten deze situatie afhandelen.

Fouten afhandelen

Wat gebeurd er als een replica faalt ? Geschreven berichten komen niet langer aan bij de replica die faalt en het zal geen berichten meer ontvangen, hiermee raakt de replica achter op de leader of met andere woorden hij raakt out of sync.

In bovenstaande scenario faalt Replica 3 eerst en ontvang niet langer de berichten van de leader, daarna faalt Replica 2 en ontvangt eveneens geen berichten meer, beiden zijn out of sync met de leader. Nu is alleen nog de leader in sync. Als in het laatste scenario de leader eveneens faalt dan hebben drie dode replicas.

Replica 1 is echter nog steeds sync, het kan dan wel geen nieuwe arriverende berichten verwerken maar het is in syn met elk bericht dat het mogelijk kon ontvangen. Replica 2 mist enige berichten en Replica 3 mist nog meer berichten.

Gegeven deze situatie zijn er twee mogelijke scenarios om dit falen af te handelen:

  1. Wachten totdat de broker van de leader weer actief is om te vervolgen met het verwerken van berichten, dit is het meest eenvoudige scenario
  2. Het kiezen van de eerste de beste broker die kan worden opgebracht als nieuwe leader

Oplossing 1: Als de broker die als leader actief was weer is opgebracht zal het weer beginnen met het ontvangen en schrijven van berichten en als de replicas weer worden opgebracht zullen deze starten met het in sync brengen van de log met de leader

Oplossing 2: In dit geval als de broker niet de leader is, dan zal de broker van de nieuwe leader zal out of sync zijn, omdat het berichten mist van de leader vanaf het moment dat het faalde. Als de overige brokers worden opgebracht, zullen deze zien dat de verwerkte berichten niet bestaan bij de nieuwe leader en zullen deze berichten verwijdert worden. Door zo snel als mogelijk voor een nieuwe leader te kiezen kunnen berichten verloren gaan, hiermee wordt echter mogelijk een langdurige downtime voorkomen door het aanwijzen van een nieuwe broker als leader.

In het geval dat de leader zelf faalt voordat het een replica kon schrijven zal de Kafka controller het verlies van de leader detecteren en een nieuwe leader kiezen uit de pool van sync replicas. Dit kan resulteren in LeaderNotAvailable fouten voor de client omdat dit proces enkele seconden kan duren. In zo'n geval zal echter geen verlies van data optreden zolang producers en consumers deze fout op de juiste wijze afhandelen en opnieuw proberen.

Consistentie als Client

Kafka clients kennen we in twee varianten:

  • Producer
  • Consumer

Beide clients kunnen worden geconfigureerd met verschillende nivos van consistentie.

Voor een producer zijn er drie mogelijke scenarios ten aanzien van de consistentie van berichten:

  1. Voor elk bericht kunnen we wachten op alle in sync replicas om het bericht te bevestigen
  2. Alleen wachten totdat de leader het bericht heeft bevestigd
  3. Niet wachten op bevestiging van berichten

Afhankelijk van de vereisten voor consistentie en doorvoer kun je kiezen wat het beste is voor jouw use case scenario.

Voor een consumer zijn er eveneens drie mogelijke scenarios waaruit we kunnen kiezen voor de consistentie van berichten:

  1. Ontvang een bericht maximaal eenmaal - At most once delivery
  2. Onvang een bericht tenminste eenmaal - At least once delivery
  3. Ontvang een bericht exact eenmaal - Exactly once delivery

At most once delivery, de consumer leest de data van een partition, verwerkt de offsets die het heeft gelezen, en verwerkt daarna het bericht. Als de consumer crasht tussen het verwerken van de offset en het verwerken van het bericht zal het starten vanaf de volgende offset zonder het bericht ooit te hebben gelezen. Dit zal zal lijden tot onacceptabel berichten verlies.

At least once, de consument leest de data ven een partitie, verwerkt het bericht, waarna het de offset verwerkt van het bericht dat verwerkt is. Als de consumer crasht in deze situatie dan zal het hetzelfde bericht opnieuw verwerken.  Dit kan tot een dubbele berichten lijden in het downstream systeem maar niet tot verlies van berichten.

Exactly once delivery wordt gegarandeerd door de consumer het bericht te laten vewerken en de output van het bericht inclusief de offset op te slaan in een transactioneel systeem. In het geval dat de consumer crasht kan het de laatste transactie lezen uit het transactionele systeem en opnieuw starten met lezen vanaf deze offset. Hiemee wordt verlies van berichten en het produceren van dubbele berichten voorkomen. Aan deze methode hangt echter een prijskaartje ten aanzien van de doorvoer snelheid van het systeem omdat elk bericht en offset als een transactie moet worden verwerkt.

In de praktijk wordt een Kafka consumer applicatie vaak toegepast met "at least once delivery" omdat het de beste trade off oplevert tussen doorvoer snelheid en juistheid van berichten. Dit betekent dat het downstream systeem het mogelijk arriveren van dubbele berichten zal moeten afhandelen.

Vergelijk van Kafka met traditionele broker

Kafka is geen traditionele berichten broker met veel functionaliteiten zoals bijvoorbeeld ActiveMQ.

  • Kafka kent geen individuele berichten id voor elk afzonderlijk bericht, maar berichten zijn uniek addresseerbaar via topic, partition en offset
  • Kafka traceert geen consumers voor een topic of wie een bericht consumeert

Vanwege deze verschillen kan Kafka optimisaties uitvoeren.

  • Kafka verlicht de belasting door geen indexen te onderhouden ten aanzien van berichten
  • Kafka kent geen deletes, alleen delete markeringen. Kafka houdt alle informatie in het logbestand voor een te specificeren tijd
  • Kafka kan efficient berichten streamen naar een consumers gebruik makende van kernel level I/O, berichten worden niet in een user space opgeslagen
  • Kafka kan gebruik maken van het operating systeem voor bestand page caches en het efficient schrijven naar disk

Conclusie

Het zal duidelijk zijn de bovengenoemde performance karakteristieken en zijn schaalbaarheid en fout tolerantie Kafka tot een excellente kandidaat maken om te gebruiken in een een big data oplossing als een betrouwbare manier om data te injecteren en grote hoeveelheden data snel te verwerken. Er zijn vele grote bedrijven die gebruik maken van Kafka voor het injecteren van hun data, één van het is Netflux die ongeveer 500 billioen events per dag verwerkt ofwel ca. 1.3 Petabyte of data.

Kakfa kan voorzien in de opslag voor domein gedreven ontwerp concepten zoals Command Query Responsible Segregation en event generatie met krachtige mechanismen om schaalbare microservices te implementeren. Event genererende applicaties zoals in het geval van de Internet of Things zijn moeilijk te implementeren middels traditionele database, een additioneel concept in Kafka genaamd log compation kan events behouden voor de levensduur van de app. Hiermee kunnen applicaties ontkoppelt worden "loosely coupled", omdat het logs can verliezen of negeren en de domein status van een log met behouden events kan terugzetten.

Moet je Kafka gebruiken? Dit is een vraag die afhankelijk is van je use case. Kafka is niet een generieke oplossing die van toepassing is op alle scenarios maar voor een zekere klasse van problemen die web-scale en enterpise bedrijven ondervinden. Als je een set van schaalbare services of applicaties wilt bouwen dan kan Kafka dienst doen als bron van de waarheid middels collectie van alle feiten of events voor een systeem.

 

Wilt u meer weten over het implementeren van Kafka binnen uw organisatie en wilt u gebruik maken van de kennis en ervaring die Scalar Data reeds heeft opgedaan met de implementatie van deze opwindende technologie voor klant oplossingen dan kunt u contact met ons opnemen, we assisteren en helpen graag bij het implementeren van Kafka in uw organisatie.

e-mail: [email protected]

telefoon: 06-30748787

 

 

Ronald Span

Founder of Scalar Data, over 20 years of experience in a variety of national and international IT projects in different roles, development, consultancy, pre-sales, management and business development. Scalar Data is helping organizations to implement their big data strategy.