Kafka-Replikationskonfiguration: Sicherstellung von Datenbeständigkeit und Verfügbarkeit

Konfigurieren Sie Kafka-Replikation, ISR, Producer-Bestätigungen und Rack-Awareness, ohne die Beständigkeit zu schwächen.

Kafka-Replikationskonfiguration: Sicherstellung von Datenbeständigkeit und Verfügbarkeit

Die Kafka-Replikationskonfiguration ist der Punkt, an dem ein Cluster aufhört, ein Haufen von Brokern zu sein, und sich wie ein System verhält, dem Sie bei Ausfällen vertrauen können. Die Einstellungen sind an sich nicht kompliziert: Replikationsfaktor, In-Sync-Replicas, Producer-Bestätigungen, Leader-Wahl und Rack-Platzierung. Das Knifflige ist, dass sie nur zusammen Sinn ergeben.

Ein Thema mit drei Replikaten kann dennoch bestätigte Daten verlieren, wenn Producer schwache Bestätigungen verwenden. Ein Producer mit acks=all kann dennoch Schreibvorgänge fehlschlagen lassen, wenn min.insync.replicas für die Anzahl der derzeit aktiven Broker zu streng ist. Ein Cluster, das über Verfügbarkeitszonen verteilt ist, kann dennoch einen schlechten Tag haben, wenn alle Replikate einer heißen Partition in derselben Ausfall-Domäne landen. Replikation ist kein einzelnes Kontrollkästchen.

Die Art, wie ich über Kafka-Replikation denke, ist einfach: Für jede Partition behält Kafka mehrere Kopien, wählt eine Kopie aus, die Lese- und Schreibvorgänge akzeptiert, und hält die anderen Kopien nah genug, dass eine von ihnen übernehmen kann. Ihre Aufgabe ist es zu entscheiden, wie viele Kopien ausreichen, wie viele auf dem neuesten Stand sein müssen, bevor ein Schreibvorgang als erfolgreich gilt, und ob der Cluster jemals Verfügbarkeit über Datensicherheit bevorzugen sollte.

Ein Kafka-Thema ist in Partitionen unterteilt. Jede Partition hat ein Leader-Replikat und null oder mehrere Follower-Replikate. Producer schreiben an den Leader. Verbraucher lesen normalerweise vom Leader. Follower holen Datensätze vom Leader und halten ihre lokalen Logs synchron. Wenn der Broker des Leaders ausfällt, wählt Kafka einen neuen Leader aus Replikaten aus, die als sichere Kandidaten gelten.

Diese Liste sicherer Kandidaten ist das ISR, kurz für In-Sync-Replicas. Ein Replikat ist im ISR, wenn es gemäß den Kafka-Replikat-Verzögerungsregeln eng genug mit dem Leader Schritt hält. Wenn ein Follower das Abrufen einstellt, zu lange zurückfällt oder der Broker verschwindet, entfernt Kafka ihn aus dem ISR. Wenn er aufholt, kann er wieder beitreten.

Dieses Detail ist wichtig, weil das ISR das ist, was die Kafka-Beständigkeit mehr als nur Wunschdenken macht. Mit acks=all bestätigt der Leader eine Produktionsanfrage erst, wenn der Datensatz auf die erforderlichen In-Sync-Replicas repliziert wurde. Die genaue Anforderung wird durch min.insync.replicas gesteuert. Wenn das Thema replication.factor=3 und min.insync.replicas=2 hat, verlangt Kafka mindestens zwei In-Sync-Replicas, bevor ein acks=all-Schreibvorgang erfolgreich sein kann.

Diese Kombination ist in der Produktion üblich, weil sie eine praktische Balance bietet. Ein Broker kann ausfallen, und das Thema kann weiterhin stark bestätigte Schreibvorgänge akzeptieren. Wenn ein zweiter Broker ausfällt, bevor der erste zurückkommt, sollten Producer, die acks=all verwenden, Fehler wie NotEnoughReplicas oder NotEnoughReplicasAfterAppend sehen. Das ist während eines Vorfalls ärgerlich, aber normalerweise das richtige Verhalten. Kafka weigert sich, so zu tun, als ob ein Schreibvorgang beständig wäre, wenn nicht genügend sichere Kopien vorhanden sind.

Hier ist die typische Produktionsbasislinie für einen normalen Cluster mit drei oder mehr Brokern:

default.replication.factor=3
min.insync.replicas=2
unclean.leader.election.enable=false

