Kafka

ZooKeeper から KRaft への移行: 手順・前提・ダウンタイム最小化

2026-04-19
NicheeLab編集部

KRaft は Apache Kafka のネイティブなメタデータ管理方式で、外部の ZooKeeper を不要にします。今後のメジャー版で ZooKeeper が非推奨・削除方向にあるため、計画的な移行が必要です。

本稿では、安全性と可用性を優先し、既存 ZK クラスタから新規 KRaft クラスタへ段階的に切り替えるブルー/グリーン型を主軸に、ダウンタイムを最小化するための具体策を解説します。

なぜ今 KRaft か:前提と制約の整理

KRaft は Kafka 自身がメタデータのレプリケーションと合意形成(Raft 派生)を担う方式です。運用要素が単純化され、ZooKeeper の運用・監視・チューニングが不要になります。

移行前に確認すべき要点は、バージョンの対応、クライアント互換性、内部トピックのレプリケーション要件、セキュリティ設定(SASL/TLS)の再適用、監視・可観測性の切り替えです。一般に Kafka 3.5 以降で KRaft は実運用採用が進んでいますが、機能差分や運用モデルの違いを理解したうえで計画を立ててください。

  • クライアント互換性: 一般的な Kafka クライアントはワイヤプロトコル互換のため、ブートストラップ先を切り替えるだけで動作します。
  • コントローラ設計: 本番は専用コントローラ(3 台または 5 台)推奨。ブローカ兼任は小規模/検証向け。
  • 内部トピック: offsets と transaction_state は RF=3、ISR 適正化(例: transaction.state.log.min.isr=2)で可用性を確保。
  • ZooKeeper 連携機能の置換: トピック/ACL/クォータの管理・監視手段を KRaft 向けに見直す。
観点ZooKeeper モードKRaft モード
メタデータ管理外部 ZooKeeper内蔵 Raft(KRaft)
可用性の要点ZK クォーラム維持 + BrokerController クォーラム維持 + Broker
ローリングアップグレードの複雑さZK と Broker の両方を考慮Broker/Controller のみ(役割分離が明確)
運用対象ZK ノード + BrokerController ノード + Broker(ZK 不要)
移行の推奨方式新規 KRaft へミラーリング後に切替(段階移行)

移行前チェックリスト(互換性・キャパシティ・セキュリティ)

移行は技術的には新旧クラスタの入れ替えですが、実務的にはクライアント・運用・監視系を含む全体最適が必要です。以下のチェックリストで抜け漏れを防ぎます。

特に、ターゲットの KRaft クラスタは最初に正しくフォーマット・ブートストラップされている必要があります。フォーマット(cluster.id の生成と配布)ミスは取り返しがつきにくいため、標準化した手順書と自動化を用意します。

  • バージョン: ターゲットは KRaft 安定版(一般に 3.5+)を採用。ソース ZK 側は MirrorMaker 2 互換版を維持。
  • 容量/性能: ピーク時スループットと保存期間に基づき、ブローカ台数、ディスク、ネットワークを見積もり。内製/マネージドどちらも監視基盤を合わせる。
  • セキュリティ: SASL/TLS 証明書、JAAS、ACL、クォータを棚卸しし、KRaft 側に整備。ブートストラップ DNS 名の切替計画を用意。
  • 内部トピック: offsets.topic.replication.factor、transaction.state.log.replication.factor 等を 3 に。auto.create.topics.enable は必要に応じて無効化。
  • 監視/運用: メトリクス(JMX/Exporter)、ログ、アラート、可観測性ダッシュボードを KRaft 向けに再構築。バックアップと災対の手順を更新。

KRaft クラスタ設計の要点(Controller/Quorum/リスナー)

KRaft ではコントローラ(Controller)クォーラムがメタデータを合意し、ブローカはそれに従います。可用性は Controller の過半数と Broker 群のヘルスで決まります。本番は Controller を専用ノード 3 台(中規模)または 5 台(大規模)で構成し、Broker とは分離します。

