Von David Hagens auf Dienstag, 16. März 2021
Kategorie: Data Management

Apache Kafka in a Nutshell

Vielleicht haben Sie bereits von Apache Kafka gehört. Immerhin wird Kafka (laut eigener Aussage) in über 80% der 'Fortune-100'-Firmen eingesetzt. Doch was ist Kafka überhaupt?

Im Folgenden möchte ich versuchen diese Frage zu beantworten. Dabei gehe ich lediglich auf die fachlichen und technischen Grundlagen ein. Eine Installationsanleitung wird es in diesem Post daher nicht geben. Dafür empfehle ich an dieser Stelle den Quickstart-Guide unter https://kafka.apache.org/quickstart.

Was ist Kafka? 

Apache Kafka ist eine Event-Streaming-Plattform.

Gut, da die Frage jetzt also geklärt ist, wünsche ich noch einen schönen Tag.

Naja, okay, ich schätze die Erklärung ist etwas unzureichend. Was ist also eine Event-Streaming-Plattform? Und stimmt das überhaupt? Ich hatte da schon mal etwas anderes gelesen...
Um die zweite Frage vorweg zu nehmen: Es gibt Quellen, die Kafka nicht als Event-Streaming-Plattform sondern als Messaging-Plattform oder als Message Queue bezeichnen. Grundsätzlich lässt sich dies schon vergleichen, meiner Meinung nach passt der Begriff Event-Streaming-Plattform aber etwas besser, und die Dokumentation bezeichnet Kafka auch als solche.

Was ist eine Event-Streaming-Plattform? 


Zur ersten Frage, was eine Event-Streaming-Plattform ist, lässt sich folgendes sagen:

Eine Event-Streaming-Plattform besteht - schon am Namen erkennbar - aus drei Komponenten:

  1. Das Event
  2. Das Streaming
  3. Die Plattform

Um zu verstehen, was eine Event-Streaming-Plattform ist, müssen diese drei Komponenten geklärt werden.

Fangen wird also mit der ersten Komponente an:

Das Event

Das Event ist die minimale Dateneinheit. Es stellt einen Fakt dar, ist also unveränderlich, aber auch an den Zeitpunkt gebunden, an dem es erstellt wurde. Ein Event stellt somit immer die zu diesem Zeitpunkt geltende Wahrheit dar, kann aber durch ein neues Event widerlegt werden. Dies lässt sich zum Beispiel mit dem Ablesen eines Temperatursensors vergleichen. Wenn Sie um 11 Uhr ablesen, dass es draußen 10 Grad sind, ist dies an den Zeitpunkt gebunden. Wenn Sie eine Stunde später wieder auf das Thermometer schauen und es dann 15 Grad anzeigt, ändert das nichts daran, dass um 11 Uhr 10 Grad gemessen wurden. Das Event stellt in diesem Fall also die Aufzeichnung der Temperatur (10 Grad um 11 Uhr) dar und wird eine Stunde später durch ein weiteres Event erweitert (15 Grad um 12 Uhr). Beide Events stellen aber korrekte Aufzeichnungen dar.

Vieles kann als Event dargestellt werden. Als beliebtes Beispiel wird oft Twitter herangezogen. Ein Tweet ist dabei ein Event, das sollte offensichtlich sein. Interaktionen von Usern können aber auch in Events abgebildet werden. Wenn ein Nutzer einem anderen Nutzer folgt, dann stellt dies ein Event dar und ist damit ein Fakt. Wenn der Nutzer dem anderen Nutzer dann nicht mehr folgt, würde man in der relationalen Welt vermutlich einen Wert in der Datenbank löschen. In der Event-basierten Welt würde dies aber einen neuen Fakt aufstellen. Der Wahrheitsgehalt des alten Events wird dadurch nicht beeinflusst. Zum Zeitpunkt des ersten Events stimmt es ja, dass Nutzer A dem Nutzer B folgt, genauso wie es zum Zeitpunkt des zweiten Events stimmt, dass Nutzer A dem Nutzer B nun nicht mehr folgt.

Auf der technischen Seite besteht ein Event aus einem Key und einem Value sowie dem Timestamp. Zusätzlich kann ein Event weitere Metadaten enthalten. Sowohl Key als auch Value folgen keinem bestimmten Format und können zum Beispiel als JSON, Avro oder auch reinem Text vorliegen. In Kafka werden die Daten binär gespeichert, was wiederum auch heißt, dass die Clients sich um das Serialisieren und Deserialisieren der Daten kümmern müssen. Die Größe der Daten ist auch nicht beschränkt, allerdings muss beachtet werden, dass größere Daten zu einer schlechteren Performance führen können. Die standardmäßige maximale Größe für ein Event beträgt 1 MB.

Damit ist der erste Teil der Event-Streaming-Plattform kurz erklärt. Kommen wir nun zum zweiten Teil:

Das Streaming

