Apache Kafka は、しばしば一連の概念として説明されます。トピック、パーティション、ブローカー、プロデューサー、コンシューマー、レプリカ、オフセット、リーダー、フォロワー、そしてコンシューマーグループです。

最初のうちは、それでうまくいきます。

そして、最初の障害が話題に上ります。

ブローカーが落ちます。フォロワーが遅れ始めます。ISR が縮小します。プロデューサーが acks=all を使います。コンシューマーは読み続けますが、ハイウォーターマークまでしか読めません。コントローラー選出が起こります。あるリージョンが利用できなくなります。突然、システムは静的な図ではなくなります。それは意思決定のタイムラインになるのです。

そして、ここで Kafka を教えるのが難しくなります。

個々の概念が理解不可能だからではなく、興味深い振る舞いは、それらが相互作用したときにのみ現れるからです。

だからこそ私たちは Kafka シミュレータ を作りました。これは、安全に壊して一歩ずつ再生できる、ブラウザベースで決定的な Kafka のモデルです。Apache Kafka 4.3 のセマンティクスで動作し、バックエンドを必要とせず、あなたのシナリオに関するテレメトリを一切送信しません。

Kafka の障害はホワイトボードでは説明しづらい

Kafka に関するいくつかの問いは、尋ねるのは簡単でも、可視化なしで答えるのは驚くほど難しいものです。

  • レプリケーションファクターが 3min.insync.replicas2 で、ブローカーが 1 台落ちたとき、何が起こるか?
  • 2 台目のブローカーが落ちると、何が変わるか?
  • 最初の障害の後でもプロデューサーが書き込めるのに、なぜ 2 度目の障害の後には NotEnoughReplicas を受け取り始めるのか?
  • acks=all は正確には何を待っているのか?
  • なぜハイウォーターマークが進まなくなったのか?
  • ブローカー障害の後、どのレプリカがリーダーになるのか?
  • アンクリーンリーダー選出は実際には何を失うのか?
  • 健全なクラスタ、劣化したクラスタ、そしてまだ生きているが耐久性保証をもはや満たせないクラスタ、その違いをどう説明するか?

これらは、静的な図が崩れ始める瞬間です。

Kafka は分散システムです。そこには時間、順序、障害、回復、そしてトレードオフがあります。最も重要な学びは、しばしば遷移のなかに隠れています。障害の前と後、リバランスの前と後、コントローラー選出の前と後、そして ISR が変わる前と後です。

Kafka が動く様子を見るためのシミュレータ

シミュレータの目標はシンプルです。Kafka の振る舞いを可視化することです。

Kafka の設定を変更し、シナリオを実行するか自分でクラスタを構築し、それを壊し、そして何が起こったかを一歩ずつ調べることができます。「健全」から「障害」へと飛ぶのではなく、シミュレータはその間のタイムラインを露わにします。

  • シナリオを一時停止できます。
  • 前後にステップ移動したり、タイムライン上の任意の瞬間へスクラブしたりできます。
  • ブローカー、パーティション、レプリカ、プロデューサー、コンシューマー、オフセット、ISR、ハイウォーターマーク、そしてメトリクスを調べられます。
  • Why タブを開いて、現在の状態を平易な言葉で説明したものを読めます。
  • Metrics タブを開いて、その状況でどの Kafka メトリクスが動くかを見られます。
プロデューサーの Inspector パネル: acks=all、冪等性オン、リトライ、リトライバックオフ、linger.ms、圧縮、そしてパーティショナーの選択。
シミュレータ内の任意のエンティティを調べられます。ここではプロデューサー: acks、冪等性、バッチング、リトライ、そしてパーティショナーがすべて編集可能です。

これは特に障害時の振る舞いを教えるのに役立ちます。実際の Kafka クラスタでは、障害はノイズが多く、同時並行的で、しばしば切り分けが困難です。シミュレータでは、同じ障害が制御された学習の瞬間になります。

「なぜこの produce リクエストは失敗したのか?」と問うことができます。

  • そしてイベントを 1 つ戻ります。
  • そして 1 つ進めます。
  • そして ISR を調べます。
  • そしてハイウォーターマークを確認します。
  • そしてプロデューサーの設定を現在のレプリカ状態と比較します。

要点は、最終結果を見せることだけではありません。要点は、その結果に至る道筋を理解できるようにすることです。

定番の例: acks=allmin.insync.replicas

最もシンプルで役に立つウォークスルーの 1 つは、最良の教材の 1 つでもあります。これはシミュレータのホームページにある定番のデモであり、フリープレイのサンドボックスで実際に手を動かして再現できます。

次の設定から始めます。

  • レプリケーションファクター: 3
  • min.insync.replicas: 2
  • プロデューサーの acks: all
