Die Kafka-Architektur erklärt: Kernkomponenten und ihre Rollen

Erkunden Sie die grundlegenden Bausteine der verteilten Event-Streaming-Architektur von Apache Kafka. Dieser Leitfaden erläutert deutlich die Rollen von Kafka Brokern, Topics, Partitionen, Producern, Consumern und die Koordinationsrolle von ZooKeeper. Erfahren Sie, wie diese Komponenten zusammenwirken, um einen hohen Durchsatz und eine fehlertolerante Datenverarbeitung und -speicherung zu gewährleisten – ein unverzichtbares Wissen für jede Kafka-Implementierung.

Kafka-Architektur erklärt: Kernkomponenten und ihre Rollen

Die Kafka-Architektur kann auf den ersten Blick verwirrend wirken, da dasselbe System Speicherung, Streaming, Replikation und den Fortschritt der Konsumenten verwaltet. Sobald man die Hauptteile trennt, wird das Modell viel einfacher: Produzenten schreiben Datensätze in Topic-Partitionen, Broker speichern diese Partitionen und Konsumenten lesen Datensätze anhand des Offsets.

Dieser Leitfaden erklärt die Kernkomponenten von Kafka und wie sie in einem echten Cluster zusammenarbeiten.

Broker: Die Kafka-Server

Ein Kafka-Cluster besteht aus einem oder mehreren Brokern. Ein Broker ist ein Kafka-Server, der Partitionsdaten speichert und Client-Anfragen von Produzenten und Konsumenten bearbeitet.

Wenn ein Produzent einen Datensatz sendet, schreibt er auf den Broker, der derzeit die Zielpartition führt. Wenn ein Konsument Datensätze liest, holt er sie von dem Broker, der diese Partition bedient. In normalen Setups verwaltet jeder Broker viele Partitionen vieler Topics.

Das Hinzufügen von Brokern kann die Speicherkapazität erhöhen und den Datenverkehr verteilen, behebt aber nicht automatisch jeden Engpass. Sie benötigen auch genügend Partitionen, eine ausgewogene Replikatplatzierung, gesunde Festplatten und ausreichende Netzwerkkapazität.

Topics: Benannte Datenströme von Datensätzen

Ein Topic ist ein benannter Datenstrom von Datensätzen, wie orders, payments oder user_activity. Produzenten schreiben in Topics und Konsumenten abonnieren Topics.

Ein Topic ist in Partitionen unterteilt. Jede Partition ist ein geordnetes, nur-anhängbares Log. Kafka garantiert die Reihenfolge der Datensätze innerhalb einer einzelnen Partition, nicht über das gesamte Topic hinweg.

Dieses Detail ist wichtig. Wenn alle Ereignisse für einen Kunden in der richtigen Reihenfolge verarbeitet werden müssen, verwenden Sie einen stabilen Schlüssel wie customer_id. Der Standard-Partitionierer von Kafka verwendet den Schlüssel, um eine Partition auszuwählen, sodass Datensätze mit demselben Schlüssel normalerweise in dieselbe Partition gelangen.

Partitionen und Offsets

Jeder Datensatz in einer Partition erhält einen Offset. Der Offset ist eine Nummer, die die Position des Datensatzes in dieser Partition identifiziert.

Ein Topic namens orders mit drei Partitionen könnte beispielsweise so aussehen:

orders-0: offset 0, offset 1, offset 2
orders-1: offset 0, offset 1
orders-2: offset 0, offset 1, offset 2, offset 3

Offsets sind nur innerhalb ihrer eigenen Partition sinnvoll. Offset 3 in orders-2 steht in keinem Zusammenhang mit Offset 3 in einer anderen Partition.

Partitionen verleihen Kafka Parallelität. Mehr Partitionen ermöglichen es mehr Konsumenten in derselben Konsumentengruppe, gleichzeitig zu arbeiten, bis zu einem aktiven Konsumenten pro Partition innerhalb dieser Gruppe.

Replikation und Leader

Kafka verwendet Replikation, um Daten verfügbar zu halten, wenn ein Broker ausfällt. Jede Partition kann mehrere Replikate auf verschiedenen Brokern haben.

Ein Replikat ist der Leader. Produzenten und Konsumenten kommunizieren normalerweise mit dem Leader für diese Partition. Die anderen Replikate sind Follower. Follower kopieren Daten vom Leader und sind bereit, die Führung zu übernehmen, wenn der Leader ausfällt.

Der Replikationsfaktor steuert, wie viele Kopien Kafka behält. Ein Replikationsfaktor von 3 bedeutet, dass Kafka drei Kopien jeder Partition auf drei Brokern speichert, wenn genügend Broker verfügbar sind.

Sie können ein Topic wie folgt erstellen:

kafka-topics.sh --create \
  --topic user_activity \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 3

Dieser Befehl erfordert einen Cluster mit mindestens drei Brokern. In einem lokalen Setup mit einem einzelnen Broker verwenden Sie einen Replikationsfaktor von 1.

Produzenten: Anwendungen, die Ereignisse schreiben

Produzenten senden Datensätze an Kafka-Topics. Ein Datensatz kann einen Schlüssel, einen Wert, einen Zeitstempel und Header enthalten.

Der Produzent fragt zunächst den Cluster nach Metadaten, um zu erfahren, welcher Broker jede Partition führt. Dann sendet er die Datensätze direkt an den richtigen Broker.

Die Zuverlässigkeit des Produzenten hängt stark von Einstellungen ab wie:

Einstellung Auswirkung
acks Wie viele Broker-Bestätigungen erforderlich sind, bevor ein Schreibvorgang als erfolgreich gilt
retries Ob der Produzent vorübergehende Fehler wiederholt
enable.idempotence Hilft, durch Produzenten-Wiederholungen verursachte Duplikate zu vermeiden
compression.type Reduziert Netzwerk- und Festplattennutzung für viele Workloads

