導入
Tencent Cloud Message Queue の Kafka コアの責任者である Lu Shilin 氏は、Kafka アーキテクチャで遭遇する問題と課題、Kafka エラスティック アーキテクチャ ソリューションのアナロジーから、「Tencent Cloud における Kafka 階層ストレージの実践と進化」の素晴らしい共有をもたらしました。 、Kafka 階層 Tencent Cloud における Kafka 階層ストレージの実践と進化について、ストレージ アーキテクチャと原則、Tencent Cloud の実装と実践という 4 つの側面から詳細に共有します。
Kafka アーキテクチャが直面する問題と課題
カフカのアーキテクチャ
上の図は、Kafka 自体の現在のアーキテクチャです。Tencent Cloud がオンライン環境に Kafka クラスターを展開する場合、Zookeeper または Kraft をメタデータ ストレージとして使用し、物理マシンまたは VM をコンピューティング リソースとして、ローカル ディスクをストレージ メディアとして使用してクラスターを構築します。
ただし、この展開モデルには次の問題があります。
1. データがローカルに保存されるため、ローカル状態が比較的重くなり、運用保守操作にはデータの移行が必要となり、運用保守が複雑になります。
2. この導入モデルではリソースがブローカー次元にあるため、オンライン運用保守時はブローカーノード次元で拡張・縮小が行われますが、ノード次元のリソースはCPU、帯域幅、ディスクに分割されます。など、これらはブローカー ノード ディメンションに直接存在します。ノード ディメンションの処理によりリソースが無駄に消費されます。
3. オンライン サービス プロセス中に、障害回復や大量の履歴データの処理などのシナリオが発生します。履歴データを処理すると、履歴データのバックトラッキングの問題が発生し、ページ キャッシュが汚染され、全体的な読み取りおよび書き込みの SLA に影響します。クラスター。
次に、これら 3 つの質問を踏まえて、具体的なシナリオを見てみましょう。
運用・保守の難しさ
上で述べたように、Kafka クラスターでは特定の運用および保守操作中にデータの移行が必要となるため、運用および保守がより困難になります。
次の 3 つの状況があります。
1. ノード間のデータの不均一な分散
定常状態では、Kafka のパーティション パーティションがさまざまなブローカー ノードに均等に分散されていることは誰もが知っていますが、パーティションはトピックに属し、トピックにはさまざまなビジネス シナリオがあり、異なるビジネス シナリオ間のトラフィックは異なります。ノードのパーティションが均等であっても、データが均等に分散されていない可能性があります。
2. ノード システム インジケーターのボトルネック (帯域幅、ディスク、CPU など)
単一ノードの一部の物理リソースでシステムのボトルネックが発生し、ノードをアップグレードまたは拡張する必要があります。
3. ノード内に大量のデータがあり、移行が遅く、読み取りと書き込みに影響します。
日々のトラフィックが比較的大きく、クラスター内のデータが多すぎる場合は、実際にデータの移行が必要になります。
したがって、上記の3つの問題がデータ再配置につながりますが、データ量が大きい場合、データ再配置には数日レベルの運用保守期間がかかり、実際にはオンラインでは受け入れられません。
資源の無駄遣い
システムのボトルネックを分析するために考慮されるリソースは、基本的に CPU、ディスク、帯域幅、メモリです。
CPU
-
圧縮アルゴリズム (Gzip、Snappy、Zstd など)
-
メッセージフォーマット変換(V0、V1、V2)
Kafka がメッセージ圧縮を使用する場合、サーバー側でメッセージを解凍して検証する必要があり、CPU を大量に消費します (Gzip の圧縮損失は特に大きくなります)。また、クラウド上のクライアント環境は比較的複雑で、クライアントのバージョンや利用シナリオ、利用姿勢なども不明です。
さらに、顧客は Tencent Cloud CKafka クラスターを購入するときにクラスターのバージョン情報に注意を払わない可能性があります。購入したクラスターのバージョンは、使用する SDK のバージョンと一致していない可能性があります。また、メッセージのプロトコル変換も必要となり、これには、たくさんの時間、CPU。
ディスク
-
ストレージスペース、大量のコールドデータストレージ
-
履歴データの Tail-Read 読み取り、ディスク IO ボトルネック
-
HDD ディスクが高スループット下でディスク IO ボトルネックを引き起こす
帯域幅
-
瞬時にトラフィックが急増
-
クラスターのファンアウト/読み取り/書き込み比率が大きい
メモリ
●Broker 電流制限後に大量の Delay 操作が発生する
要約すると、さまざまな使用シナリオ モードで Kafka によって引き起こされるリソースのボトルネックは異なります。オンラインでは、ノードレベルのリソース損失を引き起こす 1 つまたは複数のシナリオが発生する可能性があります。
上記の問題は誰もがよく知っています。これらの問題は、ローカルに保存され、ストレージとコンピューティング リソースが分離されていない、Kafka の重いローカル状態によって引き起こされます。これらの問題を解決するには、比較的成熟したエラスティック アーキテクチャを導入する必要があります。上記の弾力性とリソースの切り離しは、アーキテクチャの実現に役立ちます。
Kafka エラスティック アーキテクチャ ソリューションの比較
ストレージとコンピューティングの分離アーキテクチャ
ストレージとコンピューティングの分離アーキテクチャが最初に考慮され、現在 Pulsar で使用されているアーキテクチャでもあります。Pulsar の基盤となるストレージは Bookkeeper です。写真のアーキテクチャは、ストレージ ベースとして HDFS を使用しています。このアーキテクチャはクラウドネイティブ ストレージです。そしてコンピューティング分離アーキテクチャ。
-
プロキシは、統合アクセス、サービス検出、フォーマット変換を含む電流制限、およびいくつかの一般的に必要な機能のアップロードとフローティングを担当します。
-
ブローカーはパーティションのホルダーとして、HDFS やブックキーパーなどの複数のストレージ メディアのセットに適応するために使用され、パーティション間の負荷分散の役割を果たします。
-
ストレージ層は、HDFS、Tencent Cloud COS、Amazon S3 などのマルチモード ストレージを使用できます。
このアーキテクチャの利点は明らかです。コンピューティング リソースとストレージ リソースが完全に分離されていることがわかります。容量を拡張する場合、次のような利点があります。
-
ノードの拡張にはデータの移行は必要ありません
-
ストレージ ノードはコンピューティング ノードから分離されており、必要に応じて拡張できます。
理論的には利点がありますが、実際の実装には明らかな問題が 2 つあります。
1. HDFS または Bookkeeper では、ファイルを切り取るときに問題が発生します。古いファイルは Recover Lease である必要があり、新しいファイルはメタデータ (Zookeeper/Etcd などに強く依存する) を保存する必要があるため、ファイルを切り替えるときに不具合やジッターが発生します。
2. このアーキテクチャでは、ストレージ システムと HDFS が実際に強い依存関係にあることがわかります。これが壊れると、生産と消費が実行できなくなり、システムが回復するのを待つしかなくなります。
これら 2 つの問題はオンライン上で深刻な問題であり、これらをホストする非常に信頼性の高いストレージ システムを見つけるのは困難です。システム設計プロセスでは強い依存性はお勧めできません。外部システムへの依存性を弱くすることが最善です。
柔軟なローカルストレージアーキテクチャ
2 番目のアーキテクチャは、現在 CKafka の比較的一般的なアーキテクチャであり、コア ロジックはクラウド ディスク + クラウド ホストであり、クラウド ディスクの LVM と組み合わせた自動化されたオペレーション システムとクラウド ホストのライブ マイグレーションに依存して、急速な拡張を実現します。 。
自動運用システムはリソースの使用状況を監視するために使用されます。たとえば、100G のディスクが使用されており、90G が使用されている場合、自動運用システムを使用してディスクの 90% を監視できます。ディスクの拡張が必要な場合は、その後、クラウド ディスクを自動的に適用し、LVM を使用してストレージ容量とスループットを向上させることができます。
自動運用システムはコンピューティングリソースノードの動作も監視し、監視の結果、CPUやメモリなどのコンピューティングリソースにボトルネックがあることが判明した場合には、Tencent Cloud CVMやコンテナのライブマイグレーションを利用してコンピューティングリソースを垂直アップグレードします。
これは Tencent Cloud Online で現在使用されている一連の製品アーキテクチャですが、前述したように、この製品アーキテクチャには欠陥があります。「垂直方向にしか拡張できませんが、分散システムはすべて分散されています。垂直方向の拡張だけでは絶対に不十分です。水平方向の拡張機能が必要です。したがって、このシステムは水平方向の拡張の分野ではネイティブの Kafka システムに似ています。」という質問です。
柔軟なリモートストレージアーキテクチャ
したがって、上記の 2 つの柔軟なアーキテクチャによって引き起こされる問題を考慮して、著者は、ローカル ストレージとリモート ストレージを組み合わせることができるかどうかを確認するために、いくつかの新しい可能性を検討しました Kafka の階層ストレージは、少量のホット データをクラウド ディスク上にローカルに保持します。 、リモートストレージには大量のコールドデータが保存されます。
ローカルのエラスティックストレージ
-
ローカル ストレージ サービスはトラフィック/テール読み取りを書き込み、ネイティブ Kafka と同じレイテンシ、可用性、一貫性を提供します。
-
リモート ストレージの障害やパフォーマンスの低下が発生した場合、ローカル ストレージは柔軟な拡張をサポートし、読み取りおよび書き込みサービスを提供します。
リモートのエラスティックストレージ
-
リモート ストレージ サービス キャッチアップ読み取り、ホット データとコールド データの分離。
-
オンデマンドで使用し、量に基づいて請求します。
-
マルチモードストレージとマルチメディアストレージをサポートします。
アドバンテージ
1. 最初の利点は、書き込み遅延がローカル書き込み遅延と一致していることです。リモート ストレージに障害が発生したり不具合が発生した場合、ローカル ストレージにデグレードし、自動運用システムと組み合わせてローカル ストレージ形式を動的に拡張できます。 。
2. 2 番目の利点は、リモート ストレージが比較的安価であるため、ある程度のコストを削減できることです。
コスト、サービスの安定性、実装可能性を組み合わせて、Kafka の柔軟なアーキテクチャを構築するためにローカル ストレージ + リモート ストレージを選択しました。
Kafka の階層ストレージ アーキテクチャ
次に、現在の階層ストレージの強化がどのように実現されているかについて話しましょう。それを含めることのセマンティクスは何ですか? どのようなデータ ライフサイクル管理を提供できるのでしょうか?
階層ストレージの読み取りおよび書き込みプロセス
積層製造プロセス
制作の主なプロセスはネイティブ Kafka と同様で、クラウド ディスクに書き込まれたデータはリモート ストレージ COS に非同期的に同期されます。
階層的な消費プロセス
消費プロセスも同様です。ユーザーのコンシューマのオフセットに基づいて比較が行われます。ローカルに保存されている場合は、ローカル ストレージが最初に返されます。ローカル ストレージにそれがない場合は、リモート ストレージからリアルタイムで読み取ります。または、メッセージ読み取りを消費するためのさまざまな読み取り戦略に応じたさまざまな読み取り戦略とダウンロード戦略があります。
データのライフサイクル
階層型ストレージの導入後、データはローカルに保存されるだけでなく、リモートおよびローカルのデータ ライフ サイクルの管理も必要になります。
上の 4 つの図は、階層型ストレージが有効になった後の完全なデータ フローです。
1. Kafka Broker がデータを保存するための最小ファイル単位はセグメントです。セグメントは 2 つのタイプに分けられます: アクティブ/非アクティブ。アクティブ セグメントは現在書き込み中のセグメントを指し、非アクティブ セグメントはその逆です。
2. 階層化をオンにすると、非アクティブなセグメントのみがアップロードされます。対応する図では、階層化がオンになった後、最初にセグメント 0 がアップロードされます。
3. Local Retention パラメーター、非アクティブなセグメントがリモート ストレージにアップロードされた後、ローカルのセグメントは実際に削除できますローカルにアップロードされたファイルの保存時間を制御するパラメーター Local Retention がここで設計されています。
4. ネイティブ Kafka に反映される保持パラメータ このパラメータのセマンティクスはトピック データの保存時間であり、図の保持時間後のリモート データ削除に対応します。
これら 1 ~ 4 のステップのステータス フローは、Kafka のローカル データとリモート データのライフサイクル管理を構成します。
オフセット制約
Kafka の各メッセージはオフセット位置に対応しており、メッセージ データにはローカル エンドからリモート エンドへのアップロードが含まれるため、アップロードされるオフセットには特定の制約があります。
図1:
図 II:
図 2 では、左から右に、Lz、Ly、Ry、Lx、Rx です。
-
Lz (ローカル ログ終了オフセット)、ローカル データ内の最新データのオフセット位置。
-
ローカル データの Ly (最終安定オフセット) は、消費可視データです。Kafka には、消費可視/トランザクション可視の 2 つのメッセージ分離レベルがあります。
-
Ry (リモートログ終了オフセット)、リモートデータ内の最新データのオフセット位置。
-
Lx (ローカル ログ開始オフセット)、ローカル データ内の最も古いデータのオフセット位置。
-
Rx (リモート ログ開始オフセット)、リモート データ内の最も古いデータのオフセット位置。
オフセット制約は、Lz >= Ly >= Lx および Ly >= Ry >= Rx の 2 つのルールです。
セグメントステートマシン
前述したように、データはセグメント ディメンションに従ってローカルからリモートにアップロードされるため、アップロード プロセス中に各セグメントはさまざまな状態になります。セグメント状態の転送と状態管理は、セグメント ステート マシンを通じて実現できます。
セグメント状態フローは主に、CopySegment、DeleteSegment、および DeletePartition の 3 つの次元に反映されます。
-
セグメントのコピー
○ コピーセグメント開始 -> コピーセグメント終了
-
セグメントの削除
○ セグメントの削除開始 -> セグメントの削除終了
-
パーティションの削除
○ DeletePartitionMarked -> DeletePartitionStarted -> DeletePartitionFinished
同時に、ある状態から別の状態への遷移には制限があり、たとえば、CopySegmentStarted -> DeleteSegmentStarted だけではなく、CopySegmentStarted から DeleteSegmentStarted までは、CopySegmentStarted -> CopySegmentFinished -> DeleteSegmentStarted であることを保証する必要があります。
階層型ストレージアーキテクチャ
上記では、Kafka 階層ストレージの読み取りおよび書き込みプロセス、データ ライフ サイクル、およびセグメント状態フローを紹介しましたが、これらのロジックは Kafka ネイティブ システムのどこに実装されているのでしょうか?
次の図は、Kafka ストレージ クラス全体とアーキテクチャ図を示しています。
-
Kafka ReplicaManager は、ローカル ストレージ LogManager とリモート ストレージ RemoteLogManager の管理を担当します。
-
ローカル ストレージ LogManager は、ローカル データのライフサイクル管理を担当します。
-
リモート ストレージ RemoteLogManager は、リモート ストレージのライフ サイクル管理とセグメント メタデータ管理を担当します。
○ RemoteStorageManager は、リモート ストレージのライフサイクル管理を担当します。
○ RemoteLogMetadataManager はセグメントのメタデータ管理を担当します。
-
メタデータストレージ
○ ETCD/ZooKeeper はメタデータ ストレージ サービスとして機能し、メタデータのストレージと回復を担当します。
Tencent Cloudの導入と実践
セグメントメタデータ管理
以下に示すように:
-
メタデータ情報の同期には、内部トピックを WAL として利用します。
-
ブローカーは WAL を消費してメモリ ステート マシンの状態を構築します。
-
ブローカーは定期的にメモリ スナップショットのスナップショットと、スナップショットの対応するオフセットをブローカーにローカルに保持します。
-
ブローカーは、ステート マシンの回復のためにスナップショットと増分 WAL に依存します。
消費パフォーマンス
上記の読み書きプロセスで紹介したように、書き込みプロセスは実際にはネイティブ Kafka に似ているため、書き込みパフォーマンスは基本的にネイティブ Kafka と同じですが、履歴データの読み取りスループットなど、読み取りパフォーマンスの方が皆さん気になるかもしれません。 、SLA、およびデータの信頼性。オンライン演習ではリモート ストレージとして COS を使用しましたが、事前演習でストリーミング読み取りに COS Stream を直接使用するとパフォーマンスのボトルネックが発生することがわかりました。読み取りパフォーマンスを向上させるには、次の解決策を使用してください。
1. プリロード方法。メッセージの事前読み取りおよび事前ロード用のメモリ プールを計画します。
2. 空きリソースがあるときに、事前にホットスポット データをダウンロードします。
分離
サードパーティ製ストレージの導入により、オンラインの安定性が最も重要であることは誰もが知っていますが、安定性は活力であるため、その分離も非常に重要です。
ハードディスク
- ディスク IO への影響を軽減する独立した IO ディスク
CPU
-
コアスレッドはコアにバインドされています
-
スレッドの分離
帯域幅
-
アップロード/ダウンロード制限
-
アップロード/ダウンロードタスク並列制御
メモリ
-
オフヒープメモリを使用する
-
ByteBuffer の再利用
ロールバック
-
階層化アップロード機能を一時停止する
-
段階的なデータのダウンロードをオンデマンドで一時停止する機能
-
オペレーティング システムがクラウド ディスク容量を自動的に拡張します
-
トピック/クラスター ディメンションのロールバックのサポート
今後の展望
全体的な実装アーキテクチャは上で明確に紹介しましたが、最後に今後の開発方法について説明します。
データがサードパーティのストレージに保存されると、このデータをより詳細に制御できることは誰もが知っています。データは HDFS に保存されるため、ファイルを操作することができます。
スキーマ
- メッセージ形式の保存 (Protobuf、Json)
現在、ビッグ データとデータ シンボルの概念は業界に広く普及しています。大手工場や企業ではさまざまなシナリオがあります。ブローカーがデータのこの部分を HDFS または COS に転送するときに、スキーマも転送できます。またはProtobuf、Json など Broker は単なるコンピューティング層であり、データをアップロードするだけでなく、Schema 機能を使用したり、データ形式を変換したりすることもできます。
アクセス層
- トラフィック アクセス、ステートレスかつ水平方向にスケーラブル
コンピューティング エンジン
-
フォーマット変換計算レイヤー: 行-列フォーマット変換 (Parquet)
-
寄木細工の床はフーディ/デルタ湖に直接つながっています
-
ファイルを取得するためのクラウド API
ストレージ層
-
マルチモードストレージ、データ分類
-
ソフトウェアとハードウェアを組み合わせて新しいストレージ システムを探索する