Diese Werte machen nicht automatisch jede Arbeitslast sicher, aber sie geben Ihnen einen vernünftigen Ausgangspunkt. default.replication.factor=3 bedeutet, dass neue Themen drei Kopien erhalten, sofern der Themen-Erstellungsbefehl nichts anderes sagt. min.insync.replicas=2 bedeutet, dass mindestens zwei Replikate für starke Schreibvorgänge synchron sein müssen. unclean.leader.election.enable=false weist Kafka an, kein veraltetes Replikat als Leader zu wählen, nur um eine Partition beschreibbar zu halten.

Setzen Sie den Replikationsfaktor nicht höher als Ihre Broker-Anzahl. Kafka kann drei Replikate nicht auf drei verschiedene Broker platzieren, wenn nur zwei Broker existieren. In kleinen Entwicklungsumgebungen ist replication.factor=1 in Ordnung, weil Bequemlichkeit wichtiger ist als Ausfalltoleranz. In der Produktion bedeutet 1, dass ein einzelner Broker-Ausfall Daten unverfügbar machen und dauerhaft Datensätze verlieren kann, die nur auf diesem Broker gespeichert sind.

Die Producer-Seite muss mit der Themen-Seite übereinstimmen. Für wichtige Daten verwenden Sie acks=all. Aktivieren Sie auch Idempotenz, es sei denn, Sie haben einen bestimmten Grund dagegen. In modernen Kafka-Clients sind idempotente Producer die normale Wahl, um durch Wiederholungen verursachte Duplikate zu reduzieren.

acks=all
enable.idempotence=true
retries=2147483647
max.in.flight.requests.per.connection=5

Kopieren Sie den Wiederholungswert nicht blind in jeden Client, ohne Ihre Client-Version und Lieferanforderungen zu verstehen. Die wichtige Idee ist, dass beständige Kafka-Produktion normalerweise Wiederholungen, Idempotenz und acks=all zusammen benötigt. Wenn Sie acks=1 setzen, kann der Leader einen Datensatz bestätigen, bevor Follower ihn kopiert haben. Wenn dieser Leader zum falschen Zeitpunkt ausfällt, kann ein bestätigter Datensatz verschwinden. Das ist für einige Telemetrie-Streams akzeptabel. Es ist nicht akzeptabel für Zahlungen, Audit-Trails, Bestandsbewegungen oder alles, was ein nachgelagertes Team als Quelle der Wahrheit betrachtet.

Wenn Sie ein Thema erstellen, legen Sie die Replikationsentscheidungen bewusst fest, anstatt sich auf die Broker-Standardwerte zu verlassen:

kafka-topics.sh --create   --bootstrap-server broker1:9092   --topic orders.v1   --partitions 12   --replication-factor 3   --config min.insync.replicas=2

Die Partitionsanzahl ist getrennt von der Replikation. Zwölf Partitionen mit Replikationsfaktor drei bedeuten insgesamt 36 Partitionsreplikate. Das hat Speicher-, Netzwerk-, Dateihandle- und Controller-Metadatenkosten. Replikation verbessert die Beständigkeit, ist aber nicht kostenlos.

Für bestehende Themen ist das Ändern von min.insync.replicas einfach:

kafka-configs.sh --alter   --bootstrap-server broker1:9092   --entity-type topics   --entity-name orders.v1   --add-config min.insync.replicas=2

Das Ändern des Replikationsfaktors für ein bestehendes Thema hängt von der Kafka-Version und den Werkzeugen ab. Neuere Kafka-Versionen unterstützen kafka-reassign-partitions.sh und in einigen Fällen Themenänderungs-Workflows, die Erhöhungen erleichtern. In älteren Clustern bedeutet eine Erhöhung der Replikation normalerweise das Erstellen und Ausführen eines Partitions-Neuverteilungsplans. Eine Verringerung der Replikation ist empfindlicher, da Sie Kopien entfernen. Behandeln Sie es als geplanten Vorgang, nicht als beiläufigen Befehl während eines lauten Vorfalls.

Eine Neuverteilung sollte gedrosselt werden, wenn das Thema groß oder der Cluster bereits ausgelastet ist. Das Nachziehen der Replikation liest alte Daten von vorhandenen Replikaten und schreibt sie auf neue. Das kann Festplatten- und Netzwerkkapazität von laufenden Produzenten und Verbrauchern stehlen. Ein sicheres Runbook enthält normalerweise ein Wartungsfenster, eine Vorher-Nachher---describe-Ausgabe, Neuverteilungs-Drosseln und einen Rollback-Plan.

Sie können ein Thema wie folgt überprüfen:

