Apache Kafka

大規模なリアルタイムデータストリーミングのための分散メッセージングプラットフォーム

メッセージングストリーム処理

Apache Kafka とは

Apache Kafka は、LinkedIn 社内で生まれ Apache Software Foundation に寄贈された分散ストリーミングプラットフォームである。ASF のインキュベーターに入ったのが 2011 年 7 月、トップレベルプロジェクトとして卒業したのが 2012 年 10 月で、以来イベントストリーミングの代表的な実装として使われ続けている。処理規模の実例として、寄贈元の LinkedIn は 2019 年の技術ブログで、1 日あたり 7 兆メッセージ規模を Kafka で扱っていると公表している。

設計上の最大の特徴は、メッセージを「読んだら消える待ち行列」ではなく「追記されていくログ」として扱う点にある。コンシューマーが読み終えてもメッセージは削除されず、トピックごとに設定した保持期間が来るまでブローカーに残る。だから同じデータを別々の用途で独立に読めるし、下流のバグに気づいたときは過去の位置まで巻き戻して読み直せる。従来のメッセージキューと発想が違うのは、ほぼこの 1 点に由来する。

Kafka の基本概念

Kafka の構造で最初に押さえるべきは、パーティションとコンシューマーグループの対応関係である。

Topic "orders"  ─ Partition 0Partition 1Partition 2

Consumer Group A (Consumer 2 台)      Consumer Group B (Consumer 1 台)
  A1 ← Partition 0, Partition 1         B1 ← Partition 0, 1, 2
  A2 ← Partition 2

グループ A とグループ B は、同じ 3 つのパーティションをそれぞれ独立に読む。パーティションがグループ間で分け合われるわけではない。一方、1 つのグループの内側では、あるパーティションを読むコンシューマーは常に 1 台だけになる。公式の設計解説も、各パーティションは購読中のコンシューマーグループごとにちょうど 1 台のコンシューマーに割り当てられ、そのコンシューマーの位置は次に読むメッセージのオフセットという 1 個の整数で表せると説明している。

ここから実務上の上限が出てくる。グループ内のコンシューマーをパーティション数より多く並べても、余った分は何も割り当てられずに待機するだけで、処理能力は増えない。並列度を上げたいなら先にパーティションを増やす。逆に順序が要る処理では、同じキーのメッセージが同じパーティションへ入りパーティション内では書かれた順に読めるという性質を使い、キー設計で順序保証の範囲を決める。

概念説明
Topicメッセージのカテゴリ (例: orders, payments)
PartitionTopic を分割した単位。並列度の上限を決め、順序保証もこの単位で成立する
Producerメッセージを Topic に送信
ConsumerTopic からメッセージを読み取り
Consumer Group同じグループ ID を名乗る Consumer の集合。グループ単位でパーティションを分担する
BrokerKafka サーバー。クラスターを構成
Offsetパーティション内の読み取り位置を示す整数。コミットした値が次回の開始点になる

オフセットはブローカーが勝手に進めるものではなく、コンシューマーが「ここまで読んだ」とコミットする値である。コミット先はクラスター側なので、コンシューマーのプロセスが落ちても、同じグループ ID で立ち上げ直せば続きから読める。任意の古いオフセットへ意図的に巻き戻して読み直すこともできる。

落とし穴はコミットのタイミングにある。処理を終える前にコミットすると、その直後に落ちたメッセージは誰も処理しないまま飛ばされる。処理を終えてからコミットすると、コミット前に落ちた分は再起動後にもう一度届く。どちらに倒すかは Kafka ではなくアプリケーション側の設計判断で、後者 (少なくとも 1 回) を選ぶなら、同じメッセージが 2 回来ても結果が変わらない処理を書いておく必要がある。

Kinesis との比較

同じ用途で候補に挙がる Kinesis Data Streams との差は、容量の上限が値として定義されているかどうかに集約される。Kafka は自分でブローカーを並べるので上限は用意した台数とディスク次第、Kinesis はシャードという単位ごとに上限が数値で決まっている。

