Cluster Linkingは、ブローカー同士が直接レプリケーションするConfluentの公式機能で、トピックのパーティション・レコード・オフセットを1対1で保持して複製します。これにより、消費者の再バランスやオフセット変換を最小限に抑えた移行やDRが可能になります。
本稿では、オフセット保持を前提にした複製・移行の設計注意点、段階的カットオーバー手順、監視と検証方法を解説し、CCAAK受験で問われやすい差異点もまとめます。
Cluster Linkingは、宛先クラスタがリンク経由で元クラスタからデータをフェッチするサーバーサイド複製です。MirrorMaker 2のような外部コネクタを介さず、トピック単位の"ミラー"を宛先側に作成して、元トピックのパーティション構成・順序・各レコードのオフセットをそのまま保持します。
オフセットが保持されることで、消費者はクラスタ切替後も同じ数値のオフセットから再開できます。従来必要だったオフセット変換や整合性のための待ち時間が大幅に減り、DR/リージョン移行/ブルーグリーン展開が単純化されます。
オフセット保持のイメージ(同一パーティション/同一オフセット)
最小リンク作成(宛先クラスタ側で実行)
# 宛先: リンク作成(プロパティファイルで安全に資格情報を保持)\n# link-src.properties 例\n# bootstrap.servers=src-broker:9092\n# security.protocol=SASL_SSL\n# sasl.mechanism=PLAIN\n# sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username=\"...\" password=\"...\";\n\n# 宛先でリンクを作成\n$ kafka-cluster-links \\\n --bootstrap-server dest-broker:9092 \\\n --create --link src-to-dest \\\n --config-file link-src.properties\n\n# ミラートピック作成(orders を元からミラー)\n$ kafka-mirrors \\\n --bootstrap-server dest-broker:9092 \\\n --create --mirror-topic orders --link src-to-destCluster Linkingでは、ミラートピックの各パーティションは元の同一パーティションからフェッチし、各レコードのオフセット・タイムスタンプ・ヘッダを保持します。これにより、コンシューマはクラスタ切替時にオフセット値の変換を必要とせず、シークの一貫性が得られます。
ただし、以下が満たされていないと、切替時に期待どおりに再開できない可能性があります。特に、ミラー中は宛先側への書き込みができないため、完全なカットオーバーまでは書き込み先が単一であることを守る必要があります。
| 項目 | Cluster Linking | MirrorMaker 2(比較) |
|---|---|---|
| オフセット | レコードの数値オフセットを保持(翻訳不要) | 通常は変換が必要(Offset Syncで翻訳) |
| 実行形態 | ブローカー内機能(サーバーサイド) | Kafka Connect ワーカー上のコネクタ |
| レイテンシ | 低〜中(ブローカー間フェッチ) | 中(コネクタ経由のオーバーヘッド) |
| 片方向/双方向 | 片方向リンクを複数張る設計 | 双方向構成は可能だが複雑化 |
| 切替時の手順 | ミラー昇格+グループオフセット整合 | 生産・消費の停止とオフセット翻訳が中心 |
ミラーの状態確認(遅延・健康度)
# リンク/ミラーの記述\n$ kafka-cluster-links --bootstrap-server dest:9092 --describe --link src-to-dest\n$ kafka-mirrors --bootstrap-server dest:9092 --describe --mirror-topic orders\n\n# 代表的な遅延メトリクス(JMX名は環境によりプレフィックス差異あり)\n# kafka.server: type=ReplicaFetcherManager,name=MaxLag,clientId=*,link=src-to-dest\n# kafka.server: type=MirrorTopicMetrics,name=TimeLag,topic=orders移行: 既存クラスタ(Source)でプロデュースを継続しながら、宛先(Destination)でミラーを追随させ、十分に追いついたタイミングで昇格し、書き込み先を切替えます。オフセット保持により、消費者は同じオフセットで読み続けられます。
DR: 平常時は片方向にミラー。障害時に宛先でミラーを昇格し、プロデュース/コンシュームを切替えます。復旧後に逆方向の新リンクを張り返す計画(ブレインスプリット回避のため、同時双方向書き込みは避ける)。
昇格(プロモート)と書き込み切替の最小シーケンス
# 1) 生産を短時間停止(ソースの最終レコードまで追いつかせる)\n# 2) 宛先でミラーを昇格(以後、通常トピック)\n$ kafka-mirrors --bootstrap-server dest:9092 --promote --mirror-topic orders\n# 3) プロデューサのbootstrap.serversを宛先に変更して再開\n# 4) コンシューマは同じgroup.id/オフセットで継続(次節のオフセット整合参照)Cluster Linkingはレコードのオフセットを保持しますが、コンシューマグループのコミットは別トピックに格納されるため、自動移行を前提にしないのが安全です。以下は停止時間を最小化しつつ、同一オフセットで切替えるための現実的な手順です。
なお、auto.offset.reset=latest/earliest の既定挙動に依存すると再開位置がズレるため、宛先でのグループオフセットを明示的に整合させます。
グループオフセットの事前整合(例: 単一トピック・少数パーティション)
# 1) ソースで現在のコミット位置を確認\n$ kafka-consumer-groups --bootstrap-server src:9092 --describe --group app-g1 \\n --topic orders\n# 出力から各partitionのCURRENT-OFFSETを控える(p0=1043, p1=879 など)\n\n# 2) 宛先で同じgroup.idに対し、手動で同値を設定\n$ kafka-consumer-groups --bootstrap-server dest:9092 --group app-g1 \\n --topic orders --reset-offsets --to-offset 1043 --partition 0 --execute\n$ kafka-consumer-groups --bootstrap-server dest:9092 --group app-g1 \\n --topic orders --reset-offsets --to-offset 879 --partition 1 --execute\n\n# 3) ミラーを昇格し、コンシューマ/プロデューサを宛先に切替\n$ kafka-mirrors --bootstrap-server dest:9092 --promote --mirror-topic orders遅延は切替可否判断の核心です。TimeLag/RecordsLag、リンクのヘルス、フェッチエラーの有無をモニタリングし、ラグしきい値を定めます。ネットワーク帯域やretention.msの差異で進行が詰まるケースに注意します。
設定ドリフトは意図せぬ挙動の原因です。cleanup.policy, min.insync.replicas, compression.type など、ミラー作成時点の設定を確認し、昇格後に必要なら明示的に変更します。ACL/RBACは別管理とし、切替前にアクセス権を先行配布します。
簡易ヘルスチェックと遅延取得の例
# Describeでリンクとミラーの状態を点検\n$ kafka-cluster-links --bootstrap-server dest:9092 --describe --link src-to-dest | sed -n '1,200p'\n$ kafka-mirrors --bootstrap-server dest:9092 --describe --mirror-topic orders\n\n# JMXをcurl/jolokia等で取得し、TimeLagがしきい値未満であることを確認\n# 例: curl http://jolokia:8778/jolokia/read/kafka.server:type=MirrorTopicMetrics,name=TimeLag,topic=ordersCluster Linkingは「レコードのオフセット保持」が最大の差別化点です。MirrorMaker 2のOffset Syncのような変換が不要であること、ミラートピックは宛先で読み取り専用であること、昇格で通常トピックになることを押さえます。
試験では、どのレイヤで機能が提供されるか(ブローカー/Connect)、切替時に必要な操作(昇格・グループオフセット整合)、二重書き込み回避などの設計判断が頻出です。
要点チェック(擬似コマンドによる暗記用メモ)
# create link -> create mirror -> catch up -> promote -> switch clients\n# オフセット保持: 変換不要。グループオフセット: 手動整合/移行を計画。CCAAK
問題 1
既存クラスタAから新クラスタBへトピックordersをダウンタイム最小で移行したい。Cluster Linkingでミラートピックを作成し、十分追いついた。オフセット保持を活かして消費を同じ位置で継続するために、最も適切な次の操作はどれか。
正解: A
Cluster Linkingはレコードのオフセットを保持するが、グループコミットは自動移行前提ではない。昇格後、宛先で同じgroup.idのオフセットを明示的に整合してから切替えるのが安全。latest任せや__consumer_offsetsの直接ミラーは不適切で、ミラー中の直接書き込みも不可。
ミラートピックのパーティション数は変更できますか?
ミラー状態の間は元トピックのパーティション構成に追随し、宛先側から独自変更はできません。昇格後は通常トピックとなるため、一般的な制約の範囲でパーティション数を拡張できます。
ACLやRBACはリンクで一緒に複製されますか?
データ複製とは独立です。宛先で必要な権限を事前に用意し、切替前に配布しておく運用が推奨です。
トランザクションやEOS(Exactly-Once Semantics)はどう扱われますか?
Cluster Linkingはレコード順序とオフセットを保持しますが、トランザクション境界はクラスタ間で共有されません。トランザクションをまたぐ書き込みは単一クラスタ内で完結させ、切替時は停止・昇格・再開の順を守って整合性を確保してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Kafka Topic と Partition の基礎: 分散とスケーラビリティの要
CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...
CCDAK 試験ガイド:出題範囲・配点・申込み・対策
Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...
Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点
CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...
Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性
レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...
Kafka の Offset とコミット: ポジション管理と at-least-once の基礎
CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...