Kafka のアーキテクチャ図:ブローカー、パーティション、レプリカ、コンシューマーグループ

Kafka のアーキテクチャ図を解説。ブローカー、パーティション、リーダーとレプリカ、プロデューサーのキー、コンシューマーグループ、オフセット、KRaft、重要な設定。

· 創業者・開発者

公開日:

Kafka のアーキテクチャ図:ブローカー、パーティション、レプリカ、コンシューマーグループ

Kafka は、矢印が出入りする「Kafka」と書かれた 1 つの箱として簡単に描けます。しかしその箱は、人々が頼りにしているすべての性質を隠してしまいます。何が順序付けられ、何が順序付けられないのか、データのコピーがいくつあるのか、ブローカーが落ちたらどうなるのか、そして複数のサービスがお互いに干渉せずに同じストリームをどう読めるのか、です。

この記事では、重要な構成要素を備えた Kafka クラスターを図にします。ブローカー、トピックとパーティション、リーダーとフォロワーのレプリカ、キーを持つプロデューサー、コンシューマーグループとオフセット、そしてクラスターを管理する KRaft コントローラーです。

トピック、パーティション、ブローカー

トピック は、orders のような名前の付いたレコードのストリームです。各トピックは パーティション に分割され、各パーティションは追記専用のログで、すべてのレコードに増え続ける オフセット が付きます。

パーティションはあらゆるものの単位です。

  • 順序: レコードはパーティション内では順序付けられますが、パーティションをまたいだ順序はありません。
  • 並列性: 1 つのグループ内でトピックを消費できるコンシューマーの数は、最大でもパーティション数までです。
  • 配置: パーティションは、クラスターのサーバーである ブローカー に分散されます。

パーティション数は、トピックごとに必要なスループットと、並列に動かしたいコンシューマーの数から、余裕を持たせて決めます。後からパーティションを追加することもできますが、キーがどのパーティションに割り当てられるかが変わります。

レプリケーション

各パーティションにはレプリケーション係数があり、通常は 3 です。1 つのレプリカが リーダー として読み書きを処理し、残りはリーダーのログをコピーする フォロワー です。追いついているフォロワーは ISR(in-sync replica の集合)を構成します。リーダーのブローカーが落ちると、追いついているフォロワーが新しいリーダーになります。

耐久性を決める設定は次のとおりです。

設定 場所 典型的な値 効果
replication.factor トピック 3 各パーティションのコピー数
min.insync.replicas トピックまたはブローカー 2 書き込みが有効になる前に、その書き込みを持っている必要があるレプリカの数
acks プロデューサー all 成功とする前にすべての同期レプリカを待つ

係数 3、min.insync.replicas=2、acks=all の組み合わせでは、確認応答された書き込みは少なくとも 2 台のブローカーに存在し、ブローカーが 1 台停止していてもクラスターは書き込みを受け付け続けます。これらの設定とその相互作用については、Kafka のドキュメント で説明されています。

プロデューサーとキー

プロデューサーは、レコードごとにパーティションを選びます。キーがある場合、デフォルトのパーティショナーはキーをハッシュするので、同じキーを持つレコードはすべて同じパーティションに入り、順序が保たれます。キーがない場合、レコードはバランスのために分散され、レコード間の順序は失われます。

キーは、イベントの順序を保つ必要があるエンティティから選びます。注文 ID やアカウント ID です。図ではプロデューサーにキーを書き込みましょう。キーは、プロデューサーが持つ設定の中で最も影響の大きいものです。少数の巨大な値に偏るキーは避けます。パーティションがいくつあっても、1 つのホットキーが 1 つのパーティションに負荷を集中させるからです。

再試行によってレコードが重複することがあります。最近の Kafka はデフォルトで冪等プロデューサーを有効にしており、パーティション内でプロデューサーの再試行による重複を取り除きます。ただし、アプリケーション自身の再試行による重複は依然として起こりうるので、コンシューマーも冪等にしておくべきです。

