ZooKeeperの問題

10 年近くにわたり、すべての Apache Kafka クラスターにはアンサンブルが必要でした Apache ZooKeeper メタデータを管理するには別のものを使用します。 どのブローカーがアクティブであったか、どのブローカーがどのパーティション、トピック、ACL メタデータのリーダーであったか。 ZooKeeper は調整システムです 分散型は堅牢で信頼性が高いですが、運用上でいくつかの重大な問題が発生しました。

  • 運用の複雑さが 2 倍になる: Kafka を管理する各チームは、別個の ZooKeeper クラスターも管理する必要がありました (通常は 3 つまたは 5 つのノード)、独自の監視、アップグレード サイクル、および個別の構成を備えています。
  • メタデータのスケーラビリティが制限されている: ZooKeeper は、パーティション数が約 200,000 を超えるとパフォーマンスの低下を示しました これは、各パーティションのメタデータが個別の ZooKeeper ノードとして書き込まれているためです。
  • コントローラーの選択が遅い: Kafka ブローカー コントローラーがダウンしたとき、新しいコントローラーは整数を読み取る必要がありました。 ZooKeeper が動作する前に、ZooKeeper からクラスターのステータスを取得します。このプロセスは、大規模なクラスターの場合は数十秒かかる場合があります。
  • 災害復旧の難しさ: ZooKeeper でデータ損失が発生した場合の Kafka クラスターの回復 それは複雑で危険な手作業のプロセスでした。

クラフトタイムライン

  • KIP-500 (2020): Kafka から ZooKeeper を削除するという当初の提案
  • カフカ 2.8 (2021 年 4 月): 早期アクセスの KRaft を含む最初のバージョン (テストのみ)
  • カフカ 3.3 (2022 年 10 月): KRaft は、新しいクラスターの運用準備が整っていると宣言しました。
  • カフカ 3.5 (2023 年 6 月): ZooKeeper から KRaft への移行ツールが利用可能になりました
  • カフカ 3.7 (2024 年 3 月): ZooKeeper モードは非推奨になりました
  • カフカ 4.0 (2025 年 3 月): ZooKeeper モードは完全に削除されました

KRaft の仕組み: Raft コンセンサス ログ

メタデータログの概念

KRaft (Kafka Raft) で採用されているソリューションは洗練されています。メタデータを外部システムに依存するのではなく、 Kafka はメタデータを Kafka の内部トピック 呼ばれた @metadata。 このトピックは、Raft プロトコルを介してコントローラー ノード間で複製されます。

KRaft では、クラスター ブローカーは次の 2 つの役割のいずれか (または小規模クラスターの場合は両方) を引き受けます。

  • コントローラー: クラスターのメタデータを管理します。実稼働クラスターでは、3 つのコントローラーのクォーラムが推奨されます。 アクティブ コントローラー (Raft リーダー) は、すべてのメタデータの変更を処理し、それらを他のコントローラーに複製します。
  • ブローカ: パーティション ログを管理し、プロデューサーとコンシューマーにサービスを提供します。ブローカーはコピーを保管します コントローラーから受信したメタデータのキャッシュ。ストリーミングで更新されます。

Kafka の Raft プロトコル

Raft は、(Paxos とは異なり) 理解できるように設計された分散型コンセンサス アルゴリズムです。 つまり、すべてのクォーラム ノードの中から 1 つが選出されます。 リーダー。指導者はすべての経典を受け取り、 それらをフォロワーに伝播し、大多数のノードが書き込みを確認すると、書き込みがコミットされたと見なされます。

KRaft では、これは次のように変換されます。

  1. メタデータ操作 (トピックの作成、パーティション リーダーの割り当てなど) がリーダー コントローラーに到着します。
  2. リーダー コントローラーは操作をシリアル化されたイベントとしてメタデータ ログに書き込みます。
  3. イベントはプロトコル経由でコントローラーのフォロワーに複製されます。 FETCH (既存の Kafka コードを活用)
  4. 大多数のコントローラーが確認 (クォーラム) すると、操作はコミットされます
  5. ブローカーは、アクティブなコントローラーからプッシュされたメタデータの更新を次のように受信します。 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

クォーラム コントローラー: サイズ設定

クォーラム コントローラーはコンセンサス ルールに従います。 f 失敗しても必要だ 2f+1 結び目。

  • コントローラー3個: 1 つの障害を許容します (本番環境の最小構成)
  • 5つのコントローラー: 2 つの同時障害を許容します (重要なクラスターに推奨)
  • 1コントローラー: ローカル開発/テスト専用、フォールト トレランスなし