ネットワークとリスナーは、クライアント用(例: PLAINTEXT/TLS)と Controller 用(CONTROLLER)を分け、inter.broker.listener.name を明確に設定します。

  • プロセスロール: process.roles=controller(専用)または broker,controller(兼任; 検証/小規模向け)。
  • クォーラム: controller.quorum.voters は id@host:port のカンマ区切り(例: 1@c1:9093,2@c2:9093,3@c3:9093)。
  • ノード ID: node.id を一意に。旧 broker.id は KRaft では node.id に統合。
  • リスナー: controller.listener.names=CONTROLLER、listener.security.protocol.map で CONTROLLER のプロトコルを定義。

ダウンタイム最小化の移行パターン

安全で一般的な方法は、新規 KRaft クラスタを並行稼働させ、MirrorMaker 2(OSS)または Cluster Linking(Confluent Platform)でデータとオフセットを同期し、最終同期後にクライアントのブートストラップ先を切り替えるブルー/グリーン方式です。

同一クラスタ内での"その場"移行は運用や復旧の複雑度が高く、長期的なリスクも大きいため、ダウンタイム最小化の観点でも多くの現場では新規構築→段階切替が選ばれます。

  • ブルー/グリーン(推奨): 並行で同期し、ラグゼロを確認して一括切替。失敗時は DNS/設定を戻してロールバック可。
  • 段階切替: トピック単位やコンシューマグループ単位で順次移行。重要系を最後に回す。
  • クライアント切替: Producer 先行または Consumer 先行など、ワークロードの特性に合わせて順序を設計。

ブルー/グリーン移行(MirrorMaker 2 で同期)

MirrorMaker 2 / Cluster LinkingProducers既存 ZK クラスタbrokers: B1..Bn / ZK ensembleConsumers段階的切替新規 KRaft クラスタcontrollers: C1..C3/5 / brokers: B1'..Bn'切替: 1) KRaft 起動 2) ミラー開始 3) ラグ確認 4) Producer 切替 5) Consumer 切替 6) 旧系停止

手順例:ZK から新規 KRaft へ(MirrorMaker 2 利用)

以下は代表的な手順です。実環境では自動化(IaC/構成管理)と変更管理プロセスに組み込み、検証環境でのリハーサルを必ず実施してください。

KRaft 側の format はクラスタ ID を全ノードで共通にします。Controller を先に起動し、ブローカはその後に起動します。MM2 はチェックポイントとオフセット同期を有効にし、最終切替前にラグゼロを確認します。

  • 1. KRaft 用設定ファイルを準備(Controller と Broker を分離推奨)
  • 2. クラスタ ID を生成し、各ノードでフォーマット
  • 3. Controller を起動し、続いて Broker を起動
  • 4. MirrorMaker 2(もしくは Cluster Linking)でトピック・グループを同期
  • 5. ラグゼロを確認し、Producer→Consumer の順でブートストラップ先を切替
  • 6. 監視・エラー率・遅延を観測して安定化を確認、旧クラスタを段階的に停止

設定と実行コマンド例(KRaft フォーマット/起動、MirrorMaker 2)

# Controller ノード(例: c1)の server.properties(抜粋)
process.roles=controller
node.id=1
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
listeners=CONTROLLER://0.0.0.0:9093
controller.quorum.voters=1@c1:9093,2@c2:9093,3@c3:9093
log.dirs=/var/lib/kafka/data

# Broker ノード(例: b1)の server.properties(抜粋)
process.roles=broker
node.id=11
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://b1:9092
listener.security.protocol.map=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
inter.broker.listener.name=PLAINTEXT
controller.listener.names=CONTROLLER
controller.quorum.voters=1@c1:9093,2@c2:9093,3@c3:9093
offsets.topic.replication.factor=3
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=2
unclean.leader.election.enable=false
log.dirs=/var/lib/kafka/data

# 1) クラスタ ID の生成(コントローラで一度だけ実行し、各ノードに配布)
CLUSTER_ID=$(kafka-storage.sh random-uuid)
echo $CLUSTER_ID

# 2) 各ノードでフォーマット(同一 CLUSTER_ID を使用)
sudo kafka-storage.sh format -t $CLUSTER_ID -c /etc/kafka/server.properties

# 3) Controller 起動 → Broker 起動(サービス管理で順序を担保)
# systemctl start kafka-controller; systemctl start kafka-broker ... 等

# 4) MirrorMaker 2 設定(connect-distributed 用の MM2 プラグイン構成)
# mm2.properties(抜粋)
name=mm2
connector.class=org.apache.kafka.connect.mirror.MirrorSourceConnector
tasks.max=4

