v1.8 は 11 本の新しいシナリオからなる dr モジュールを追加し、Kafka CLI ターミナルをフリープレイに持ち込みます。

今回のリリースは、Kafka の中でも難しい部類のアーキテクチャに焦点を当てています。ストレッチクラスタ、マルチリージョン構成、フェイルオーバー、MirrorMaker 2、そしてディザスタリカバリです。さらに、ターミナルから直接操作する 9 本のシナリオを収めたトラック 13 も加わります。合計で20 本の新しいシナリオとなり、カリキュラムは 134 本中 100 本に到達します。

v1.8 の内容

クラスタのトポロジー自体は新しいものではありません。v1.3 以来、フリープレイに登場してきました。まずアクティブ/パッシブとアクティブ/アクティブのミラーペア、続いて 3-DC と 2.5-DC のストレッチクラスタです。

欠けていたのは、それらを取り巻くカリキュラムでした。v1.8 は 11 本のシナリオを追加し、これらのアーキテクチャが問題の起きたときにどう振る舞うのか、なぜそれぞれ異なる形で壊れるのか、そしてその障害が実際に何を意味するのかを順にたどります。

ストレッチクラスタ(6 本)。 複数の拠点に広がる 1 つの Kafka クラスタです。ここで DC を失うことは、リージョンのフェイルオーバーではなく、レプリケーションの問題になります。

  • 2-DC - acks=all の書き込みは両方の拠点に存在するので、どちらの拠点を失っても耐久性が保たれます。
  • 3-DC と 2.5-DC - 3 票中 2 票の過半数、あるいはウィットネス拠点が、DC 障害の後もコントローラー選出を機能させ続けます。2.5-DC 構成では、生き残った DC のオブザーバーが自動的に ISR へ昇格し、min.insync.replicas を回復させます。
  • ウィットネスのない 2-DC - 偶数の投票者が二分されるとクォーラムが失われ、接続が回復するまでリーダー選出が止まります。
  • リーダー DC の喪失と、1 つの DC 内での分断 - リーダーシップは生き残った拠点へ移ります。DC 内のリンクが切れると、パーティションが min.ISR の下限に達するところまで、孤立したレプリカが脱落していきます。

ミラークラスタ(5 本)。 MirrorMaker 2 でつながれた 2 つの独立した Kafka クラスタです。ここでリージョンを失うことは、別のクラスタへのフェイルオーバーを意味します。

  • ミラーラグと RPO - レプリケーションリンクを切ってラグを積み上げ、フェイルオーバーして、どのレコードが向こう側に届かなかったのかを正確に確かめます。
  • アクティブ/アクティブ - 各リージョンが自分のリージョン固有のトピックを所有し、それを反対側へミラーします。
  • オフセット変換 - 別のクラスタへ移ったコンシューマーは、元のオフセットをそのまま再利用することはできません。MM2 のチェックポイントがオフセットを変換し、コンシューマーは直近のチェックポイント以降の末尾を再生します。
  • フェイルバック - 元のプライマリを戻して再同期し、データを失うことなく順方向のレプリケーションを再開します。

Kafka CLI ターミナルエミュレータ