kafka-topics.sh --describe   --bootstrap-server broker1:9092   --topic orders.v1

Achten Sie auf drei Felder in der Ausgabe: Leader, Replicas und Isr. Replicas ist die zugewiesene Menge. Isr ist die Menge, die derzeit auf dem neuesten Stand ist. Wenn Replicas 1,2,3 ist, aber Isr 1,2 ist, ist Broker 3 für diese Partition zurück oder nicht verfügbar. Wenn viele Partitionen einen fehlenden Broker im ISR zeigen, überprüfen Sie die Festplatte, das Netzwerk, die Prozessgesundheit und die Logs dieses Brokers. Wenn nur wenige heiße Partitionen betroffen sind, ist der Leader möglicherweise überlastet oder die Partition hat ungewöhnlich hohen Datenverkehr.

Unclean Leader Election verdient besondere Aufmerksamkeit. Wenn alle In-Sync-Replicas einer Partition verschwunden sind, hat Kafka zwei Möglichkeiten. Es kann die Partition unverfügbar lassen, bis ein sicheres Replikat zurückkehrt, oder es kann ein nicht synchrones Replikat wählen und riskieren, Datensätze zu verlieren, die auf dem alten Leader bestätigt wurden. unclean.leader.election.enable=false wählt Sicherheit. true wählt Verfügbarkeit auf Kosten von Datenverlust.

Es gibt Arbeitslasten, bei denen eine unreine Wahl verteidigbar sein könnte: kurzlebige Clickstream-Daten, wegwerfbare Metriken oder eine Pipeline, bei der vorgelagerte Systeme alles wiederholen können. Für die meisten Geschäftsdaten lassen Sie es deaktiviert. Die Verfügbarkeit einer Partition zu verlieren ist schmerzhaft, aber stiller Datenverlust ist schlimmer, weil Verbraucher weitermachen können, als ob nichts passiert wäre.

Rack-bewusste Replikation hilft bei einer anderen Art von Ausfall. Wenn Ihre Broker auf Racks, Zonen oder Hosts mit gemeinsamen Strom-/Netzwerkpfaden verteilt sind, teilen Sie Kafka mit, wo jeder Broker lebt:

broker.rack=zone-a

Setzen Sie den korrekten Wert auf jedem Broker. Kafka wird versuchen, Replikate über Racks zu verteilen, sodass ein einzelner Zonenausfall weniger wahrscheinlich jede Kopie einer Partition entfernt. Das ist keine Magie. Sie brauchen immer noch genügend Broker in jeder Zone, genügend Speicherplatz und eine sorgfältige Partitionsplatzierung. Aber ohne broker.rack hat Kafka keine Möglichkeit zu wissen, dass zwei Broker dieselbe Ausfall-Domäne teilen.

Überwachen Sie die Replikation kontinuierlich. Die nützlichsten Frühwarnzeichen sind unter-replizierte Partitionen, offline Partitionen, ISR-Schrumpfungsereignisse und Produktionsfehler im Zusammenhang mit unzureichenden Replikaten. In Prometheus-basierten Setups beobachten Teams häufig Kafka-Broker-Metriken für unter-replizierte Partitionen und offline Partitionen und kombinieren diese Alarme dann mit Broker-Festplatten-, Netzwerk- und JVM-Metriken.

Eine gute Frage bei einem Vorfall ist: Ist das ISR geschrumpft, weil ein Broker ausgefallen ist, weil die Replikation nicht Schritt halten kann oder weil das Netzwerk unzuverlässig ist? Die Behebung unterscheidet sich. Ein toter Broker benötigt Service-Wiederherstellung. Ein langsamer Broker benötigt möglicherweise Festplattenaustausch, I/O-Untersuchung oder weniger Partitions-Leader. Ein Netzwerkproblem kann sich als wiederholte Trennungen und Fetcher-Verzögerung zeigen, selbst wenn CPU und Festplatte in Ordnung aussehen.

Rollierende Broker-Neustarts sind ein weiterer Bereich, in dem Replikationseinstellungen ihren Wert zeigen. Starten Sie einen Broker nach dem anderen neu. Warten Sie, bis Partitionen ein gesundes ISR wiedererlangt haben, bevor Sie den nächsten Broker neu starten. Wenn Sie Broker zu schnell mit min.insync.replicas=2 neu starten, können Producer fehlschlagen, weil zu wenige Replikate synchron sind. Dieser Fehler ist erwartet, aber Sie können ihn mit Geduld und Überwachung vermeiden.