"Stream" ist das englische Wort für Bach oder Wasserlauf. Viele kennen Streaming vermutlich eher von YouTube, Netflix oder anderen Plattformen. Für unseren Anwendungsfall passt als Übersetzung aber die des Datenstroms am besten. Ein Datenstrom ist ein kontinuierlicher Fluss an Daten. Daraus ergeben sich direkt schon drei Dinge:

  1. Der Datenstrom muss, wie ein Wasserlauf auch, aus einer Quelle kommen.
  2. Der Datenstrom muss, ebenfalls wie ein Wasserlauf, irgendwohin münden. Bei einem echten Fluss könnte das ein See sein, genauso könnte es bei einem Datenfluss einen Data-Lake geben, in dem die Daten am Ende landen.
  3. Der Datenstrom fließt ununterbrochen, ohne absehbares Ende, und kann auch unterschiedliche Lasten zu unterschiedlichen Zeiten aufweisen. Genauso wie ein echter Fluss über die Ufer treten kann, könnte ein Datenstrom zu bestimmten Zeitpunkten zu viele Daten erhalten und damit das ganze System verlangsamen. Tatsächlich kann in einem solchen System theoretisch ein Rückstau entstehen, wenn das System die Datenlast nicht schnell genug verarbeitet.

Um aus verschiedenen Events einen Strom zu erstellen, müssen wir diese Events lediglich in eine Warteschlange stellen. Wenn neue Events entstehen, werden diese einfach an die Warteschlange angehängt. Wenn Events verarbeitet werden, werden diese aus der Warteschlange genommen. Quellen und Senken/Mündungen sind also schon einmal möglich. Um unterschiedliche Lasten zu unterschiedlichen Zeiten abzufangen und generell sehr hohe Lasten aushalten zu können, muss diese Warteschlange jetzt eigentlich nur noch verteilt werden können.

In Kafka ist eine solche Warteschlange ein Topic. Events können also nach Kategorien sortiert gespeichert werden. Im oben genannten Beispiel Twitter, in dem ein Nutzer einem anderen Nutzer folgt, könnte das Topic zum Beispiel "user_following" heißen. Ein Tweet würde dann in dem Topic "tweets" landen. Wie in der relationalen Welt Daten in verschiedene Tabellen aufgeteilt werden, werden in Kafka die Events in verschiedene Topics aufgeteilt. Im Gegensatz zu einer reinen Warteschlange können Events in Kafka auch über einen Offset indexiert werden. Die Events werden hier also nicht gelöscht, wenn sie verarbeitet oder gelesen wurden. Der Offset entspricht dabei dem tatsächlichen Offset in der entsprechenden Datei, Kafka verwendet also keine aufwendigen Indexierungsmethoden. Über den Key des Events kann hingegen nicht indexiert werden.

Zur fertigen Event-Streaming-Plattform fehlt jetzt nur noch:

Die Plattform

Üblicherweise arbeitet eine Kafka-Installation auf einem Cluster aus mehreren Brokern (so wird ein Server im Kafka Umfeld bezeichnet). Die Kafka-Installation bei LinkedIn, wo Kafka ursprünglich entwickelt wurde, bestand 2019 zum Beispiel aus über 100 Clustern, betrieben auf über 4000 Brokern, welche über 100.000 Topics mit 7.000.000 Partitionen halten. Pro Tag wurden damals zu Spitzenzeiten über 7.000.000.000.000, also 7 Billionen, Events verarbeitet.

Um ein Topic auf mehrere Broker zu verteilen, wird es partitioniert. Eine Partition entspricht einer physischen Datei auf dem Broker und stellt in sich eine eigene Warteschlange für das Topic dar. Ein Topic kann damit über mehrere Broker verteilt gespeichert werden, wobei jeder Broker eine oder mehrere Partitionen speichern kann. Um zusätzliche Ausfallsicherheit herzustellen, können Partitionen auch über mehrere Broker repliziert werden. Dabei wird eine Leader-Follower-Technik angewendet, wobei der Leader alle Lese- und Schreibvorgänge übernimmt und die Follower diese Vorgänge replizieren. Wenn der Leader feststellt, dass ein Follower einen ungültigen Status sendet, oder der Follower rückständig ist, so wird dieser automatisch entfernt und ein neuer Broker übernimmt. Wenn der Leader ausfällt, suchen die restlichen Follower automatisch einen neuen Leader für die Partition aus.

Die Broker organisieren sich untereinander über Apache Zookeeper, das Kafka-Team arbeitet aber kontinuierlich daran, die Abhängigkeiten zu Zookeeper zu entfernen, sodass ein Kafka-Cluster komplett ohne Abhängigkeiten zu anderen Systemen betrieben werden kann.

Unsere fertige Plattform besteht also aus Events, welche in Topics über verschiedene Broker verteilt gespeichert werden.

Quellen und Senken