コントローラーは次のとおりです。 ひたむきな (コントローラーロールのみ、ユーザーパーティションは管理しません) または 組み合わせた (同じマシンがブローカーとしても機能します)。小規模クラスター (ブローカー数 10 未満) の場合、コントローラー 組み合わせても問題ありません。大規模または高スループットのクラスターの場合、専用コントローラーが管理負荷を分離します。 パーティション I/O ロードからのメタデータ。

KRaft クラスターを最初から構成する

# 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

重要: クラスター ID は不変です

Il cluster.id フォーマットがファイルに書き込まれるときに生成されます meta.properties 各ノードの そしてメタデータログにあります。初期化後は変更できません。このファイルを紛失した場合にノードを追加したい場合 既存のクラスターに接続するには、適切なブートストラップ手順を使用する必要があります。クラスター ID をシークレット管理システムに保存します。

Docker Compose: ローカル開発用の KRaft クラスター

# 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:

ZooKeeper を使用した Kafka 3.x から KRaft への移行

ZooKeeper モードで Kafka 3.x クラスターを管理していて、KRaft に移行する必要がある場合 (Kafka 4.0 を使用するために必要)、 プロセスが呼び出されます KRaft の移行 バージョン 3.5 以降正式にサポートされています。 良いニュース: 移行は起こる ダウンタイムなしで 生産者と消費者にとって。

移行のフェーズ

公式プロセスは 6 つのフェーズに分かれています。

  1. 前提条件を確認する: Kafka 3.7 (ZooKeeper+KRaft 二重書き込みサポートを備えた最新バージョン) にアップグレードします。 すべてのブローカーが持っていることを確認してください metadata.version 整列しました。
  2. KRaft コントローラーの導入: KRaft コントローラー ノード (3 つの新しいノード、または既存のブローカーを開始します) 追加の役割)。コントローラーは、移行ツールを介して ZooKeeper から初期メタデータを取得します。
  3. 二重書き込みモード: ブローカーはメタデータを ZooKeeper と KRaft メタデータ ログの両方に書き込みます。 この段階では、システムは完全に動作します。
  4. 移行が完了しました: すべてのブローカーが移行され、ZooKeeper は Kafka に対して読み取り専用になります。 生産者と消費者は中断を認識しません。
  5. ZooKeeper ファイナライザー: ZooKeeper から Kafka メタデータをクリーンアップするファイナライザーを実行します。
  6. ZooKeeper をシャットダウンする: ZooKeeper アンサンブルを廃止します。完全に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

移行に関する重要なお知らせ

  • 簡単に戻らないでください: KRaft の移行が完了し、ZooKeeper が削除されたら、 ロールバックは非常に複雑です。まず、本番環境と同じステージング環境に移行します。
  • ACL と構成: ZooKeeper 経由で管理される ACL と動的構成が移行されます メタデータ ログに自動的に記録されますが、移行後に存在することを確認してください。
  • コネクタ Kafka Connect: Kafka クラスターを状態のバックエンドとして使用するコネクタ (group.id、offsets) は変更されずに引き続き機能します。
  • ミラーメーカー 2: geo レプリケーションに MM2 を使用する場合は、同じ内のリモート クラスターを更新します。 バージョンの非互換性を回避するためのメンテナンス期間。

高度な構成の KRaft: 専用コントローラー

高スループットのクラスター、または多数のパーティション (>50,000) を管理するクラスターの場合、 コントローラーをブローカー (専用コントローラー) から分離することをお勧めします。このように メタデータ操作 (トピックの作成、リーダーの選択、構成の変更) は競合しません。 同じディスク上のパーティション ログ I/O を使用します。

# 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

Confluent Cloud および Amazon MSK (バージョン 3.6 以降 KRaft を採用) などのマネージド環境では、 コントローラーとブローカーの分離は自動的に行われ、ユーザーには透過的です。

KRaft の運用上のメリット

起動と回復の高速化

ZooKeeper では、Kafka ブローカー コントローラーが再起動するときに、クラスターの状態全体を読み取る必要がありました。 操作できるようになる前に ZooKeeper から削除してください。 100,000 以上のパーティションを持つクラスターの場合、これには時間がかかる場合があります 30~90秒 コントローラーが使用できない。

KRaft を使用すると、リーダー コントローラーはメタデータ ログをメモリとローカル ディスクにすでに保持します。フェイルオーバー 通常、コントローラに必要となるのは 5秒未満たとえ大規模なクラスターであっても。ケーススタディ フィンテック企業のレポート (Confluent Engineering Blog、2025) では、セットアップ時間の 40% 削減が文書化されています。 KRaftに移行後。

