リバランスはコンシューマグループの安定性と可用性に直結します。試験では概念と設定の因果、運用では停止時間の最小化が要点です。
本稿は公式挙動に基づき、イベント発生条件、プロトコル差分、設定のトレードオフ、監視・運用までを一気通貫で解説します。
リバランスは、コンシューマグループ内でパーティション割り当てを再計算し直すプロセスです。グループコーディネータが JoinGroup と SyncGroup の往復でメンバーに割り当てを通知し、各メンバーは再開前に revoke/assign の処理を行います。
プロトコルには大きく Eager と Cooperative(増分)があります。Eager は全メンバーが一度すべてのパーティションを手放す方式で停止時間が伸びがち、Cooperative は段階的に譲り合うため停止時間を短縮できます。
| フェーズ | 主なRPC/イベント | 失敗時の挙動 |
|---|---|---|
| 検出 | ハートビート/サブスクリプション変化検知 | タイムアウトでメンバー不在を判断し再参加を促す |
| Join | JoinGroup リクエストとリーダー選出 | 期限超過で再試行、過度に長いと長時間の空白が発生 |
| Sync | SyncGroup により最終割り当て確定 | 競合や変更があると再ラウンド(Cooperative では増分適用) |
基本シーケンス(簡略)
Java コンシューマのリバランスリスナー(要点のみ)
consumer.subscribe(Collections.singletonList("orders"), new ConsumerRebalanceListener() {
@Override
public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
// 処理中メッセージを安全に終了し、最後まで読んだ位置を同期コミット
consumer.commitSync();
}
@Override
public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
// 再開時の位置調整。必要に応じて seek を行う
// consumer.seekToCommitted(partitions);
}
});リバランスは任意の変更で常に発生するわけではありません。主因はメンバーシップ、サブスクリプション、トピック構成の変化です。心拍やポーリングの時間超過は、実務で最も多い誘因です。
コーディネータのフェイルオーバー時はメンバーの再参加が発生し得ますが、必ずしも割り当てが大幅に変わるわけではありません。とはいえ短時間の空白や再同期は覚悟が必要です。
| イベント | 代表的な原因 | 回避/抑制の可否 |
|---|---|---|
| メンバー離脱 | Pod/VM 再起動、デプロイ、クラッシュ | 静的メンバーシップとローリングで抑制可 |
| ハートビート切れ | GC/CPU 飽和、ネットワーク遅延、session.timeout.ms 設定不一致 | チューニングと監視で抑制可 |
| max.poll 超過 | 重い処理で poll 間隔が延びる、バッチ肥大化 | 処理分割・backpressure・max.poll 設定で抑制可 |
| パーティション増加 | スケール要件対応 | 不可避だが Cooperative で影響縮小可 |
発生条件の概念マップ
代表的なコンシューマ設定(発生回避の土台)
# 心拍とメンバー健全性
session.timeout.ms=... # 過度に短い/長いは不安定化
heartbeat.interval.ms=... # session.timeout の分数に収める
# アプリ処理健全性
max.poll.interval.ms=... # 処理が長いなら適切に延長
max.poll.records=... # 1 回の処理量を制御して超過を防ぐEager 方式(Range/Sticky など)は再均衡開始時に全メンバーがいったん全パーティションを revoke し、割り当て完了まで読むのを止めます。単純で互換性が広い反面、停止時間が伸びがちです。
Cooperative Sticky は増分的に譲り合う方式で、影響のあるパーティションのみを段階的に移譲します。複数ラウンドを経て安定化しますが、多くのケースで総停止時間は短くなります。
| 項目 | Eager 系(Range/Sticky) | Cooperative Sticky |
|---|---|---|
| 停止時間の傾向 | 長い(全 revoke) | 短い(影響範囲のみ段階的に revoke) |
| 収束ラウンド | 通常 1 | 複数(増分適用) |
| 重複・取りこぼしリスク | リスナー実装が弱いと上がる | 段階的移譲で抑制しやすい |
| 互換性/要件 | 広範に可 | 対応クライアントで明示設定が安全 |
Eager と Cooperative の時間挙動(概念)
Eager:
[Revoke all]----[Assign all]----[Resume]
^ 全停止
Cooperative:
[Revoke impacted]--[Assign subset]--[Resume some]--[Next round]--[Stable]
^ 影響範囲のみ停止アサイン戦略の設定例
# Cooperative(推奨・対応クライアント)
partition.assignment.strategy=[org.apache.kafka.clients.consumer.CooperativeStickyAssignor]
# Eager(互換優先)
# partition.assignment.strategy=[org.apache.kafka.clients.consumer.StickyAssignor]
# または RangeAssignor を明示コンシューマの有効停止時間は、revoke から resume までの区間と、アプリの処理中断・再初期化コストの和で決まります。Cooperative では対象が一部に限定されるため、合計としての空白が短くなります。
アプリ側のコミット設計が未熟だと、リバランスに伴う重複処理や取りこぼしのリスクが上がります。onPartitionsRevoked での同期コミットと、再割り当て時の初期化を明確にしましょう。
| パラメータ | 主な作用点 | 誤設定時のリスク |
|---|---|---|
| max.poll.interval.ms | アプリ処理の許容最大時間 | 超過で強制離脱→頻繁なリバランス |
| session.timeout.ms | メンバー存続の猶予 | 短すぎると誤検知、長すぎると障害検知が遅い |
| max.poll.records | 1 回の処理件数 | 大きすぎると処理延伸、小さすぎるとオーバーヘッド |
タイムライン(単一メンバーの視点)
time --->
[poll]--process--process--RebalanceStart--revoke--commit--assign--init--resume--process
^ 停止窓口処理の一時停止と再開の基本パターン
// revoke 受領で安全停止
consumer.pause(currentPartitions);
consumer.commitSync();
// 必要なクローズ処理...
// assign 受領で再初期化
// for (tp : assigned) { seekToCommitted(tp); }
consumer.resume(assignedPartitions);停止時間を下げる近道は、発生頻度を減らし、発生時の影響範囲を狭めることです。Cooperative Sticky と静的メンバーシップの併用、適切なハートビート・ポーリング設定、計画的スケールが柱になります。
ローリングデプロイ時は静的メンバーシップでスロットを保持しつつ、1 台ずつ入れ替えると再分散の波及を抑えられます。
| 手法 | 期待効果 | 補足/注意 |
|---|---|---|
| Cooperative Sticky | 影響範囲のみ段階的移譲で短時間化 | 同一グループで統一、互換性確認 |
| 静的メンバーシップ | ローリング時の不必要なリバランス抑制 | group.instance.id はグループ内で一意 |
| ハートビート調整 | 誤検知減・検知時間の適正化 | 過度の短縮は負荷増、長過ぎは検知遅延 |
| 段階的スケール | 大規模再分散の回避 | 各段階でレイテンシとラグを観測 |
静的メンバーシップのスロット保持イメージ
設定とローリングの基本例
# 静的メンバー + Cooperative
partition.assignment.strategy=[org.apache.kafka.clients.consumer.CooperativeStickyAssignor]
group.instance.id=order-svc-1 # グループ内で一意
# ローリング手順(概念)
# 1) 1 台ずつ停止
# 2) すぐに同一 group.instance.id で起動
# 3) 安定化を確認して次の台へリバランスの過多はアプリ停止時間とレイテンシ悪化に直結します。クライアントとブローカのメトリクス、ログ、CLI を組み合わせて早期検知・切り分けを行います。
典型的な兆候は rebalances-total の急増、heartbeat-rate の低下、RebalanceInProgressException の多発です。原因がアプリ処理か、インフラ遅延か、設定かを切り分けます。
| 指標/ログ | 意味 | アクション |
|---|---|---|
| rebalances-total の増加 | リバランス頻発 | 発生源の時間帯・デプロイと突き合わせ |
| heartbeat-rate 低下 | 心拍遅延/停止 | GC/CPU/ネットワークを調査、タイムアウト再調整 |
| RebalanceInProgressException | リバランス衝突 | リトライとリスナー処理の健全性確認 |
グループ状態の遷移(概念)
よく使う運用コマンド
# 現在の割り当てとラグ
kafka-consumer-groups --bootstrap-server <bkr:9092> --describe --group <group>
# グループのメンバー一覧
kafka-consumer-groups --bootstrap-server <bkr:9092> --describe --members --group <group>
# オフセットを安全に調整(計画メンテ用)
# 実行前に --dry-run で必ず確認
kafka-consumer-groups --bootstrap-server <bkr:9092> --group <group> --topic <t> --reset-offsets --to-latest --dry-runCCDAK / CCAAK
問題 1
コンシューマグループの停止時間を最小化しつつローリングデプロイを行いたい。最も効果が高く、公式の挙動に沿った対策はどれか。
正解: A
Cooperative Sticky は段階的な譲り合いで停止時間を縮小し、静的メンバーシップはローリング時の不要な再分散を抑制する。B は max.poll 超過検知を過敏化し逆効果、C は障害検知が遅れ空白が伸びる、D は一時的な全停止を招きやすい。
コーディネータのフェイルオーバーは必ずリバランスを引き起こしますか?
メンバーの再参加は発生し得ますが、必ずしも大規模な再割り当てとは限りません。短時間の空白や再同期は起こり得るため、クライアントの再試行とリスナー実装を堅牢にしておくことが重要です。
パーティション数を増やすと何が起こりますか?
グループは新しいパーティションを含めて再計算し、リバランスが発生します。Cooperative を使うと影響範囲のみ段階的に移譲され、停止体感を抑えられます。閑散時間帯の実施と監視が推奨です。
session.timeout.ms と max.poll.interval.ms の違いは?
session.timeout.ms は心拍ベースのメンバー存続時間で、ネットワークやプロセス健全性を監視します。max.poll.interval.ms はアプリ処理の健全性で、poll 呼び出し間隔が長過ぎると不健全と見なされ離脱します。両者は独立だが、どちらの超過もリバランス誘因になります。
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-...