Für wichtige Daten ist acks=all üblich, da der Leader auf synchronisierte Replikate wartet, bevor er den Schreibvorgang bestätigt. Das genaue Verhalten hängt auch von Broker-Einstellungen wie min.insync.replicas ab.

Konsumenten und Konsumentengruppen

Konsumenten lesen Datensätze aus Topics. Die meisten Produktionskonsumenten laufen innerhalb einer Konsumentengruppe.

Innerhalb einer Konsumentengruppe weist Kafka jede Partition nur einem aktiven Konsumenten gleichzeitig zu. So ermöglicht Kafka die Skalierung der Verarbeitung unter Beibehaltung der Reihenfolge innerhalb jeder Partition.

Wenn orders beispielsweise drei Partitionen hat und Ihr Dienst drei Konsumenten in derselben Gruppe, kann jeder Konsument eine Partition verarbeiten. Wenn Sie einen vierten Konsumenten zur selben Gruppe hinzufügen, wird ein Konsument untätig bleiben, da nur drei Partitionen zugewiesen werden können.

Verschiedene Konsumentengruppen erhalten unabhängige Lesezugriffe. Ihr Abrechnungsdienst und Ihr Analysedienst können beide das orders-Topic lesen, ohne sich gegenseitig Datensätze wegzunehmen.

Offsets und Konsumentenfortschritt

Konsumenten verfolgen den Fortschritt, indem sie Offsets committen. Kafka speichert committete Offsets für Konsumentengruppen in einem internen Topic namens __consumer_offsets.

Wenn ein Konsument abstürzt und neu startet, verwendet er den committeten Offset, um fortzufahren. Der Zeitpunkt des Commits beeinflusst das Verarbeitungsverhalten:

Commit-Zeitpunkt Mögliches Ergebnis
Commit vor Abschluss der Verarbeitung Ein Absturz kann Datensätze überspringen
Commit nach Abschluss der Verarbeitung Ein Absturz kann Datensätze erneut verarbeiten

Viele Systeme wählen die At-Least-Once-Verarbeitung: Verarbeiten Sie den Datensatz, dann committen Sie den Offset. Dies kann nach einem Absturz zu Duplikaten führen, daher sollten nachgelagerte Schreibvorgänge nach Möglichkeit idempotent sein.

Cluster-Metadaten: ZooKeeper und KRaft

Ältere Kafka-Cluster verwenden Apache ZooKeeper zur Verwaltung von Cluster-Metadaten und Controller-Wahlen. Viele bestehende Installationen laufen noch auf diese Weise.

Neuere Kafka-Bereitstellungen können den KRaft-Modus verwenden, Kafkas integriertes Metadaten-Quorum. In KRaft-Clustern ist Kafka nicht mehr auf ZooKeeper für die Metadatenverwaltung angewiesen.

Wenn Sie ältere Kafka-Tutorials lesen, prüfen Sie, ob sie ZooKeeper oder KRaft voraussetzen. Befehle, Konfigurationsdateien und Betriebsschritte können unterschiedlich sein.

Wie ein Datensatz Kafka durchläuft

Ein typischer Schreib- und Leseablauf sieht wie folgt aus:

  1. Ein Produzent verbindet sich mit einem Bootstrap-Broker und holt Metadaten.
  2. Der Produzent wählt basierend auf dem Datensatzschlüssel oder der Partitionierungsstrategie eine Partition aus.
  3. Der Produzent sendet den Datensatz an den Leader-Broker für diese Partition.
  4. Der Leader hängt den Datensatz an sein Log an und Follower replizieren ihn.
  5. Der Leader bestätigt den Schreibvorgang basierend auf der acks-Einstellung des Produzenten.
  6. Ein Konsument pollt die Partition und empfängt Datensätze ab seinem aktuellen Offset.
  7. Der Konsument verarbeitet Datensätze und committed Offsets für seine Konsumentengruppe.

Dieser Ablauf erklärt, warum Kafka sowohl Echtzeitverarbeitung als auch Wiedergabe unterstützen kann. Konsumenten entfernen keine Datensätze, wenn sie sie lesen.

Aufbewahrung: Kafka behält Daten nach Richtlinien

Kafka ist keine traditionelle Warteschlange, in der eine Nachricht verschwindet, sobald ein Konsument sie liest. Kafka behält Datensätze basierend auf Aufbewahrungseinstellungen.

Häufige Topic-Einstellungen umfassen:

retention.ms=604800000
retention.bytes=10737418240

retention.ms steuert die zeitbasierte Aufbewahrung. retention.bytes steuert die größenbasierte Aufbewahrung. Die tatsächliche Bereinigung hängt auch von Segment-Einstellungen und der Broker-Konfiguration ab.

Einige Topics verwenden Log-Kompaktierung anstelle von oder zusätzlich zur löschbasierten Aufbewahrung. Die Kompaktierung behält den neuesten Wert für jeden Schlüssel, was für zustandsähnliche Topics wie Benutzerprofile oder Konfigurationsänderungen nützlich ist.

Was Sie sich merken sollten

Kafkas Architektur basiert auf partitionierten Logs. Broker speichern Partitionen, Produzenten schreiben auf Partitions-Leader, Konsumenten lesen nach Offset, und Konsumentengruppen verteilen die Arbeit auf Partitionen.

Wenn Sie ein Kafka-Topic entwerfen, denken Sie an Reihenfolge, Partitionsanzahl, Replikationsfaktor, Aufbewahrung und das Verhalten der Konsumentengruppe. Diese Entscheidungen prägen, wie Ihr System skaliert, sich von Fehlern erholt und alte Ereignisse wiedergibt.