Kafka

KRaft モード徹底理解: ZooKeeper 不要化とメタデータ設計の要点

2026-04-19
NicheeLab編集部

KRaft は Kafka 自身がメタデータをレプリケーションし、ZooKeeper を使わずにクラスタを成立させる運用形態。コントローラ・クォーラムが Raft 合意でメタデータログを管理し、ブローカはその適用結果を購読する。

本稿では、ZooKeeper 不要化の背景、KRaft のメタデータ設計、主要プロパティ設定、導入・移行、可用性/セキュリティ設計を、試験(CCAAK)で狙われやすいポイントに焦点を当てて解説する。

KRaft の要点と試験観点

KRaft は Kafka のコントロールプレーンを内製化し、コントローラ・クォーラムがメタデータログを Raft で合意・複製する。ZooKeeper は不要となり、Kafka のライフサイクル内でクラスタ形成・メタデータ更新が完結する。

実務では、コントローラ専用ノードかブローカと同居させるかの選択、奇数ノードのクォーラム設計、ストレージ初期化(kafka-storage.sh)が肝。試験では、プロパティ名や起動順序、KRaft 専用の概念(メタデータログ、スナップショット)が頻出。

  • ZooKeeper は KRaft モードでは一切使用しない。両者の混在は不可。
  • コントローラ・クォーラムは奇数台(例: 3, 5)で過半数合意をとる。
  • node.id を用いる。broker.id を使う従来の設定と混同しない。
  • controller.listener.names と listeners の整合性が必須。
  • kafka-storage.sh でクラスタ ID を生成し、format してから起動。
用語KRaft における意味試験での要チェック点
Controller Quorumメタデータを合意・複製するコントローラ群奇数台・voters 設定・リーダ概念
Metadata Logメタデータ変更の不変ログ(コントローラで管理)スナップショットと再現の関係
Snapshotメタデータ状態の圧縮点高速ブートストラップ・復旧手順
process.rolesbroker, controller の役割付与同居/分離構成の可否と注意点
node.idKRaft での一意ノード IDbroker.id 非推奨との違い

KRaft の論理構成(高レベル)

metadata updates / subscriptionsClientsBrokers(data)Controller Quorum(Raft: leader & followers)KRaft の論理構成(高レベル)

クラスタ ID の生成とストレージ初期化(必須手順)

# 1) クラスタ ID を生成
$ KAFKA_HOME/bin/kafka-storage.sh random-uuid
hd9a2a0f-1b23-4c56-9d78-90efab12cd34

# 2) server.properties を用いてストレージを初期化
$ KAFKA_HOME/bin/kafka-storage.sh format -t hd9a2a0f-1b23-4c56-9d78-90efab12cd34 -c config/server.properties

ZooKeeper 不要化の背景と KRaft 比較

KRaft ではコントロールプレーンとデータプレーンが Kafka 内に収斂する。ZooKeeper の外部依存・運用負担(監視、アップグレード、スケーリング)を避け、メタデータ変更の一貫性と遅延の予測可能性を高める。

比較観点は、メタデータの保存形式、合意アルゴリズム、障害許容、構成・運用のシンプルさ。公式ドキュメントの用語と一致する理解が重要。

  • ZooKeeper: 階層ツリー + ウォッチャ。KRaft: ログ + スナップショット。
  • Zab vs Raft(実装は Kafka Raft)。どちらも過半数合意だが実装と責務の境界が異なる。
  • KRaft ではブローカがメタデータログの適用結果を購読し、即時に状態更新する。
項目ZooKeeper クラスタKRaft (Controller Quorum)
コントロールプレーン外部(ZooKeeper)Kafka 内製(コントローラ)
メタデータ形式ZNode 階層不変ログ + スナップショット
合意アルゴリズムZabRaft(過半数合意)
依存・運用別クラスタの設計・監視が必要Kafka の一体運用で簡素化
構成の要点zookeeper.connectprocess.roles, controller.quorum.voters
ネットワークZK ポートの開放が必要CONTROLLER リスナーで隔離可能

Before/After 概念図

BrokersBeforeZooKeeperBrokersAfterController Quorum(Raft)Before(ZooKeeper) / After(KRaft)

設定の対比例

# 旧(ZooKeeper 依存)
# zookeeper.connect=zk1:2181,zk2:2181,zk3:2181
# broker.id=1