orders という名前のトピックのトピック設定パネル。パーティション 3、レプリケーションファクター 3、min.insync.replicas 2。
定番のセットアップ: レプリケーションファクター 3、min.insync.replicas 2 のトピック。

健全なクラスタでは、プロデューサーがリーダーに書き込み、フォロワーがレコードをレプリケートし、ハイウォーターマークが進み、レコードはコミット済みになります。

では、ブローカーを 1 台落としてみましょう。

クラスタは劣化しますが、まだ書き込み可能です。同期しているレプリカがまだ 2 つあるので、プロデューサーは acks=all を満たせます。これが重要な境界です。システムはもはや完全には健全ではありませんが、設定された耐久性保証はまだ維持できています。

では、もう 1 台ブローカーを落としてみましょう。

同期しているレプリカは 1 つだけになります。リーダーはまだ生きているかもしれませんが、プロデューサーは min.insync.replicas=2 をもはや満たせません。書き込みは NotEnoughReplicas で失敗します。

broker-1 と broker-2 がダウンしたシングル DC クラスタ。broker-3 が生き残ったリーダーで、ISR が min.insync.replicas を下回ったためプロデューサーはリトライを繰り返して止まっている。
3 台中 2 台のブローカーがダウン。生き残ったリーダーはまだデータを保持していますが、ISR が min.insync.replicas を下回っているため、acks=all のプロデューサーはリトライを繰り返すことしかできません。

この区別こそが、Kafka の信頼性に関する核心的な学びの 1 つです。

クラスタは利用可能であり得ます。 リーダーは存在し得ます。 トピックにはまだデータがあり得ます。 それでも、耐久性の契約を満たせないために書き込みが拒否されることがあるのです。

これはまさに、ISR、リーダー、プロデューサーのリクエスト、ハイウォーターマーク、そしてメトリクスの変化を 1 つの画面でまとめて見られると、はるかに理解しやすくなる類の概念です。

一歩ずつの学習のために作られています

シミュレータの各シナリオは、操作して進められるサンドボックスとして設計されています。

再生し終わると消えてしまう固定のアニメーションを眺めているわけではありません。デバッガのようにシナリオの中を移動できます。

シナリオが番号付きのステップに分割され、それぞれに短い説明が付いた Steps タブ。クリックすると再生ヘッドが移動する。
どのシナリオも操作して進められる、一歩ずつのウォークスルーです。任意のステップをクリックすると、そこへ再生ヘッドがジャンプします。

すべてのイベントは、決定的でシードに基づいたタイムラインの一部です。それを再生し、一時停止し、前に進め、後ろに戻し、各瞬間の状態を調べられます。これにより、デモだけでなく、ワークショップ、オンボーディング、デバッグの議論、アーキテクチャレビューにも役立ちます。

シナリオの全状態は URL にエンコードされます。シナリオ、クラスタ設定、あなたが行ったすべてのアクション、シード、そしてタイムライン上の位置です。つまり、シナリオは再現可能なリンクとして共有できます。同じ設定、同じシード、同じタイムライン、同じ障害の瞬間です。

これにより、シミュレータは次のような説明に役立ちます。

「このリンクを開いて、ブローカー 2 が落ちる瞬間まで移動してください。」

「では ISR を確認してください。」

「では 1 ステップ進めて、リーダー選出を観察してください。」

「ではプロデューサーのエラーを見てください。」

「ではそれをメトリクスの動きと比較してください。」

記憶を頼りに Kafka の振る舞いを説明する代わりに、具体的で調査可能な状態を指し示すことができます。

最初の 1.0 リリースで提供されるもの

最初の 1.0 リリースでは、Fundamentals をテーマとした、シングル DC に絞ったバージョンのシミュレータから始めます。

このリリースは、基礎的な Kafka 学習に集中しています。トピック、パーティション、オフセット、キーとパーティショニング、ブローカー、レプリカとリーダー、ログエンドオフセットとハイウォーターマークの違い、プロデューサーの確認応答(acks=0acks=1、acks のトレードオフ、そして acks=1 の耐久性のギャップ)、コンシューマーのフェッチループ、グループメンバー間のパーティション割り当て、そしてリバランスです。

これは 13 個のガイド付きシナリオとして提供され、それぞれに固定されたゴールデントレースが付属します。さらに、自分自身のシングル DC クラスタを構築して実験できるフリープレイのサンドボックスもあり、上述の acks=all の耐久性ウォークスルーも含まれています。

最初のリリースの目標は、私たちが内部に持っているすべてのシナリオを公開することではありません。目標は、コアとなる仕組みをしっかりと教える、安定して理解しやすいプレイグラウンドを提供することです。

