Kafka

Kafka Cooperative Rebalance: Stop-the-world を避ける最新プロトコル

2026-04-19
NicheeLab編集部

従来の Eager Rebalance は全コンシューマーが一斉にパーティションを手放すため、短時間でも“全停止”が発生しやすく、遅延やスループット低下の原因になっていました。

Cooperative Rebalance は割り当てを段階的・増分で移し替えることで Stop-the-world を避ける最新のプロトコルです。ここでは仕組み、導入手順、コールバック設計、運用の勘所を CCDAK 受験にも役立つ視点で解説します。

なぜ Stop-the-world が起きるのか(Eager Rebalance の限界)

Eager Rebalance では、メンバーの増減や設定変更をきっかけに、グループ内の全コンシューマーが一度すべてのパーティションを手放し、再割り当てを待ちます。短時間でも消費停止が全体に波及するため、レイテンシ尖りや処理スループットの落ち込みを招きます。

実務ではローリングデプロイ、スケールアウト、ネットワーク揺らぎ等が頻発し、再均衡の回数が増えがちです。Stop-the-world を抑えることは、そのまま SLO の安定やピーク時の耐性に直結します。

  • 全メンバーが一斉に revoke → assign されるのが Eager の本質的ボトルネック
  • 長時間処理とコミットのズレがあると重複処理や遅延が目立つ
  • 再均衡のたびにキャッシュ温め直しや接続張り直しが発生しやすい

Eager Rebalance(従来)の典型設定例

props.put("partition.assignment.strategy", java.util.List.of(
  "org.apache.kafka.clients.consumer.RangeAssignor"
));
// デフォルトは RangeAssignor(Eager)で、全メンバーが一旦 revoke される

Cooperative Rebalance の仕組み(増分・段階的な再均衡)

Incremental Cooperative Rebalancing は、必要最小限のパーティションのみを段階的に移動します。既存メンバーの大半は割り当てを維持したまま、移動対象だけを revoke/assign するため、Stop-the-world を避けられます。

コンシューマー側は ConsumerRebalanceListener のコールバックで、revoke されたものだけを安全にコミット・解放し、assign されたものを消費開始します。グレースフルに revoke できなかった場合のために onPartitionsLost が呼ばれるケースを考慮します。

  • 段階的に移行するため、全体停止が起きにくい
  • onPartitionsRevoked は“本当に外れるパーティションだけ”が渡る
  • onPartitionsLost は異常時の最終手段(未コミット処理の扱いに注意)
  • Sticky かつ Cooperative により、パーティションの移動量を最小化
戦略挙動Stop-the-world主なコールバック
Eager (Range/RoundRobin/Sticky)全メンバーが一度全パーティションを手放す発生しやすいonPartitionsRevoked/Assigned(Lost は想定外)
CooperativeSticky必要最小限のみ増分移動(段階的)ほぼ回避可能onPartitionsRevoked/Assigned/Lost
Sticky(Eager)移動量は抑えるが全 revoke は発生軽減するが回避は不可onPartitionsRevoked/Assigned

増分的な移動イメージ(Cooperative Rebalance)

revoke P1move P1 onlyConsumer A (before)P0, P1Consumer B (before)P2, P3Consumer A (after)P0Consumer B (after)P2, P3, P1Cooperative では P1 のみ増分的に A→B へ移動。A は P0 を保持し続け、B も P2/P3 を手放さない。全体停止を回避

Cooperative Sticky Assignor の有効化

props.put("partition.assignment.strategy", java.util.List.of(
  "org.apache.kafka.clients.consumer.CooperativeStickyAssignor"
));
// 可能なら全メンバーで同一戦略に統一すること

安全な導入手順(ローリング切替の勘所)

同一コンシューマーグループ内では、実効的に選ばれるアサイナーは“共通集合の先頭”になります。混在期間は予期せぬフォールバック(Eager 化)を招くため、切替は計画的に行います。

最も安全なのは、全メンバーを CooperativeStickyAssignor をサポートするバージョンへ先に上げ、その後に戦略を統一するか、新しい group.id へ移行する方法です。

  • ローリング時は一時的に Eager 挙動へ戻る可能性がある点に注意
  • group.instance.id(静的メンバーシップ)併用でリバランス頻度をさらに低減
  • 互換性不明な混載は避け、観測しながら段階的に切替える

安全な切替(例: 新 group.id を用いた段階移行)

# 1) 先にアプリを CooperativeStickyAssignor 対応版へデプロイ
# 2) 新しい group.id で起動し、旧グループから段階的にトラフィック移行
props.put("group.id", "orders-consumer-v2");
props.put("partition.assignment.strategy", java.util.List.of(
  "org.apache.kafka.clients.consumer.CooperativeStickyAssignor"
));

コールバックとコミット設計(実装の落とし穴)

Cooperative では revoke されるパーティションだけを整然と閉じられます。onPartitionsRevoked 内では、対象パーティションの未処理を flush/commit し、外部リソースを解放します。onPartitionsAssigned では新規割り当ての初期化を軽量に行います。