コンシューマーグループとオフセット

コンシューマーグループ は、1 つの目的のために作業を分担するコンシューマーの集まりです。Kafka は各パーティションをグループ内のちょうど 1 つのコンシューマーに割り当てるので、パーティションが 3 つなら忙しく働けるコンシューマーは最大 3 つで、4 つ目は遊んでしまいます。コンシューマーが参加したり離脱したりすると、グループはリバランスし、パーティションが移動します。

各グループは自分の位置、つまりパーティションごとのコミット済み オフセット を管理し、Kafka はそれを内部トピックに保存します。これによって、複数のサービスが同じストリームを独立して読めます。fulfillment と analytics はそれぞれ自分のグループと自分のオフセットを持ち、お互いに影響しません。

オフセットを処理の前ではなく後にコミットすると、at-least-once の処理になります。クラッシュの後、コンシューマーは最後のコミット以降のレコードを再処理します。繰り返しが無害になるよう、処理を冪等にしておきましょう。

リテンションとコンパクション

Kafka は、レコードが読まれた後も保持します。時間またはサイズに基づくリテンションは、たとえば 7 日後に古いセグメントを削除します。一方、ログコンパクションはキーごとに最新のレコードを無期限に保持し、トピックを現在の状態の変更履歴(changelog)に変えます。トピックごとに選びましょう。イベントには通常リテンションを使い、「顧客ごとの最新の住所」のような状態にはコンパクションを使います。

サイジングの計算例

チェックアウトがピーク時に 1 秒あたり 3,000 件の注文イベントを生成し、それぞれ約 1 KB、つまり 3 MB/s だとします。fulfillment サービスの 1 つのコンシューマーは 1 秒あたり 400 件のイベントを処理できます。ピーク時には少なくとも 8 つのコンシューマーを並列に動かす必要があるので、パーティションも少なくとも 8 つ必要です。成長と、障害を起こしたコンシューマーのパーティションの分の余裕を残すために 12 を選びます。レプリケーション係数が 3 なら、クラスターはブローカー全体で 9 MB/s をディスクに書き込み、このレートで 7 日間保持すると、複製後のデータは最大で約 5.4 TB になります。平均トラフィックはピークより少ないので、これはディスク計画の上限と考えてください。こうした数字は図の隣に置くべきです。ブローカーの台数とディスクを決めるのは、Kafka と書かれた箱ではなく、これらの数字だからです。

KRaft:ZooKeeper はもう不要

以前のクラスターはメタデータを ZooKeeper に保存していました。現在の Kafka は、KRaft と呼ばれる Raft ベースのコントローラーのクォーラムで、メタデータを自ら管理します。2025 年 3 月にリリースされた Kafka 4.0 は、ZooKeeper なしで完全に動作する最初のメジャーリリースです。図では、小規模なクラスターが同じマシンで両方の役割を動かしている場合でも、コントローラーのクォーラムはブローカーとは別に描きましょう。

アーキテクチャ図

2 つのプロデューサーがキー付きのイベントを 3 台の Kafka ブローカーに送ります。各ブローカーは 1 つのパーティションのリーダーで、残り 2 つのフォロワーです。KRaft コントローラーがメタデータを管理します。3 つのコンシューマーからなる fulfillment グループはそれぞれ 1 つのパーティションを読み、analytics のコンシューマーは自分のグループで全パーティションを読みます。

12 個のコンポーネント · 9 個の接続

Archboard で開く
ダイアグラムの内容
  • Checkout service
  • Payments service
  • Broker 1: P0 leader, P1 P2 followers
  • Broker 2: P1 leader, P0 P2 followers
  • Broker 3: P2 leader, P0 P1 followers
  • KRaft controllers
  • Consumer group: fulfillment
  • Consumer 1
  • Consumer 2
  • Consumer 3
  • Analytics consumer
  • order 8812 to P0
  • order 9001 to P2
  • replicate
  • same events, separate group
  • metadata