つまり、最初の公開バージョンは、その背後にあるシミュレータエンジンよりも意図的に小さくしてあります。説明、エッジケース、視覚的な状態が整う前にすべての高度なモードを公開するよりも、Kafka を明快に説明する信頼できるシナリオ群をリリースすることを選びます。

カテゴリ別にグループ化されたシナリオライブラリ — Anatomy、Producers and EOS、Consumer groups、Replication、Tiered storage、Disaster recovery、Schema Registry、Authorization、Share groups — それぞれにシナリオ数が付いている。
シミュレータの背後にある完全なシナリオライブラリ。1.0 リリースでは Fundamentals を提供し、その他のパックはおおむね隔週のペースで展開されます。

次に来るもの

シミュレータエンジンは、最初のパックが公開する範囲よりもはるかに多くをすでにモデル化しており、新しいシナリオパックはおおむね隔週のペースで追加されます。変更履歴で、何が公開済みで、次に何が来るかを追跡できます。

今後のパックでは、レプリケーションと min.insync.replicas の境界、配信セマンティクスとトランザクション、ストレージとライフサイクル、コントローラーとクォータ、カオスと障害のラボ、そしてマルチ DC 災害復旧(アクティブ-パッシブ、アクティブ-アクティブ、ストレッチ 3-DC および 2.5-DC クラスタ、DC フェイルオーバー、オブザーバー昇格、ネットワーク分断、遅いブローカー、アンクリーンリーダー選出)のガイド付きシナリオを追加します。

これらのシナリオは強力ですが、慎重に扱う必要もあります。マルチ DC の Kafka の振る舞いはトレードオフに満ちています。印象的に見えても誤った教訓を与えてしまうデモを作るのは簡単です。私たちは高度なシナリオが堅実で、説明可能で、前提としている仮定について誠実であってほしいと考えています。だからこそ、それらは一度にではなく、段階的に展開されるのです。

ストレッチ 2.5-DC トポロジ: データセンター dc-a は停止、dc-b はリーダーを持つアクティブ、dc-c はウィットネス。生き残ったデータセンターのオブザーバーが昇格中。
近日公開: データセンターを 1 つ失った後のストレッチ 2.5-DC クラスタ — 生き残った側のオブザーバーが昇格して、パーティションを書き込み可能に保ちます。

理解しやすくしたい障害モード

Kafka の信頼性は 1 つの機能ではありません。それは一連のトレードオフです。

シミュレータは、それらのトレードオフを具体的な障害モードを通じて説明できるように設計されています。

  • ブローカー障害
  • 遅いフォロワー
  • ネットワーク分断
  • ISR の縮小
  • リーダー選出
  • アンクリーンリーダー選出
  • プロデューサーのリトライ挙動
  • コンシューマーの位置とラグ
  • DC フェイルオーバー
  • オブザーバー昇格
  • レプリケーションラグ
  • 障害後の回復

これらのうちのいくつかは、最初のリリースですでに探索できます。コンシューマーの位置とラグ、acks=1 の耐久性のギャップ、そしてフリープレイのサンドボックスでの手を動かすブローカー障害です。残りは、カオスとマルチ DC のパックとともに登場します。

データセンター全体を分断または破壊したり、KRaft クォーラムを停止したりするコントロールを備えた Failure Lab パネル。
近日公開: Failure Lab — データセンター全体を隔離または破壊したり、KRaft クォーラムを停止したりして、クラスタの反応を観察します。

重要なのは、それぞれの障害が同じ教育的な問いに答えるべきだということです。

  • 何が変わったか?
  • なぜ変わったか?
  • まだ安全なものは何か?
  • もはや保証されないものは何か?
  • 何かがおかしいことを、どのメトリクスが教えてくれるべきか?

優れたシミュレータは、赤いアイコンを見せるだけであってはいけません。その背後にあるシステムの状態を説明すべきなのです。

Why タブ

シミュレータの最も重要な部分の 1 つが Why タブです。

シナリオが興味深い状態に達すると、シミュレータはクラスタがなぜそのように振る舞っているのかを説明します。

たとえば、ブローカー障害の後、可視化はプロデューサーがまだ書き込めることを示すかもしれません。Why タブは、ISR が min.insync.replicas を満たすのに十分なレプリカをまだ含んでいると説明します。

2 度目の障害の後、プロデューサーは NotEnoughReplicas を受け取り始めるかもしれません。Why タブは、acks=all が設定された最小数の同期レプリカを必要とするのに、現在の ISR が小さくなりすぎていると説明します。さらに、その原因となったパーティションやブローカーを直接指し示してくれます。

3 つのパーティションが min.insync.replicas を下回っているため acks=all の書き込みが NOT_ENOUGH_REPLICAS で拒否されていることを説明し、推奨される対処も示す Why タブ。
拒否された書き込みに対する Why タブ: 3 つのパーティションが min.insync.replicas を下回っているため、acks=all が NOT_ENOUGH_REPLICAS で失敗しています — そして回復方法も提案します。