観点Kafka (MSK)Kinesis Data Streams
管理MSK でマネージドフルマネージド
スループットブローカー台数とパーティション数で拡張1 シャードあたり書き込み 1 MB/s または 1,000 レコード/s
保持期間設定次第 (期限なしも可)最大 8,760 時間 (365 日)・最小 24 時間
読み取りConsumer Group を増やせば同じデータを何度でも1 シャードあたり読み取り 2 MB/s、GetRecords は 5 回/s。拡張ファンアウトで登録コンシューマーを分離できる
エコシステムKafka Connect, Kafka StreamsLambda 統合
コストブローカーのインスタンス時間 + ストレージシャード時間 (プロビジョンドモード)
適用場面大規模、既存 Kafka 資産AWS ネイティブ、小〜中規模

上限が値で決まっている側は、必要な流量からシャード数を逆算できる代わりに、流量が伸びたらシャードを増やす操作が必要になる (キャパシティモードにはシャードを自分で決めるプロビジョンドと、自動で追随するオンデマンドがある)。上限が台数次第の側は、その見積もりを自分で背負う代わりに設定の自由度が高い。AWS に閉じたシンプルな構成なら Kinesis、大規模で Kafka エコシステムを活用するなら MSK を選択する。以上の Kinesis 側の数値は 2026 年 8 月時点の公式ドキュメントの値である。

ZooKeeper から KRaft へ

長らく Kafka は、クラスターのメタデータ (どのブローカーが生きているか、どのパーティションのリーダーが誰か) の管理を Apache ZooKeeper に任せていた。Kafka クラスターの隣に ZooKeeper アンサンブルを立てるのが当然の構成で、運用対象が 2 つに増えるうえ、メタデータの反映がクラスター規模の上限にもなっていた。

これを置き換えたのが KRaft で、メタデータを Kafka 自身の内部ログとして持ち、Raft をもとにした合意方式でコントローラーを選ぶ。KRaft が本番利用可と位置づけられたのは 3.3 で、4.0 では ZooKeeper モードそのものが削除された。したがって 4.0 系以降のブローカーは KRaft でしか動かず、ZooKeeper モードで動いているクラスターは 4.0 へ上げる前に KRaft へ移行しておく必要がある (2026 年 8 月時点の公式アップグレード手順)。手元の手順書や社内 Wiki が ZooKeeper 前提のまま残っていると、バージョン更新のときにここで止まる。

MSK (Managed Streaming for Apache Kafka)

AWS MSK は Kafka のマネージドサービスで、ブローカーのプロビジョニング、パッチ適用、モニタリングを AWS が担う。MSK Serverless を使えばクラスターの容量管理も不要になり、トピックのパーティション配置まで自動で扱われる。ただし課金項目にパーティション時間が入るので、流量が小さくてもトピックとパーティションを気軽に増やす設計だと料金が積み上がる (2026 年 8 月時点の料金体系)。

タイプ管理負荷コスト
MSK Provisioned中 (ブローカー数を指定)インスタンス時間 + ストレージ
MSK Serverless低 (容量とパーティション配置を自動管理)クラスター時間 + パーティション時間 + データ転送 + ストレージ

ユースケース

  • イベントソーシング: 全イベントを Kafka に永続化し、状態を再構築
  • CDC (Change Data Capture): DB の変更を Kafka 経由で下流システムに伝播 (Debezium)
  • ログ集約: 複数サービスのログを Kafka に集約し、OpenSearch や S3 に転送
  • リアルタイム分析: ストリーム処理エンジン (Kafka Streams, Flink) でリアルタイム集計

採用を判断するとき効くのは、ここまでの上限の話よりも「読み直せること」を要件に組み込めるかどうかである。下流のシステムを作り替えたくなったとき、保持期間の内側であれば新しいコンシューマーグループを立て、過去のイベントから状態をもう一度組み立て直せる。この余地が要らない、ただ通知を届けたいだけの用途なら、ブローカーとパーティションを抱える運用コストは過剰になる。

この記事は役に立ちましたか?

関連用語

関連する記事