2 つのパックを同時に出します。v1.5 — ストレージとライフサイクル、そして v1.6 — 運用・コントローラー・クォータです。合わせて Kafka Simulator に19 本の新しいシナリオが加わり、カリキュラムは 122 本中 74 本に到達。フリープレイは v1.3 で始まったクラスタ形状の階段を完成させます。
今回はフリープレイから始めます。最も要望が多かったのがこの 2 つの解放だからです。
フリープレイ: トポロジーの階段が完成
v1.3 以来、サンドボックスはパックごとにクラスタ形状を 1 つずつ増やしてきました — まずアクティブ/パッシブ、次にアクティブ/アクティブ。どちらも非同期ミラーでつながれた2 つのクラスタです。今回着地する 2 つは別種のもの — データセンターをまたいで引き伸ばされた 1 つのクラスタで、レプリケーションは同期、ISR 自体が WAN をまたぎます。
違いは、何かが壊れた瞬間に現れます。
- ミラー構成でリージョンを失うのはフェイルオーバーです。反対側を昇格させ、ミラーがまだコピーしていなかった分は受け入れます。
- ストレッチクラスタで DC を失うのはレプリケーションの出来事です。ISR が縮み、まだ書けるかどうかは
min.insync.replicasだけで決まります。
3-DC ストレッチ(v1.5 の新機能)
3 つのデータセンター、1 つのクラスタ。既定のサンドボックスは dc-a・dc-b・dc-c それぞれにブローカー 1 台とコントローラー 1 台を置き、ブローカーはインターリーブされるのでラウンドロビン配置が各パーティションのレプリカを 3 拠点すべてに分散させます。パーティションは 3 つなので、各 DC が自然なリーダーを 1 つ持った状態で開きます — 孤立した 1 パーティションではなく、DC をまたいだ均衡したリーダーシップが見えるレイアウトです。
KRaft クォーラムは 3 拠点にまたがって 1 つだけ存在します(リージョンごとに 1 つではありません)。DC を 1 つ落とすと 3 票のうち 1 票を失いますが、残る 2 票が依然として過半数を構成し、クラスタは意思決定を続けられます。3 拠点にする理由を、具体的な形で示したものです。
2.5-DC ストレッチ(v1.6 の新機能)
最後の段です。データ用のデータセンター 2 つに加えて、コントローラーの票だけを持ちデータをまったく持たない 3 つ目のウィットネス拠点。
Confluent の MRC 形状です。各データ DC は同期レプリカ 2 つとオブザーバー 1 つを持ちます — 同期セットで RF 4、min.insync.replicas は 3。オブザーバーについて 2 点。
- オブザーバーは ISR に数えられないので、
acks=allの書き込みを待たせません。すべてのコミットをゲートする WAN 越しのレプリカはレイテンシ的に破滅的ですが、オブザーバーなら書き込みパスの代償を払わずにリモートコピーを保てます。 - ISR が
min.insync.replicasを下回ると、オブザーバーは自動昇格して耐久性を回復できます。サンドボックスの既定は「ISR 低下で昇格し、DC 復旧時に降格」。昇格したままにする設定も、自動をオフにして手動で行う設定もあります。
ウィットネスは、このリリースのコントローラー系シナリオと直結します。クォーラムは奇数の投票者を好みますが、そのために 3 つ目のフルデータセンターを買うのは高い — だから半分だけ買うのです。シナリオ 06.0.2(「KRaft クォーラム」)は、まさにウィットネスが防ぐための障害で終わります。いまはその両方の構成をサンドボックスで組んで比べられます。
これで5 つのクラスタ形状すべてが利用可能になりました: シングル DC、アクティブ/パッシブ、アクティブ/アクティブ、3-DC ストレッチ、2.5-DC ストレッチ。残るフリープレイの解放 — v1.7 の障害ラボ、v1.8 の Kafka CLI ターミナル、v1.9 のガバナンス — はいずれも新しい形状ではなく新しい機能です。
v1.3 のときと同じ但し書きです: これらのトポロジーを解説する DR カリキュラムの着地は依然として v1.8 です。形状が先に来るのは意図的で、シナリオが語り出す前にアイデアを試せる場所を用意するためです。
それまでにマルチリージョン構成をもっと読んでおきたい方は、SoftwareMill のApache Kafka のディザスタリカバリとマルチリージョンアーキテクチャに関するガイドがおすすめです。これらの形状が内包するトレードオフを丁寧に扱っており、サンドボックスを触りながら別タブで開いておく価値があります。
シナリオ
v1.5 — ストレージとライフサイクル(9 本)
Kafka のログは無限のテープではありません。このモジュールは、書き込まれた後にレコードに何が起きるかを 3 つのグループで扱います。
リテンション — retention.ms と retention.bytes がログ開始オフセットを前進させる様子と、リテンションが既に削除したオフセットを要求したコンシューマーが受け取るもの(OFFSET_OUT_OF_RANGE と、それに続くリセット)。
コンパクション — cleanup.policy=compact がキーごとに最新値を残し、オフセットを保ったまま隙間を残す様子。トムストーンによるキー削除と、削除がパージされる前にコンシューマーがそれを観測できる猶予窓としての delete.retention.ms。そして両方のポリシーを同時に走らせる compact,delete。
階層ストレージ — 古びたログ接頭部をリモート層へオフロードし、読み戻し、ローカルリテンションと総リテンションの違いを見ます。クラスタのサイジングを最も大きく変えるのがこのグループです — ローカルリテンションは、コンシューマーがどこまで遡れるかを縛るものではなくなります。
v1.6 — コントロールプレーン(kraft、4 本)
コントローラーが何をしていて、いなくなると何が止まるのか。
- コントローラーの仕事と KRaft クォーラム — コントローラーが一貫性を保つのはメタデータで、データではありません。クォーラムの過半数を失えばコントローラーは不在になり、リーダーはその場に留まり、投票者が戻るまで新しいことは何も決まりません。
- コントローラーのフェイルオーバーとメタデータのキャッチアップ — 新しいアクティブコントローラーはコミット済みメタデータオフセットに追いつくまで応答できません。フェイルオーバー直後に選出が一瞬凍るのはこのためです。
- ZooKeeper と KRaft — 同じクラスタを 2 つのコントロールプレーンで並べて比較します。
v1.6 — 運用(operations、6 本)
運用者が稼働中のクラスタで何を変えるのか、そしてそれぞれの代償。
- スケールアウトとそれに続くリバランス、そしてブローカーをドレインしてから外すスケールイン。
- 手動でのパーティション再割り当てと、負荷下でスロットルされた同じ再割り当て — 稼働中のトラフィックを守るためにキャッチアップ速度に上限をかけた結果、新しいレプリカが遅れて ISR に加わる様子が見えます。
- 稼働中の設定変更、そしてデータを捨てるのではなく応答を遅らせることでプロデューサーを絞るクライアントクォータ。
次に来るもの
122 本中 74 本、出荷済みパックは 7 つ。フリープレイのサンドボックスは、この先カリキュラムが参照するすべてのクラスタ形状をモデル化できるようになりました。次は v1.7 と障害ラボ — その 5 つの形状のどれにでも、ブローカーの kill やネットワーク分断を任意に注入できるようになります。
シミュレーターを開いて 2.5-DC のサンドボックスを起動し、データ DC を 1 つ落としてみてください。オブザーバーが昇格して min.insync.replicas を下回らないよう支える様子が見られます。