これにより、障害は視覚的なイベントから学習のイベントへと変わります。

目標は「これは失敗した」と言うことだけではありません。 目標は「この保証をもはや満たせなくなったために、これは失敗した」と言うことです。

メトリクスも同じ物語を語るべき

シミュレータには Metrics タブも含まれています。なぜなら、本番環境では Kafka の問題はたいていメトリクスを通じて診断されるからです。

フォロワーが遅れると、ISR の健全性と under-replicated パーティションの読み取り値にそれが現れます。acks=all の書き込みがリトライし始めると、リトライ数が動き、produce スループットが下がります。クラスタが回復すると、それらの読み取り値は再び落ち着きます。各メトリクスは、それを最後に動かしたイベントへとリンクされているので、数値とそれが変化した瞬間を結びつけられます。

シミュレータのメトリクス値は教育用であって、本番での計測の代わりにはなりません。それらは方向として正しく、シナリオの状態に紐づいていることを意図しています。学習者がクラスタで見るものと、実際の環境で監視するであろう種類のシグナルとを結びつけられるようにするためです。

これが重要なのは、Kafka の学習ではしばしばアーキテクチャと運用が切り離されてしまうからです。シミュレータは、それらを再びつなげようとします。

ブローカー障害は、ブローカーのアイコンが赤くなることだけではありません。それは ISR の縮小であり、under-replicated パーティションであり、起こりうるリーダー選出であり、プロデューサーの挙動の変化であり、メトリクスの動きでもあるのです。

誠実なシミュレーション、魔法ではない

私たちはシミュレータを役立つものにしたいと考えていますが、同時に誠実なものにもしたいと考えています。

これはブラウザの中で実際の Kafka クラスタを動かしているわけではありません。オペレーティングシステムのスケジューリング、ディスク I/O、ページキャッシュの挙動、GC の停止、実際のネットワークバッファ、TLS ハンドシェイク、バイト単位で正確なシリアライズをシミュレートしているわけではありません。

これは Kafka の振る舞いを表す、決定的で教育的なモデルです。順序、状態遷移、障害の帰結、そして設定のトレードオフを説明するために作られています。正確なスループット、レイテンシ、本番のパフォーマンスを予測するために作られているわけではありません。

その区別は重要です。シミュレータは、正しいメンタルモデルを築く手助けをするときに価値があります。実際よりも正確であるかのように振る舞い始めると、危険なものになります。

そこでシミュレータには、モデルの限界を明示したページが含まれています。何がモデル化され、何が近似され、何が省略されているかを説明しています。

改善にご協力ください

私たちはまた、バグや誤った挙動を報告するための公開リポジトリも用意しました。

これが重要なのは、Kafka はエッジケースに満ちており、シミュレーションのバグは教育上のバグだからです。シナリオが誤った説明、誤った状態遷移、あるいは誤った障害の結末を提示しているなら、私たちはそれを知りたいのです。

シミュレータは、Kafka をさまざまな方法で使う人々からのフィードバックがあれば、最も速く改善します。プラットフォームチーム、開発者、SRE、トレーナー、コンサルタント、そして Kafka クラスタが想定と違う振る舞いをした理由を説明しなければならなかったことのあるすべての人々です。

何かおかしく見えたら、ぜひ報告してください。

シングル DC のプレイグラウンドから始めましょう

最初のリリースは土台です。シングル DC の学習に焦点を当てた、ブラウザベースの Kafka シミュレータです。安全な実験のために設計されています。バックエンドは不要です。実際のクラスタも要りません。自由に物事を壊し、シナリオを再生し、URL を共有し、すべてのステップを調べられます。

フリープレイのクラスタ設定パネル: ブローカー数、KRaft ボーター、コントロールプレーン、ラック、そしてラックアウェアな配置のトグル。
フリープレイのクラスタ設定 — ブローカー、KRaft ボーター、ラック、そしてラックアウェアな配置。

マルチ DC と災害復旧のシナリオが次に来ます。アクティブ-パッシブ、アクティブ-アクティブ、ストレッチ 3-DC、ストレッチ 2.5-DC、DC フェイルオーバー、そしてオブザーバー昇格を含みます。

今はまず、基本から始めましょう。プレイグラウンドを開いて、シングル DC のフリープレイクラスタを起動し、次を行ってください。

replication.factor=3 を設定します。

min.insync.replicas=2 を設定します。

acks=all を設定します。

ブローカーを 1 台落とします。

そしてもう 1 台落とします。

Kafka は、それが動く様子を見られるようになると理解しやすくなります。

そして、安全に壊せるようになると、さらに理解しやすくなります。