KRaft w Kafce 4.0: Żegnaj ZooKeeper, kontrolerze kworum i migracja
Kafka 4.0 (marzec 2025) trwale usunęła ZooKeepera po trzech latach współpracy z KRaftem. W tym szczegółowym przewodniku wyjaśniono, jak działa nowy kontroler kworum oparty na Rafcie, Path obowiązkowej migracji dla osób pochodzących z Kafki 3.x, realnych korzyści operacyjnych i pułapek których należy unikać podczas przechodzenia do produkcji.
Problem z ZooKeeperem
Od prawie dziesięciu lat każdy klaster Apache Kafka wymagał zespołu Apache ZooKeeper oddzielne do zarządzania metadanymi: którzy brokerzy byli aktywni, który broker był liderem której partycji, tematu i metadanych ACL. ZooKeeper to system koordynacji dystrybuowane solidnie i niezawodnie, ale wprowadziło szereg istotnych problemów operacyjnych:
- Podwójna złożoność operacyjna: Każdy zespół zarządzający Kafką musiał także zarządzać oddzielnym klastrem ZooKeeper (zwykle 3 lub 5 węzłów), z własnym monitorowaniem, cyklem aktualizacji i odrębną konfiguracją.
- Ograniczona skalowalność metadanych: ZooKeeper wykazał spadek wydajności powyżej ~200 000 partycji na klaster, ponieważ metadane każdej partycji zostały zapisane jako osobne węzły ZooKeeper.
- Powolny wybór kontrolera: Kiedy kontroler brokera Kafka padł, nowy kontroler musiał odczytać liczbę całkowitą status klastra z ZooKeeper, zanim będzie mógł działać, a proces ten może zająć dziesiątki sekund w przypadku dużych klastrów.
- Trudności w odtwarzaniu po awarii: odzyskiwanie klastra Kafki w przypadku utraty danych w ZooKeeper był to złożony i ryzykowny proces ręczny.
Kalendarium KRafta
- KIP-500 (2020): Oryginalna propozycja usunięcia ZooKeepera z Kafki
- Kafka 2.8 (kwiecień 2021): pierwsza wersja z KRaftem we wczesnym dostępie (tylko do testów)
- Kafka 3.3 (październik 2022): KRaft zadeklarował gotowość produkcyjną dla nowych klastrów
- Kafka 3.5 (czerwiec 2023 r.): Dostępne jest narzędzie do migracji ZooKeeper do KRaft
- Kafki 3.7 (marzec 2024 r.): tryb ZooKeeper został wycofany
- Kafka 4.0 (marzec 2025 r.): Tryb ZooKeeper został trwale usunięty
Jak działa KRaft: Dziennik konsensusu Tratwy
Pojęcie dziennika metadanych
Rozwiązanie przyjęte w KRaft (Kafka Raft) jest eleganckie: zamiast polegać na zewnętrznym systemie metadanych,
Kafka obsługuje swoje metadane jako plik Wewnętrzny temat Kafki zwany @metadata.
Ten temat jest replikowany za pośrednictwem protokołu Raft między węzłami kontrolera.
W KRaft brokerzy klastrów przyjmują jedną z dwóch ról (lub obie w małych klastrach):
- Kontrolery: zarządza metadanymi klastra. W klastrze produkcyjnym zalecane jest kworum składające się z 3 kontrolerów. Aktywny kontroler (lider Raft) przetwarza wszystkie zmiany metadanych i replikuje je do innych kontrolerów.
- Pośrednik: zarządza dziennikami partycji, obsługuje producentów i konsumentów. Brokerzy zachowują kopię pamięć podręczna metadanych otrzymanych od kontrolera, aktualizowana podczas przesyłania strumieniowego.
Protokół tratwy w Kafce
Raft to rozproszony algorytm konsensusu zaprojektowany tak, aby był zrozumiały (w przeciwieństwie do Paxos). W skrócie: spośród wszystkich węzłów kworum wybierany jest jeden lider. Przywódca otrzymuje wszystkie pisma święte, propaguje je wśród obserwujących i gdy większość węzłów potwierdzi zapis, uważa go za popełniony.
W KRaft tłumaczy się to tak:
- Operacja na metadanych (utwórz temat, przypisz lidera partycji itp.) dociera do kontrolera lidera
- Kontroler wiodący zapisuje operację w dzienniku metadanych jako zdarzenie serializowane
- Zdarzenie jest replikowane do obserwatorów kontrolera za pośrednictwem protokołu
FETCH(wykorzystując istniejący kod Kafki) - Gdy większość kontrolerów potwierdzi (kworum), operacja zostaje zatwierdzona
- Brokerzy otrzymują aktualizacje metadanych przesyłane z aktywnego kontrolera za pośrednictwem
MetadataUpdate
# Struttura di una directory dati KRaft (broker+controller combinato)
# /var/lib/kafka/data/
/var/lib/kafka/data/
meta.properties # cluster.id, node.id, version
__cluster_metadata-0/ # il metadata log (partizione 0)
00000000000000000000.log
00000000000000000000.index
00000000000000000000.timeindex
leader-epoch-checkpoint
ordini-effettuati-0/ # log di una partizione normale
ordini-effettuati-1/
...
# meta.properties esempio:
node.id=1
version=1
cluster.id=MkU3OEVBNTcwNTJENDM2Qk
Kontroler kworum: Rozmiar
Kontroler kworum kieruje się zasadami konsensusu: tolerować f porażka, są potrzebne 2f+1 węzły.
- 3 kontrolery: toleruje 1 awarię (minimalna konfiguracja do produkcji)
- 5 kontrolerów: toleruje 2 jednoczesne awarie (zalecane dla klastrów krytycznych)
- 1 kontroler: Tylko do lokalnego rozwoju/testowania, brak odporności na błędy
Kontrolery mogą być poświęcony (tylko rola kontrolera, nie zarządzaj partycjami użytkowników) lub łączny (te same maszyny, które działają również jako brokerzy). W przypadku małych klastrów (< 10 brokerów) kontrolery razem są w porządku. W przypadku klastrów dużych lub o dużej przepustowości dedykowane kontrolery izolują obciążenie związane z zarządzaniem metadane z obciążenia we/wy partycji.
Konfiguracja klastra KRaft od podstaw
# server.properties per un nodo controller+broker combinato (cluster single-node per dev)
# ─── Identity ─────────────────────────────────────────────────────────────────
# In KRaft ogni nodo ha un node.id unico nel cluster (sostituisce broker.id)
node.id=1
# Ruoli: "broker" | "controller" | "broker,controller"
process.roles=broker,controller
# Indirizzo del quorum controller: formato node.id@host:port
controller.quorum.voters=1@localhost:9093
# ─── Listeners ────────────────────────────────────────────────────────────────
# KAFKA: listener per producer/consumer
# CONTROLLER: listener per comunicazione KRaft interna
listeners=KAFKA://localhost:9092,CONTROLLER://localhost:9093
advertised.listeners=KAFKA://localhost:9092
listener.security.protocol.map=KAFKA:PLAINTEXT,CONTROLLER:PLAINTEXT
inter.broker.listener.name=KAFKA
controller.listener.names=CONTROLLER
# ─── Storage ──────────────────────────────────────────────────────────────────
log.dirs=/var/lib/kafka/data
# ─── Replication defaults ─────────────────────────────────────────────────────
default.replication.factor=1 # 1 per dev, 3 per produzione
min.insync.replicas=1 # 1 per dev, 2 per produzione
offsets.topic.replication.factor=1
# ─── Retention ────────────────────────────────────────────────────────────────
log.retention.hours=168 # 7 giorni
log.segment.bytes=1073741824 # 1GB per segmento
# Inizializzare il cluster KRaft (una tantum)
# Step 1: generare un cluster UUID univoco
KAFKA_CLUSTER_ID=$(kafka-storage.sh random-uuid)
echo "Cluster ID: $KAFKA_CLUSTER_ID"
# Step 2: formattare la directory storage con il cluster ID
kafka-storage.sh format \
--config /etc/kafka/server.properties \
--cluster-id "$KAFKA_CLUSTER_ID"
# Output:
# Formatting /var/lib/kafka/data with metadata.version 4.0-IV3.
# Step 3: avviare il broker
kafka-server-start.sh /etc/kafka/server.properties
Ważne: Identyfikator klastra jest niezmienny
Il cluster.id generowane podczas zapisywania formatu do pliku meta.properties każdego węzła
oraz w dzienniku metadanych. Nie można go zmienić po inicjalizacji. Jeśli zgubisz ten plik i chcesz dodać plik node
do istniejącego klastra, należy zastosować odpowiednią procedurę ładowania początkowego. Przechowuj identyfikator klastra w systemie zarządzania wpisami tajnymi.
Docker Compose: Klaster KRaft na rzecz Rozwoju Lokalnego
# docker-compose.yml per cluster Kafka 4.0 KRaft (3 broker)
# Immagine: apache/kafka:4.0.0 (immagine ufficiale Apache, non Confluent)
version: "3.9"
services:
kafka1:
image: apache/kafka:4.0.0
container_name: kafka1
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: "broker,controller"
KAFKA_LISTENERS: "PLAINTEXT://kafka1:9092,CONTROLLER://kafka1:9093"
KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka1:9092"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT"
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_MIN_INSYNC_REPLICAS: 2
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
CLUSTER_ID: "MkU3OEVBNTcwNTJENDM2Qk"
volumes:
- kafka1-data:/var/lib/kafka/data
kafka2:
image: apache/kafka:4.0.0
container_name: kafka2
environment:
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: "broker,controller"
KAFKA_LISTENERS: "PLAINTEXT://kafka2:9092,CONTROLLER://kafka2:9093"
KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka2:9092"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT"
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_MIN_INSYNC_REPLICAS: 2
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
CLUSTER_ID: "MkU3OEVBNTcwNTJENDM2Qk"
volumes:
- kafka2-data:/var/lib/kafka/data
kafka3:
image: apache/kafka:4.0.0
container_name: kafka3
environment:
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: "broker,controller"
KAFKA_LISTENERS: "PLAINTEXT://kafka3:9092,CONTROLLER://kafka3:9093"
KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka3:9092"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka1:9093,2@kafka2:9093,3@kafka3:9093"
KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT"
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_MIN_INSYNC_REPLICAS: 2
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
CLUSTER_ID: "MkU3OEVBNTcwNTJENDM2Qk"
volumes:
- kafka3-data:/var/lib/kafka/data
volumes:
kafka1-data:
kafka2-data:
kafka3-data:
Migracja z Kafki 3.x z ZooKeeperem do KRaft
Jeśli zarządzasz klastrem Kafka 3.x w trybie ZooKeeper i musisz przeprowadzić migrację do KRaft (wymagana do korzystania z Kafki 4.0), proces nazywa się Migracja KRafta i jest oficjalnie wspierany od wersji 3.5. Dobra wiadomość: migracja ma miejsce bez przestojów dla producentów i konsumentów.
Fazy migracji
Oficjalny proces dzieli się na 6 etapów:
-
Sprawdź wymagania wstępne: aktualizacja do Kafki 3.7 (najnowsza wersja z obsługą podwójnego zapisu ZooKeeper+KRaft),
sprawdź, czy wszyscy brokerzy to mają
metadata.versionwyrównany. - Wdrożenie kontrolera KRaft: Uruchom węzły kontrolera KRaft (3 nowe węzły lub istniejących brokerów za pomocą dodatkowa rola). Administratorzy uzyskują początkowe metadane od ZooKeepera za pośrednictwem narzędzia do migracji.
- Tryb podwójnego zapisu: Brokerzy zapisują metadane zarówno w ZooKeeperze, jak i dzienniku metadanych KRaft. Na tym etapie system jest w pełni funkcjonalny.
- Migracja zakończona: wszyscy brokerzy migrują, ZooKeeper staje się tylko do odczytu dla Kafki. Producenci i konsumenci nie odczuwają żadnych zakłóceń.
- Finalizator ZooKeepera: Uruchom finalizator, który czyści metadane Kafki z ZooKeeper.
- Zamknięcie ZooKeepera: Likwidacja zespołu ZooKeeper. W pełni klaster KRaft.
# Step 1: Verifica metadata.version attuale del cluster
# (da eseguire con Kafka 3.7)
kafka-features.sh --bootstrap-server kafka1:9092 describe
# Output:
# Feature: metadata.version
# SupportedMinVersion: 3.0-IV1
# SupportedMaxVersion: 3.7-IV4
# FinalizedVersion: 3.7-IV4
# Step 2: Avvia i controller KRaft con la migration config speciale
# In server.properties dei controller KRaft:
process.roles=controller
zookeeper.connect=zk1:2181,zk2:2181,zk3:2181 # ancora necessario in fase di migrazione
controller.quorum.voters=10@kc1:9093,11@kc2:9093,12@kc3:9093
# Step 3: Avvia la migration (da eseguire una volta soli i controller KRaft sono up)
# Modifica server.properties di OGNI broker Kafka esistente:
# Aggiunge il parametro:
zookeeper.metadata.migration.enable=true
controller.quorum.voters=10@kc1:9093,11@kc2:9093,12@kc3:9093
# Riavvia i broker uno alla volta (rolling restart, zero downtime)
# I broker entrano in migration mode automaticamente
# Step 4: Monitora lo stato della migrazione
kafka-metadata-shell.sh \
--snapshot /var/lib/kafka/data/__cluster_metadata-0/00000000000000000000.snapshot
# Step 5: Finalizza (dopo che tutti i broker sono migrati)
kafka-features.sh --bootstrap-server kafka1:9092 upgrade \
--metadata 3.7-IV4 # o la versione target
# Step 6: Rimuovi zookeeper.connect dai server.properties e riavvia i broker
Ważne uwagi dotyczące migracji
- Nie wracaj łatwo: Po zakończeniu migracji KRaft i usunięciu ZooKeepera, wycofanie jest bardzo złożone. Najpierw przeprowadź migrację do środowiska testowego identycznego z produkcyjnym.
- Listy ACL i konfiguracje: Listy ACL i konfiguracje dynamiczne zarządzane przez ZooKeeper są migrowane automatycznie w dzienniku metadanych, ale sprawdź, czy są one obecne po migracji.
- Złącze Kafka Connect: Łączniki korzystające z klastra Kafka jako zaplecza dla stanu (group.id, offsets) nadal działają bez zmian.
- LustroMaker 2: Jeśli używasz MM2 do replikacji geograficznej, zaktualizuj klastry zdalne w tym samym okno konserwacji, aby uniknąć niezgodności wersji.
KRaft z zaawansowaną konfiguracją: Dedykowane sterowniki
W przypadku klastrów o dużej przepustowości lub zarządzających dużą liczbą partycji (>50 000) wskazane jest oddzielenie kontrolerów od brokerów (dedykowanych kontrolerów). W ten sposób operacje na metadanych (utwórz temat, wybór lidera, zmiana konfiguracji) nie konkurują ze sobą z we/wy dziennika partycji na tych samych dyskach.
# server.properties per un CONTROLLER DEDICATO (non gestisce partizioni utente)
node.id=10
process.roles=controller
controller.quorum.voters=10@kc1:9093,11@kc2:9093,12@kc3:9093
listeners=CONTROLLER://kc1:9093
listener.security.protocol.map=CONTROLLER:PLAINTEXT
controller.listener.names=CONTROLLER
log.dirs=/var/lib/kafka/metadata
# server.properties per un BROKER PURO (non è controller)
node.id=1
process.roles=broker
controller.quorum.voters=10@kc1:9093,11@kc2:9093,12@kc3:9093
listeners=KAFKA://kafka1:9092
advertised.listeners=KAFKA://kafka1:9092
listener.security.protocol.map=KAFKA:PLAINTEXT
inter.broker.listener.name=KAFKA
controller.listener.names=CONTROLLER
log.dirs=/var/lib/kafka/data
# Con questa configurazione:
# - 3 macchine controller dedicati (leggeri, poca RAM, poca CPU)
# - N broker puri (ottimizzati per I/O disco)
# - Nessuna competizione di risorse tra metadata ops e I/O partizioni
W Confluent Cloud oraz w zarządzanych środowiskach takich jak Amazon MSK (który przyjął KRaft od wersji 3.6), separacja kontrolera/brokera następuje automatycznie i jest niezauważalna dla użytkownika.
Korzyści operacyjne KRaft
Szybsze uruchamianie i odzyskiwanie
W przypadku ZooKeepera po ponownym uruchomieniu kontrolera brokera Kafka musiał on odczytać cały stan klastra z ZooKeeper, zanim będzie można z niego korzystać. W przypadku klastrów zawierających ponad 100 000 partycji może to zająć 30-90 sekund niedostępność kontrolera.
Dzięki KRaft kontroler wiodący przechowuje dziennik metadanych już w pamięci i na dysku lokalnym. Przełączenie awaryjne zazwyczaj wymaga tego kontroler mniej niż 5 sekundnawet w przypadku dużych klastrów. Studium przypadku firmy fintech (Confluent Engineering Blog, 2025) dokumentuje redukcję czasu konfiguracji o 40% po migracji do KRaft.
Skalowalność metadanych
ZooKeeper miał praktyczny limit około 200 000 partycji na klaster (niezależnie od wydajności operacji na metadanych uległo znacznemu pogorszeniu). KRaft obsługuje dziennik metadanych jak zwykle Kłody Kafki z zagęszczeniem i zostały z tym przetestowane miliony partycji na klaster.
Prostota operacyjna
Usunięcie ZooKeepera oznacza:
- Jeden system do monitorowania zamiast dwóch
- Jeden cykl aktualizacji zamiast dwóch (często ZooKeeper i Kafka miały złożone ograniczenia wersji)
- Łatwiejsze wdrożenie na Kubernetes (mniej StatefulSet, mniej PVC)
- Łatwiejsze odzyskiwanie po awarii (stan klastra znajduje się w dzienniku metadanych, a nie rozdzielony pomiędzy Kafką i ZooKeeperem)
KRaft na Kubernetesie ze Strimzi
Strimzi to najpopularniejszy operator Kubernetes do zarządzania Kafką. Od wersji 0.38, Strimzi natywnie obsługuje KRaft:
# Kafka cluster KRaft con Strimzi Operator (Kubernetes)
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
namespace: kafka
annotations:
# Abilita KRaft mode (richiede Strimzi 0.38+)
strimzi.io/kraft: enabled
spec:
kafka:
version: 4.0.0
replicas: 3
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
config:
# KRaft-specific
default.replication.factor: 3
min.insync.replicas: 2
offsets.topic.replication.factor: 3
transaction.state.log.replication.factor: 3
transaction.state.log.min.isr: 2
# Retention
log.retention.hours: 168
log.segment.bytes: 1073741824
storage:
type: persistent-claim
size: 100Gi
class: fast-ssd
# Controller separato (produzione: controller dedicati)
# Ometti questa sezione per controller combinati (default)
# entityOperator gestisce topic e utenti tramite CRD
entityOperator:
topicOperator: {}
userOperator: {}
# Creare un topic con Strimzi CRD (invece di kafka-topics.sh)
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: ordini-effettuati
namespace: kafka
labels:
strimzi.io/cluster: my-cluster
spec:
partitions: 6
replicas: 3
config:
retention.ms: "604800000"
min.insync.replicas: "2"
compression.type: snappy
Sprawdzanie statusu Klastra KRaft
# Verificare chi è il controller leader attuale
kafka-metadata-quorum.sh \
--bootstrap-server kafka1:9092 \
describe --status
# Output:
# ClusterId: MkU3OEVBNTcwNTJENDM2Qk
# LeaderId: 1
# LeaderEpoch: 42
# HighWatermark: 156789
# MaxFollowerLag: 0
# MaxFollowerLagTimeMs: 12
# CurrentVoters: [{"nodeId":1,"logEndOffset":156789,"lag":0},
# {"nodeId":2,"logEndOffset":156789,"lag":0},
# {"nodeId":3,"logEndOffset":156789,"lag":0}]
# CurrentObservers: []
# Verificare i dettagli del quorum
kafka-metadata-quorum.sh \
--bootstrap-server kafka1:9092 \
describe --replication
# Leggere il metadata log (per debugging)
kafka-dump-log.sh \
--files /var/lib/kafka/data/__cluster_metadata-0/00000000000000000000.log \
--cluster-metadata
Różnice w konfiguracji: ZooKeeper vs KRaft
Dla tych, którzy pochodzą z klastra ZooKeeper, oto główne różnice konfiguracyjne, o których warto wiedzieć:
| Konfiguracja | Tryb ZooKeeper | Tryb KRaft |
|---|---|---|
| Połączenie klastra | zookeeper.connect |
controller.quorum.voters |
| Identyfikator węzła | broker.id |
node.id |
| Role | Zawsze pośrednik | process.roles |
| Kontrolery słuchaczy | Nie dotyczy | controller.listener.names |
| Inicjalizacja | Samochód (klamki ZK) | kafka-storage.sh format |
| Pamięć ACL | Węzły ZooKeeper | Dziennik metadanych |
Wersja metadanych i flagi funkcji w KRaft
W KRaft Kafka wprowadza koncepcję wersja.metadanych: Wersja formatu metadanych w klastrze. Umożliwia to stopniowe uaktualnianie klastra bez przestojów, po jednym węźle na raz. Wersja metadanych jest aktualizowana tylko wtedy, gdy wszyscy brokerzy w klastrze obsługują nową wersję.
# Verificare la metadata.version corrente e le versioni supportate
kafka-features.sh \
--bootstrap-server kafka1:9092 \
describe
# Output tipico con Kafka 4.0:
# Feature: metadata.version
# SupportedMinVersion: 3.0-IV1
# SupportedMaxVersion: 4.0-IV3
# FinalizedVersion: 4.0-IV3
# Verificare tutti i feature flags disponibili
kafka-features.sh \
--bootstrap-server kafka1:9092 \
describe --all
# Aggiornare la metadata.version dopo un upgrade di cluster
# (eseguire DOPO che tutti i broker sono stati aggiornati alla nuova versione)
kafka-features.sh \
--bootstrap-server kafka1:9092 \
upgrade --metadata 4.0-IV3
Wersja 4.0-IV3 (Kafka 4.0, wersja przyrostowa 3) to najnowsza wersja dostępna w tej wersji
Kafka 4.0 Marzec 2025. Każda aktualizacja wersji umożliwia nowe funkcje i optymalizacje protokołów.
Rozwiązywanie problemów z KRaft: Typowe problemy
Klaster się nie uruchamia: „Nie znaleziono kworum wyborców”
Ten błąd wskazuje, że węzły kontrolera nie mogą znaleźć innych wyborców kworum. Najczęstsze przyczyny:
-
źle skonfigurowany kontroler.quorum.voters: Sprawdź, czy format jest prawidłowy
(
nodeId@hostname:port) i że nazwy hostów są rozpoznawalne przez wszystkie węzły. - Odbiornik kontrolujący jest nieosiągalny: Sprawdź, czy zapora sieciowa na to pozwala komunikacja na porcie nasłuchiwania kontrolera (domyślnie: 9093) pomiędzy węzłami kontrolera.
-
Niezgodność identyfikatora klastra: jeśli uruchomiłeś ponownie za pomocą
kafka-storage.sh formatna jednym z węzłów bez użycia prawidłowego identyfikatora klastra, węzły nie dołączą do klastra.
# Verificare il cluster ID su ogni nodo
cat /var/lib/kafka/data/meta.properties
# node.id=1
# version=1
# cluster.id=MkU3OEVBNTcwNTJENDM2Qk <-- deve essere identico su tutti i nodi
# Verificare che il controller leader sia eletto
kafka-metadata-quorum.sh \
--bootstrap-server kafka1:9092 \
describe --status | grep LeaderId
# Se LeaderId=-1, nessun leader è stato eletto (quorum non raggiunto)
# Controllare i log del broker per errori KRaft
grep -E "WARN|ERROR" /var/log/kafka/kafka.log | grep -i "kraft\|quorum\|controller"
Broker nie został dodany do klastra
Po dodaniu nowego brokera do istniejącego klastra KRaft należy sformatować brokera z tym samym identyfikatorem klastra co istniejący klaster:
# Recupera il cluster ID dal cluster esistente
CLUSTER_ID=$(kafka-metadata-quorum.sh \
--bootstrap-server kafka1:9092 \
describe --status | grep ClusterId | awk '{print $2}')
echo "Cluster ID: $CLUSTER_ID"
# Formatta il nuovo broker con lo stesso cluster ID
kafka-storage.sh format \
--config /etc/kafka/server.properties \
--cluster-id "$CLUSTER_ID"
# Avvia il nuovo broker
kafka-server-start.sh /etc/kafka/server.properties
# Verifica che il nuovo broker sia visibile nel cluster
kafka-broker-api-versions.sh \
--bootstrap-server kafka1:9092 | grep "id:"
Kolejne kroki w serii
Dzięki dołączonemu KRaft możesz zająć się bardziej zaawansowanymi aspektami konfiguracji Kafki:
-
Artykuł 3 – Zaawansowany producent i konsument: szczegółowa konfiguracja
acks,idempotent produceri ponów strategie, aby zapewnić trwałość bez duplikatów. - Artykuł 4 – Semantyka dokładnie raz: Transakcje Kafki dla zapisów atomowych na wiele tematów, z nowym koordynatorem transakcji zaimplementowanym w dzienniku metadanych KRaft.
- Artykuł 11 – Kafka w produkcji: Rozmiar klastra KRaft, konfiguracja replik kontrolerów, odzyskiwanie danych po awarii i tworzenie kopii zapasowych dzienników metadanych.
Połącz z innymi seriami
- Zaawansowany Kubernetes: wdrożenie Kafki na Kubernetesie z operatorem Strimzi, trwałe zarządzanie pamięcią masową i automatyczne skalowanie grup konsumentów.
-
Obserwowalność: Monitorowanie kworum KRaft za pomocą JMX Exporter, krytyczne metryki
jak
kafka.controller:type=KafkaController,name=ActiveControllerCounti ostrzegaj o wyborze lidera.