onPartitionsLost は異常系(グレースフルに返却できなかった)で呼ばれます。ここでは“未処理が確実に再処理されうる”前提で、状態を破棄・再初期化する方が安全です。

  • 同期コミットかつ対象パーティションのみコミット(不要な全体コミット回避)
  • 長時間処理は max.poll.interval.ms を十分に確保
  • 外部ストア(DB/キャッシュ)のハンドルはパーティション単位で管理すると楽

ConsumerRebalanceListener の骨子(Java)

consumer.subscribe(List.of("orders"), new ConsumerRebalanceListener() {
  @Override
  public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
    // revoke 対象だけを同期コミット・クローズ
    commitOffsetsFor(partitions);
    closeResourcesFor(partitions);
  }
  @Override
  public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
    // 必要最小の初期化。重い処理は避ける
    initStateFor(partitions);
  }
  @Override
  public void onPartitionsLost(Collection<TopicPartition> partitions) {
    // 異常系。未処理は再処理前提で状態を破棄
    dropStateFor(partitions);
  }
});

運用チューニングと監視ポイント

Stop-the-world を避けられても、再均衡そのものは発生します。タイムアウトやハートビートはアプリの処理時間と整合させます。特に max.poll.interval.ms は“1回の poll で処理できる最大時間”に見合う値が必要です。

監視では consumer lag、rebalancing の発生回数・時間、onPartitionsLost の有無に着目します。静的メンバーシップ(group.instance.id)や cooperative の採用で、グループの churn を最小化します。

  • session.timeout.ms と heartbeat.interval.ms の整合(セッション切れを回避)
  • max.poll.interval.ms はワークロード最長処理時間 + 余裕
  • 長い GC や外部 API 待ちが続くと離脱扱いになり得る点に注意
  • kafka-consumer-groups.sh で lag と安定性を定期点検

監視・点検コマンド例

$ kafka-consumer-groups.sh \
  --bootstrap-server broker:9092 \
  --group orders-consumer \
  --describe

# 再均衡の兆候はアプリログ(JoinGroup/SyncGroup)やメトリクスで確認

CCDAK 視点の要点と出題パターン

CCDAK では、Eager と Cooperative の違い、CooperativeStickyAssignor の利点、関連コールバック(特に onPartitionsLost)、静的メンバーシップ併用による安定化といった論点が頻出です。

設定の優先順位や混在時の挙動、ローリングデプロイ時の安全策、コミット設計の原則(重複許容・順序性)を、正確な概念として押さえておくと得点に直結します。

  • キーワード: CooperativeStickyAssignor, Incremental Rebalancing, onPartitionsLost, group.instance.id
  • Eager は一斉 revoke、Cooperative は最小限 revoke という対比を即答できること
  • 導入手順の安全策(全メンバー更新 → 戦略統一 or 新 group.id 移行)

試験で問われやすい設定キー(抜粋)

# コンシューマー設定(代表例)
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor
max.poll.interval.ms=900000
session.timeout.ms=45000
heartbeat.interval.ms=15000
group.instance.id=orders-c1   # 静的メンバーの例(ユニークに)

問題で確認

CCDAK

問題 1

コンシューマーグループのスケールアウト時に Stop-the-world を最小化したい。最も適切なアプローチはどれか。

  1. partition.assignment.strategy を CooperativeStickyAssignor に統一し、必要なら group.instance.id も設定する
  2. max.poll.interval.ms を小さくし、頻繁に再均衡を発生させて割り当てを最適化する
  3. StickyAssignor を使用しつつ、再均衡前に全メンバーを一時停止するスクリプトを用意する
  4. RoundRobinAssignor を使用し、パーティションを均等化して処理を平準化する

正解: A

CooperativeStickyAssignor は増分・段階的な再均衡で Stop-the-world を避ける。静的メンバーシップの併用でリバランス自体も減らせる。B は逆効果、C は運用負荷かつ Eager の限界を解決しない、D は Eager で全 revoke を避けられない。

よくある質問

Cooperative にすると二度取り(重複処理)は完全になくなる?

いいえ。Stop-the-world を避ける仕組みであり、重複処理の可能性は依然としてあります。重複許容な処理設計(冪等化、正確なオフセットコミット)と組み合わせて整合性を保ちます。

onPartitionsLost は必ず発生する?

通常は発生しません。ネットワーク断や長時間の停止で“グレースフルに返却できなかった”場合に呼ばれます。ここでは未処理データが再処理される前提で、局所状態を破棄して再初期化するのが安全です。

混在環境で徐々に CooperativeSticky に切り替えてよい?

同一グループで戦略が混在すると、共通集合の先頭にフォールバックし、Eager 挙動に戻る場合があります。安全なのは、全メンバーを対応版に更新してから戦略を統一するか、新しい group.id に移行する方法です。

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

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.