Die praktische Checkliste ist kurz. Verwenden Sie Replikationsfaktor drei für die meisten Produktionsthemen. Verwenden Sie min.insync.replicas=2 mit Producer acks=all für wichtige Daten. Halten Sie Unclean Leader Election deaktiviert, es sei denn, die Daten sind ausdrücklich wegwerfbar. Verteilen Sie Replikate über Ausfall-Domänen mit Rack-Awareness. Überwachen Sie die ISR-Gesundheit, nicht nur die Broker-Betriebszeit. Und testen Sie Ihre Annahmen, indem Sie einen Broker in einem kontrollierten Fenster neu starten, bevor ein echter Ausfall es für Sie tut.

Ein Detail, das bei Überprüfungen hilft, ist die Trennung von Beständigkeit und Verfügbarkeit in einfacher Sprache. Beständigkeit fragt: "Nachdem Kafka gesagt hat, dass der Schreibvorgang erfolgreich war, wie viele Ausfälle können passieren, bevor dieser bestätigte Datensatz gefährdet ist?" Verfügbarkeit fragt: "Können Produzenten und Verbraucher die Partition jetzt noch nutzen?" Starke Einstellungen reduzieren manchmal die Verfügbarkeit, weil Kafka Schreibvorgänge ablehnt, anstatt schwach replizierte Daten zu akzeptieren. Das ist kein Versagen von Kafka. Das ist Kafka, der den von Ihnen konfigurierten Vertrag einhält.

Stellen Sie sich zum Beispiel ein Thema mit Replikationsfaktor drei, min.insync.replicas=2 und Produzenten mit acks=all vor. Broker 1 ist Leader, Broker 2 und 3 sind Follower. Wenn Broker 3 ausfällt, wird ISR zu 1,2. Schreibvorgänge sind immer noch erfolgreich, weil zwei Replikate synchron sind. Wenn Broker 2 dann ausfällt, bevor Broker 3 zurückkehrt, wird ISR nur 1. Schreibvorgänge schlagen fehl. Einige Teams sehen dies zum ersten Mal in der Produktion und fragen, warum Kafka ausgefallen ist, obwohl der Leader noch lebt. Die Antwort ist, dass das Thema für einige Lesevorgänge noch verfügbar ist, aber nicht sicher für stark bestätigte Schreibvorgänge.

Sie sollten auch über die Wiederherstellung von Verbrauchern nachdenken. Replikation schützt Broker-seitige Kopien von Datensätzen. Sie schützt nicht automatisch Verbraucher-Offsets vor jedem Workflow-Fehler. Verbraucher-Offsets werden auch in Kafka gespeichert, normalerweise in __consumer_offsets, daher benötigt auch dieses interne Thema eine gesunde Replikation. Wenn die Benutzerthemen sorgfältig konfiguriert sind, aber interne Themen mit schwacher Replikation in einem frühen Cluster-Build erstellt wurden, kann das Failover-Verhalten dennoch schlechter sein als erwartet. Überprüfen Sie die Replikation interner Themen als Teil einer Produktionsbereitschaftsüberprüfung.

In Multi-Tenant-Clustern verdient nicht jedes Thema die gleiche Konfiguration. Ein Wegwerf-Metriken-Thema mit hohem Volumen und geringem Geschäftswert kann kürzere Aufbewahrung verwenden und schwächere Garantien tolerieren. Ein Abrechnungsthema sollte das nicht. Der Fehler besteht darin, dass zufällige Standardwerte diese Unterscheidung treffen. Legen Sie Themenklassen schriftlich fest: kritische Ereignisströme, wiederholbare Telemetrie, kompakte Zustandsthemen, temporäre Entwicklungsthemen. Ordnen Sie dann jede Klasse Replikation, ISR, Aufbewahrung und Producer-Einstellungen zu.

Vermeiden Sie es während Vorfällen, Beständigkeitseinstellungen zu ändern, nur um Fehler zu unterdrücken, es sei denn, jeder versteht den Kompromiss. Die Senkung von min.insync.replicas von 2 auf 1 kann Produzenten wieder in Gang bringen, aber es bedeutet auch, dass bestätigte Schreibvorgänge auf einem einzigen Broker leben können. Die Aktivierung von Unclean Leader Election kann die Partitionsverfügbarkeit wiederherstellen, aber veraltete Replikate können Datensätze verlieren. Manchmal kann das Unternehmen diesen Kompromiss wählen. Es sollte eine bewusste Vorfallsentscheidung sein, keine versteckte Operator-Abkürzung.