メタデータのスケーラビリティ

ZooKeeper には、(パフォーマンスに関係なく) クラスターあたり約 200,000 のパーティションという実際的な制限がありました。 メタデータ操作が大幅に低下しました)。 KRaft はメタデータ ログを通常どおり処理します Kafka は圧縮を使用してログを記録し、次の方法でテストされています。 数百万のパーティション クラスターごとに。

操作の簡素化

ZooKeeper を削除することは次のことを意味します。

  • 2 つのシステムではなく 1 つのシステムを監視する
  • 2 つのアップグレード サイクルではなく 1 つのアップグレード サイクル (多くの場合、ZooKeeper と Kafka には複雑なバージョン制約がありました)
  • Kubernetes でのデプロイメントが容易 (StatefulSet や PVC が少ない)
  • 災害復旧が容易になります (クラスターの状態はメタデータ ログに記録され、Kafka と ZooKeeper の間で分散されません)。

Strimzi を使用した Kubernetes 上の KRaft

ストリムジ Kafka を管理するための最も人気のある Kubernetes オペレーターです。バージョン0.38からは、 Strimzi は 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

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

構成の違い: ZooKeeper と KRaft

ZooKeeper クラスターから派生するユーザーにとって、知っておくべき主な構成の違いは次のとおりです。

構成 ZooKeeperモード KRaftモード
クラスタ接続 zookeeper.connect controller.quorum.voters
ノードID broker.id node.id
役割 常に仲介します process.roles
リスナーコントローラー 該当なし controller.listener.names
初期化 車(ZKハンドル) kafka-storage.sh format
ACLストレージ ZooKeeper の znode メタデータログ

KRaft のメタデータのバージョンと機能フラグ

KRaft を使用して、Kafka は次の概念を導入します。 メタデータ.バージョン: メタデータ形式のバージョン クラスター内で。これにより、一度に 1 ノードずつ、ダウンタイムなしでクラスターのローリング アップグレードが可能になります。 メタデータのバージョンは、クラスター内のすべてのブローカーが新しいバージョンをサポートする場合にのみ更新されます。

# 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

バージョン 4.0-IV3 (Kafka 4.0 Incremental Version 3) は、リリースで利用可能な最新のものです Kafka 4.0 2025 年 3 月。バージョンが上がるたびに、新機能とプロトコルの最適化が可能になります。

KRaft のトラブルシューティング: 一般的な問題

クラスターが起動しない: 「定足数内に投票者が見つかりません」

このエラーは、コントローラー ノードが他のクォーラム投票者を見つけられないことを示します。 一般的な原因:

  • 構成が間違っているcontroller.quorum.voters: 形式が正しいことを確認してください (nodeId@hostname:port)、ホスト名はすべてのノードで解決可能であること。
  • CONTROLLER リスナーに到達できません: ファイアウォールが許可していることを確認してください コントローラー ノード間のコントローラー リスナー ポート (デフォルト: 9093) での通信。
  • クラスターIDの不一致: で再起動した場合 kafka-storage.sh format いずれかのノードで正しいクラスター ID を使用しないと、そのノードはクラスターに参加しません。
# 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"

ブローカーがクラスターに追加されていません

新しいブローカーを既存の KRaft クラスターに追加するときは、ブローカーをフォーマットする必要があります 既存のクラスターと同じクラスター ID を持つ:

# 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:"

シリーズの次のステップ

KRaft が含まれていると、Kafka 構成のより高度な側面に取り組む準備が整います。

  • 第 3 条 – 先進的な生産者と消費者: の詳細な構成 acks, idempotent producer、重複のない耐久性を確保するために戦略を再試行します。
  • 第 4 条 – 1 回限りのセマンティクス: アトミック書き込み用の Kafka トランザクション KRaft メタデータ ログに実装された新しいトランザクション コーディネーターを使用して、複数のトピックに対応します。
  • 第 11 条 – 本番環境における Kafka: KRaft クラスターのサイジング、構成 コントローラーのレプリカ、災害復旧、メタデータ ログのバックアップ。

他シリーズとの連携

  • 高度な Kubernetes: Strimzi オペレーターを使用した Kubernetes 上の Kafka のデプロイメント、 永続ストレージ管理とコンシューマ グループの自動スケーリング。
  • 可観測性: JMX Exporter による KRaft クォーラム監視、重要なメトリクス どうやって kafka.controller:type=KafkaController,name=ActiveControllerCount そしてリーダー選出を警戒する。