3 台のブローカーからなる Kafka クラスター。1 つのトピックに 3 つのパーティションがあり、それぞれ全ブローカーに複製されています。プロデューサーは注文 ID をキーにし、1 つのコンシューマーグループが 3 つのコンシューマーでパーティションを分担し、2 つ目のグループは同じイベントを独立して読みます。

図の読み方は次のとおりです。

  • 左: 2 つのプロデューサーが注文 ID をキーにしてイベントを送ります。注文 8812 はパーティション 0 に、注文 9001 はパーティション 2 にハッシュされます。
  • 中央: 3 台のブローカーがあり、それぞれ 1 つのパーティションのリーダーで、残り 2 つのフォロワーです。破線のエッジはレプリケーションを示し、下にある KRaft コントローラーがメタデータとリーダー選出を管理します。
  • 右: fulfillment グループには、パーティションごとに 1 つずつ、3 つのコンシューマーがいます。analytics のコンシューマーは別のグループに属しているので、自分のオフセットですべてのイベントを読みます。
  • Markdown ブロック には、この図が前提としているトピックの設定を並べています。

Kafka の図に描くべきもの

  • トピックごとのパーティション数とキー: 順序と並列性を決めるからです。
  • レプリケーション係数と min.insync.replicas: 耐久性を決めるからです。
  • 名前付きの各コンシューマーグループ: コンシューマーと一緒に描きます。
  • トピックごとのリテンションまたはコンパクション。
  • 誰が生成し、誰が消費するか: サービスをまたいで描き、責任の所在を明確にします。

Kafka の上に構築するパターンについては、イベント駆動アーキテクチャの図、データベースから確実にパブリッシュするための トランザクショナルアウトボックスパターン、Kafka から分析へデータを流す データパイプラインのアーキテクチャ図 を参照してください。

Archboard で作る

  1. Google または GitHub でサインインし、図を作成します。
  2. C4 モデルパックからプロデューサー用に コンテナ ノードを追加し、説明にキーを書きます。
  3. データパックからブローカー用に Kafka ノードを 3 つ追加し、それぞれがリーダーとフォロワーを務めるパーティションをラベルに書きます。KRaft コントローラー用に コンテナ を 1 つ追加します。
  4. 基本パックからコンシューマーグループ用に フレーム を追加し、その中にコンシューマーごとに コンテナ を置きます。2 つ目のグループ用に別のコンシューマーも追加します。
  5. レプリケーションを破線のエッジで描き、トピックの設定を書いた基本パックの Markdown ブロックを追加します。

この例で使うダイアグラムノードは 12 個で、Free プランの範囲に収まります。

よくある質問

Kafka はメッセージの順序を保証しますか? パーティション内では保証します。パーティションをまたぐ順序は保証しません。順序を保つ必要があるレコードが同じパーティションに入るよう、キーを使います。

トピックにはいくつのパーティションが必要ですか? 必要なスループットと、並列に動かしたいコンシューマーの数を満たし、成長の余地もある数です。後から数を変えると、キーとパーティションの対応が変わります。

ブローカーが落ちるとどうなりますか? そのブローカーがリーダーだった各パーティションについて、別のブローカー上の追いついているフォロワーがリーダーになります。レプリケーション係数 3 と min.insync.replicas=2 なら、書き込みは続きます。

コンシューマーグループとは何ですか? トピックのパーティションを分担するコンシューマーの集まりです。異なるグループは、それぞれ自分のオフセットで同じトピックを独立して読みます。

Kafka にはまだ ZooKeeper が必要ですか? いいえ。Kafka 4.0 以降は KRaft モードでのみ動作し、コントローラーのクォーラムがクラスターのメタデータを管理します。

無料で始める — 1 シート、クレジットカード不要。

関連記事

← ブログに戻る

1分でキャンバスを開く

Google または GitHub でサインイン。1シートは無料で、チームが加わったらアップグレード。