# 新(KRaft)
process.roles=broker,controller
node.id=1
controller.quorum.voters=1@node1:9093,2@node2:9093,3@node3:9093
controller.listener.names=CONTROLLER
listeners=PLAINTEXT://node1:9092,CONTROLLER://node1:9093
inter.broker.listener.name=PLAINTEXT
metadata.log.dir=/var/lib/kafka/metadata
log.dirs=/var/lib/kafka/data

メタデータ設計: ログとスナップショット、伝搬

トピック作成や ACL 変更などのメタデータ更新は、コントローラ・リーダがメタデータログに追記し、フォロワが複製する。一定間隔または閾値でスナップショットを作成し、リスタートや新規参加ノードの高速同期を実現する。

ブローカはコントローラからメタデータ更新を購読し、インメモリキャッシュを更新する。これにより ZooKeeper のウォッチャに相当するイベント駆動が Kafka 内で完結する。

  • メタデータは不変ログで順序保証され、適用で最終状態を構成。
  • スナップショット + 増分再生で高速ブートストラップ。
  • メタデータ更新は過半数コミット後に可視化。
要素役割運用ポイント
Metadata Record単一の状態変更イベント順序・冪等適用
Metadata Logレコードの順序付き永続ログ耐障害性・再現性
Snapshot状態の圧縮表現復旧時間短縮・世代管理

メタデータ変更のフロー

Admin API (Topic)Controller Leader(Metadata Log)Append/CommitController FollowersReplicateBrokers (Apply)Push/Fetchメタデータ変更のフロー

メタデータ専用ディレクトリの指定

# コントローラ側にメタデータログを分離配置
metadata.log.dir=/var/lib/kafka/metadata
# ブローカのデータ(トピックログ)は従来どおり
log.dirs=/var/lib/kafka/data

基本構成と主要プロパティ(同居 3 ノード例)

最小の本番向けは 3 ノードのコントローラ・クォーラム。以下はブローカとコントローラを同居させた構成例。ノードごとに node.id とアドレスを変える。

CONTROLLER リスナーは運用上ネットワークで分離し、TLS/認証を適用するのが望ましい。

  • process.roles に broker,controller を両方記載で同居構成。
  • controller.quorum.voters は id@host:port をカンマ区切りで全ノード分。
  • controller.listener.names に CONTROLLER を指定し、listeners に CONTROLLER:// を定義。
  • inter.broker.listener.name はブローカ間通信用に指定。
プロパティ用途
process.roles役割指定broker,controller
node.idノード一意 ID1
controller.quorum.votersクォーラム構成1@n1:9093,2@n2:9093,3@n3:9093
controller.listener.namesコントローラ用リスナー名CONTROLLER
listenersリスナー定義PLAINTEXT://n1:9092,CONTROLLER://n1:9093
inter.broker.listener.nameブローカ間通信用PLAINTEXT

ポートとリスナーの分離イメージ

n1: PLAINTEXT 9092  <--> clients/brokers
    CONTROLLER 9093 <--> controller quorum traffic
n2: PLAINTEXT 9092, CONTROLLER 9093
n3: PLAINTEXT 9092, CONTROLLER 9093

server.properties(抜粋: ノード n1)

process.roles=broker,controller
node.id=1
controller.quorum.voters=1@n1:9093,2@n2:9093,3@n3:9093
controller.listener.names=CONTROLLER
listeners=PLAINTEXT://n1:9092,CONTROLLER://n1:9093
inter.broker.listener.name=PLAINTEXT
advertised.listeners=PLAINTEXT://n1:9092
metadata.log.dir=/var/lib/kafka/metadata
log.dirs=/var/lib/kafka/data

導入・移行の実務ポイント

新規クラスタは KRaft での構築が簡潔。手順は「設定→ストレージ初期化→起動順序(コントローラ→ブローカ)→検証」。

既存 ZooKeeper クラスタからの移行は、公式手順とサポート対象バージョンを必ず確認する。無停止または低停止を志向する仕組みが段階的に整備されてきたが、バージョン互換や制約は変動し得るため、実環境では検証環境でのリハーサルを推奨。

  • 新規構築: まず全ノードを format。クラスタ ID は全ノードで同一にする。
  • 起動: 先にコントローラ・クォーラムを安定化→ブローカ起動。
  • 検証: ブローカがメタデータを受信し、トピック作成が即時に反映されることを確認。
  • 移行: 公式ドキュメントの対象バージョン・互換性を厳守。バックアップ・ロールバック計画を用意。