# ソース(ZK クラスタ)とデスティネーション(KRaft)
source.cluster.alias=src
dest.cluster.alias=dst

src.bootstrap.servers=zk-b1:9092,zk-b2:9092
src.security.protocol=PLAINTEXT

dst.bootstrap.servers=kr-b1:9092,kr-b2:9092
dst.security.protocol=PLAINTEXT

# ミラー対象
topics=.*
groups=.*
replication.factor=3
sync.topic.acls.enabled=true
emit.checkpoints.enabled=true
sync.group.offsets.enabled=true

# 5) Connect ワーカーを起動し、MM2 コネクタを投入
# kafka-connect-distributed /etc/kafka/connect-distributed.properties &
# curl -X POST localhost:8083/connectors -H 'Content-Type: application/json' -d @mm2.json

# 6) ラグを確認(例:ConsumerGroups、MM2 のメトリクス/JMX)
# 7) ラグゼロで Producer/Consumer のブートストラップを KRaft 側に切替

検証・切替・ロールバック・運用後のタスク

切替は単なる DNS 変更ではなく、整合性の検証を伴います。エンドツーエンド遅延、エラー率、パーティション・リーダーの分布、オフセット整合を観測します。問題発生時は決めておいた時間内にロールバックします。

移行完了後は、不要なミラーリングを停止し、旧クラスタの退役を段階的に進めます。監視・アラート閾値の見直し、バックアップ/DR の更新、運用 Runbook の刷新を行います。

  • 検証: 代表トピックのメッセージ件数一致、遅延、スループット、コンシューマラグ、重複/欠損の有無。
  • 切替順序: Producer → Consumer。必要に応じて短時間のメンテナンスウィンドウを確保。
  • ロールバック: ブートストラップ先を旧クラスタに戻し、切替前スナップショット/設定で復元。MM2 は継続同期でリカバリを補助。
  • 退役: ACL/クォータ/スナップショットの保全、監査ログの保管、リソース解放の承認プロセス。

問題で確認

CCAAK

問題 1

ZK ベースの Kafka クラスタから KRaft クラスタへ、ダウンタイムを最小化して移行したい。適切な手順の組み合わせはどれか。

  1. 新規 KRaft を構築し、MirrorMaker 2 でトピックとコンシューマグループを同期。ラグゼロを確認して Producer→Consumer の順にブートストラップ先を切替える。
  2. 既存クラスタの一部ブローカをそのまま KRaft 用に再起動し、ZooKeeper を停止してからクライアントを切替える。
  3. ZK と KRaft の両方に同じ broker.id を設定し、同時に稼働させてから徐々に ZooKeeper を外す。
  4. KRaft クラスタを起動してすぐに DNS を切替え、切替後に MirrorMaker 2 で不足分を補う。

正解: A

最も安全で一般的な方法は新規 KRaft を並行稼働させ、MirrorMaker 2(または Cluster Linking)で事前に同期し、ラグゼロで切替えること。既存ブローカのその場転用や broker.id 共有は危険で、DNS 先行切替もデータ欠損や重複の恐れがある。

よくある質問

KRaft へ移行するとクライアントは変更が必要ですか?

通常はブートストラップアドレスの変更のみで動作します。API/ワイヤ互換のため、プロデューサ/コンシューマのコード変更は不要です。ただしセキュリティ設定(SASL/TLS)や DNS 名、リトライ/タイムアウトなどの接続パラメータは新旧で差異がないか確認してください。

ダウンタイムをゼロにできますか?

理論上は限りなく短縮可能ですが、完全ゼロを保証するにはネットワークやアプリ側の停止/切替影響も含めた制御が必要です。一般には短時間のメンテナンスウィンドウを取り、ラグゼロ確認後に Producer→Consumer の順で切替えると実務上の停止は数十秒〜数分に収まります。

ZooKeeper 退役後の注意点は?

旧クラスタの ACL/クォータ/設定スナップショットを保全し、監査要件に応じて一定期間保持します。監視・バックアップ・DR 手順を KRaft 前提に更新し、Controller クォーラムの健全性(リーダー交代時間、投票過半数維持)を重点監視項目に追加してください。

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

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.