v1.8 のもう 1 つの大きな柱は、下からせり上がるターミナルドロワー(Ctrl+`)です。シミュレートされたクラスタに対して Kafka CLI コマンドを実行します。

ツールは 15 個あります。kafka-topics、kafka-consumer-groups、kafka-configs、kafka-log-dirs、kafka-reassign-partitions、kafka-leader-election、kafka-get-offsets、kafka-metadata-quorum、kafka-replica-verification、kafka-server-stop、kafka-server-start、kafka-console-producer、kafka-console-consumer、kafka-transactions、そして現在接続しているトポロジーを調べるための cluster-info です。

コマンドは本物の Kafka ツールと同じフラグを使い、おなじみの、桁を揃えた列形式で出力します。シミュレータがコマンドの一部しか実装していない場合は、その --help にそう書かれています。

kafka-consumer-groups --describe --group g1 を実行しているターミナル。パーティション 0 はコンシューマー c1 で LAG 0、パーティション 1 はコンシューマーがおらず(ダッシュで表示)、LAG 4。
シナリオ 13.1.2: メンバーの 1 つがポーリングを止めたため、パーティション 1 にはコンシューマーがおらず、ラグが増え続けています。本物のクラスタで確認するのと同じ列から、そのまま読み取れます。

ログインしているホストが重要です。 プロンプトには現在のホストが表示され、ssh でホスト間を移動でき、ターミナルドロワーにはホストメニューもあります。キャンバス上のブローカーを Alt+クリックすることもできます。

コマンドは、そのホストに紐づくクラスタに対して動作します。たとえばマルチリージョンのトポロジーでは、DR 側のブローカーから kafka-topics --list を実行すると、ソーストピックではなく MirrorMaker 2 のリモートトピックが表示されます。cluster-info が示すのはそのリージョンのクォーラムであり、両クラスタを合わせたビューではありません。

--bootstrap-server を別リージョンのブローカーに向ければ、現在のシェルを離れずにそのクラスタへ問い合わせることもできます。

2 リージョンのトポロジーの上に開いたターミナルドロワー。プライマリリージョンの broker-1 では kafka-topics --list が orders を出力し、同じコマンドに --bootstrap-server broker-3:9092 を付けると primary.orders を出力する。ssh broker-3 の後はプロンプトに dr リージョンが表示され、cluster-info が dr のクォーラムとブローカーを出力する。横の Steps パネルには、同じコマンドがクリックできるチップとして並んでいる。
シナリオ 13.3.1: 同じコマンドでも、どこで実行するかによって問い合わせるクラスタが変わります。Steps パネルのチップは、それぞれのコマンドをターミナルにあらかじめ入力します。

シミュレートされた Kafka ログを、ファイルシステムとして見ることもできます。 ls、cd、tree、du、df、cat、kafka-dump-log は、シミュレータが各ブローカーについて実際に保持しているセグメントを対象に動作します。

セグメントのファイル名にはベースオフセットが使われ、リテンションはセグメントファイルを丸ごと削除します。フォロワーがスロットルされていれば、そのアクティブセグメントがリーダーのものから遅れていく様子も見られます。

broker-1 で ls -lh orders-0 を実行すると、ベースオフセット 0、4、8 の 3 つのセグメントが一覧表示される。ssh broker-3 の後、フォロワーで同じ一覧を表示するとセグメント 0 と 4 だけで、アクティブなセグメント 4 は 4.0K ではなく 2.0K。
シナリオ 13.1.3: リーダーはオフセット 8 のセグメントへロールしている一方、スロットルされたフォロワーはまだセグメント 4 を埋めている最中です。

CLI による読み取りは、シミュレータでいま表示されているフレームを反映します。シミュレーションを一時停止したり、タイムラインをスクラブして巻き戻したりすれば、--describe を実行したときに調べるのはその時点です。

CLI による変更は、ほかのシミュレータ操作と同じように振る舞います。アクションログに追加され、URL で共有でき、フレームごとに再生できます。

ここでの狙いは、学習の転移です。

実際のインシデントでは、kafka-consumer-groups --describe を見て、必要なことを教えてくれるのがどの列なのかをすぐに分かるかどうかが重要になります。ボタンしかないシミュレータでも概念は示せますが、その作業の流れまで本当に教えることはできません。

DR がこれほど後に来る理由

ディザスタリカバリは、それまでに登場したほぼすべてを束ねます。レプリケーション、コンシューマーオフセット、コントローラークォーラム、リテンション、そして障害への対処です。

それらの要素に慣れてからのほうが理解しやすいため、DR モジュールはカリキュラムのこれほど後半に置かれています。

v1.9 では、オブザーバーと Cluster Linking で同じ領域を引き続き扱います。

シミュレータを開いてデータセンターをフェイルオーバーさせ、それからターミナルを開いて、ラグを自分の目で確かめてみてください。