ステップ目的代表コマンド/観点
クラスタ ID 生成一意な識別子付与kafka-storage.sh random-uuid
ストレージ初期化メタデータ領域の準備kafka-storage.sh format -t <UUID> -c server.properties
起動順序安定合意の確立controllers → brokers
健全性確認メタデータ伝搬の確認kafka-topics.sh --create / --describe

新規構築の流れ

configformat(storage)start controllersstart brokersverify新規構築の流れ

検証用コマンド例

# トピック作成
$ KAFKA_HOME/bin/kafka-topics.sh --bootstrap-server n1:9092 --create --topic test --partitions 3 --replication-factor 3
# ブローカ視点のメタデータ確認
$ KAFKA_HOME/bin/kafka-topics.sh --bootstrap-server n1:9092 --describe --topic test

可用性・セキュリティ・監視の勘所

可用性は奇数のクォーラム設計が基本。レイテンシと耐障害のバランスで 3 もしくは 5 が一般的。コントローラ専用ノードにすると負荷分離と障害ドメイン分離の利点がある。

セキュリティは CONTROLLER リスナーで TLS/認証を必須化。監視はコントローラのリーダ選出、レプリケーション遅延、スナップショット発生、メタデータ適用の遅延などを可視化する。

  • クォーラムは 3 台で 1 台障害まで許容、5 台で 2 台まで許容。
  • CONTROLLER リスナーはブローカ/クライアント用と物理・論理に分離。
  • メトリクス: コントローラレプリケーション遅延、リーダ変更回数、メタデータ適用レイテンシ。
クォーラム台数許容障害数適用例
10検証のみ(本番非推奨)
31小規模本番
52中規模・高可用性要求

過半数の概念(5 台例)

[1][2][3][4][5]
  ^  ^  ^
3 ノードの賛同(過半数)が必要。2 台障害まで可。

CONTROLLER リスナーに TLS を適用する例(概念)

# 実際のキーストア/トラストストア設定は運用基準に合わせる
listeners=SSL://n1:9092,CONTROLLER://n1:9093
controller.listener.names=CONTROLLER
listener.security.protocol.map=SSL:SSL,CONTROLLER:SSL
ssl.keystore.location=/path/keystore.jks
ssl.keystore.password=***
ssl.truststore.location=/path/truststore.jks
ssl.truststore.password=***

問題で確認

CCAAK

問題 1

KRaft モードで 3 ノードの同居構成(broker+controller)を正しく形成する最小限の設定として最も適切なのはどれか。

  1. process.roles=broker,controller とし、node.id を各ノードで一意に設定。controller.quorum.voters に 1@n1:9093,2@n2:9093,3@n3:9093 を指定し、listeners に PLAINTEXT と CONTROLLER の両方を定義、controller.listener.names=CONTROLLER を設定する。
  2. zookeeper.connect を 3 台指定し、broker.id を設定する。controller.listener.names は省略可能で、node.id は不要である。
  3. process.roles=controller のみを 1 台に設定し、残り 2 台は broker のみ。controller.quorum.voters は空でも自動検出される。
  4. process.roles=broker,controller とし、controller.listener.names=PLAINTEXT を設定すれば CONTROLLER リスナーは不要である。

正解: A

KRaft では ZooKeeper を使わず、controller.quorum.voters に id@host:port を列挙し、controller.listener.names に CONTROLLER を指定、listeners に CONTROLLER:// を定義する。node.id は各ノードで一意。zookeeper.connect や broker.id は KRaft では用いない。

よくある質問

KRaft と ZooKeeper を同一クラスタで併用できるか?

できない。KRaft モードでは ZooKeeper を一切使用しない設計であり、混在はサポートされない。新規は KRaft で構築し、既存からの移行は公式手順と対応バージョンに従う。

controller.quorum.voters の台数はどう設計すべきか?

奇数台が原則。小規模は 3 台(1 台障害許容)、高可用性は 5 台(2 台障害許容)。不要に大きくするとレイテンシと運用負荷が増す。

ストレージ初期化を忘れて起動するとどうなる?

クラスタ ID 不一致または未初期化エラーで起動失敗する。kafka-storage.sh で UUID を生成し、全ノードを同一クラスタ ID で format してから起動すること。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Kafka

Kafka Topic と Partition の基礎: 分散とスケーラビリティの要

CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...

Kafka

CCDAK 試験ガイド:出題範囲・配点・申込み・対策

Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...

Kafka

Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点

CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...

Kafka

Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性

レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...

Kafka

Kafka の Offset とコミット: ポジション管理と at-least-once の基礎

CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...

Kafkaの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.