Wenn wir an den Datenstrom zurückdenken, fällt auf, dass in der Event-Streaming-Plattform bisher noch nicht über Quellen und Senken gesprochen wurde. Technisch gesehen sind diese auch kein Teil der eigentlichen Plattform, so wie ein See zum Beispiel auch nicht zu dem Fluss gehört, der in ihn mündet.

Quellen werden in Kafka als Producer und Senken werden als Consumer bezeichnet. Ein Producer schickt ein Event an einen zufälligen Broker, der typischerweise über ein Round-Robin-Verfahren ermittelt wird. Die Partition, in welcher das Event gespeichert wird, wird über den Key des Events ermittelt, oder, wenn der Key nicht vorhanden ist, zufällig ausgewählt. Events, die denselben Key verwenden, werden also immer in dasselbe Topic geschrieben. Es muss also eine geeignete Keying-Strategie entwickelt werden, damit nicht alle Events in derselben Partition landen, während die anderen Broker leer ausgehen.

Ein Consumer liest Events aus einer oder mehreren Partitionen. Damit auch die Consumer verteilt arbeiten können, gehört jeder Consumer einer Consumer Group an. In einer Consumer Group kann ein Event nur von einem Consumer gelesen werden. Jedem Consumer werden dazu eine oder mehrere Partitionen des Topics zugeteilt, wohingegen eine Partition maximal einem Consumer pro Consumer Group zugeteilt sein kann. Daraus ergibt sich, dass die maximale Anzahl an Consumern in einer Consumer Group gleich der Anzahl an Partitionen des Topics ist. Partitionen, die keine Zuordnung zu einem Consumer haben, zum Beispiel weil der entsprechende Consumer ausgefallen ist, werden unter den übrigen Consumern aufgeteilt.

Kafka Connect & Streams

Wir haben jetzt eine Event-Streaming-Plattform sowie Quellen und Senken. Um die Daten auf ihrem Weg zusätzlich noch in irgendeiner Weise zu verarbeiten, gibt es das Streams-Framework. Kafka Streams ermöglicht ein natives Stream Processing im Kafka-Ökosystem. Es stellt typische Datenverarbeitungsoperationen wie zum Beispiel Map oder Filter bereit. Anwendungen können in JVM-Sprachen entwickelt werden. Für Sprachen außerhalb der JVM gibt es teilweise Wrapper oder auch die plattformunabhängige Variante KSQL, über die über eine SQL-ähnliche Sprache Abfragen direkt auf verschiedenen Streams erstellt und verarbeitet werden können. KSQL basiert auf Kafka Streams und Kafka Streams arbeitet direkt mit der Consumer und Producer API.

Kafka Connect bietet eine einfache Möglichkeit, um verschiedene Systeme als Quellen und Senken mit Kafka zu verbinden. Beispielsweise gibt es Connectoren für relationale Datenbanken über JDBC oder Storage Systeme wie HDFS oder Amazon S3. Eine Tabelle einer relationalen Datenbank wird dabei als Changelog-Stream in Kafka gespiegelt. Jede Änderung der Tabelle entspricht also einem Event, wodurch die Tabelle nachgebaut werden kann. Kafka Streams bietet hierfür das Konzept des KTable. Auch Kafka Connect arbeitet mit dem Consumer und Producer API. Fertige Connectoren finden sich im Confluent Hub unter https://www.confluent.io/hub/.

Fazit

Apache Kafka bietet als Plattform redundantes und skalierbares Event-Streaming. Kafka funktioniert sowohl auf einem einzelnen Server als auch in riesigen Clustern mit mehreren 100 Brokern. Die Datenquellen und Senken werden in Kafka als Producer und Consumer bezeichnet, die Events in ein Topic schreiben oder aus einem Topic lesen. Zusätzlich können verschiedene Systeme über Kafka Connect angebunden werden. Eine Echtzeitdatenverarbeitung auf Stream Basis ist über das Kafka-Streams-Framework möglich. Durch Consumer Groups können auch die Anwendungen, welche ihre Daten aus Kafka beziehen, verteilt ausgeführt werden, ohne dass ein Event mehrfach verarbeitet wird.

Ich hoffe ich konnte Ihnen den Begriff der Event-Streaming-Plattform und Apache Kafka allgemein etwas näherbringen. Weitere Informationen finden Sie in den folgenden Links.

Zum Abschluss ist der Artikel für ein "in a Nutshell" vielleicht doch etwas lang geworden, aber es gibt ja auch Kokosnüsse ;-)

Weitere Informationen

Dokumentation: https://kafka.apache.org/documentation/


Apache Kafka bei LinkedIn: https://engineering.linkedin.com/blog/2019/apache-kafka-trillion-messages

Kafka Summit (verschiedene Keynotes zu Apache Kafka, aktuell Online, zumindest die Online Variante ist Kostenlos nach Registrierung): https://kafka-summit.org/

Quickstart-Guide: https://kafka.apache.org/quickstart

Beispielhafte Use-Cases: https://kafka.apache.org/uses

Kommentare hinterlassen