著者: ビッグボウルワイドヌードル
この記事は、chatGPT の要約に基づいており、さまざまなブログや偉人の個人 Web サイトの共有によって補足され、最終的に独自の口語的な要約を開始し、Kafka の理論的知識の完全かつ体系的なコレクションを作成するよう努めています。この記事は、基本的な名詞、高度な名詞の分析、Kafka のメカニズムとシナリオの分析、最後に Kafka ソース コード パッケージの簡単な分析の 5 つのモジュールに分かれており、より深く幅広い内容を実現します。
Kafka の基本的な名詞解析
Kafka とは何ですか? また、ブローカー、トピック、パーティション、プロデューサー、およびコンシューマーとは何ですか?
Kafka は、大量のデータとリアルタイム データ ストリームの処理に一般的に使用される、高性能でスケーラブルな分散メッセージ キュー システムです。
-
ブローカー: Kafka クラスターは 1 つ以上の独立したサーバー ノードで構成され、各ノードはブローカーと呼ばれます。各ブローカーは、メッセージの保存、受信、転送 (受信と送信)を担当します。これらは一緒になって分散メッセージング システムを形成します。
-
トピック:トピックは、Kafka のメッセージのカテゴリまたはデータ ストリームの名前です。メッセージはトピックごとに分類され、公開されます。トピックは、一意の識別子を持つメッセージ キューと考えることができます。たとえば、ログ メッセージを受信するトピックと、ユーザー アクティビティ メッセージを受信するトピックが 1 つずつあるとします。
-
パーティション: 各トピックは 1 つ以上のパーティションに分割できます。パーティションはトピックの物理的な分割であり、データの並列処理と分散ストレージを実装するために使用されます。各パーティションは、順序付けられた不変のメッセージのシーケンスです。パーティションはディスク上にファイルとして保存され、ブローカーによって管理されます。
-
プロデューサー: プロデューサーは、メッセージを生成し、Kafka トピックに発行するアプリケーションまたはシステムです。プロデューサは特定のトピックにメッセージを送信する責任を負い、オプションで特定のパーティションにメッセージを送信できます。プロデューサはメッセージをブローカーに送信し、ブローカーはメッセージを永続化し、構成されたレプリケーション ポリシーに従って他のブローカーにレプリケートします。
-
Consumer : コンシューマは、Kafka トピックからメッセージを読み取るアプリケーションまたはシステムです。コンシューマは 1 つ以上のトピックをサブスクライブし、トピックの 1 つ以上のパーティションからメッセージを読み取ります。各コンシューマは独立したコンシューマ グループ識別子を持っているため、複数のコンシューマがトピックからのメッセージを並行して消費できます。
簡単にまとめると、Kafka は一般的に使用される高性能の分散メッセージ キューであり、主にブローカー、トピック、パーティション、プロデューサー、コンシューマーの概念が含まれています。エージェントは、Kafka クラスター内の各サーバー ノードの名前であり、メッセージの保存、受信、転送を担当します。Kafka はパブリッシュとサブスクライブに基づいたメッセージング システムであり、プロデューサーとコンシューマーの間の架け橋がテーマです。各トピックは少なくとも 1 つのパーティションに分割でき、各パーティションは順序付けられたメッセージのセットであり、パーティションの数は最大並列度も表します。プロデューサは、メッセージを生成して Kafka トピックにパブリッシュするアプリケーションまたはシステムであり、コンシューマは、Kafka トピックからメッセージを読み取るアプリケーションまたはシステムです。
ニッチな知識を追加します。
-
パーティションのデータ ファイル (オフセット、メッセージ サイズ、データ)。パーティション内の各メッセージには、次の 3 つの属性が含まれます: offset、MessageSize、data (ここで、offset は、このパーティション内のメッセージのオフセットを表します。Offset は、パーティション データ ファイル内のメッセージの実際の格納場所ではなく、論理 A 値です) offset はパーティション内のメッセージの ID、MessageSize はメッセージ コンテンツ データのサイズを表し、data はメッセージの特定のコンテンツであると考えることができます。
-
データ ファイルのセグメント化 (順次読み取りと書き込み、セグメントの名前付け、バイナリ検索)。パーティションは物理的に複数のセグメント ファイルで構成されており、各セグメントは同じサイズで、順番に読み書きされます。各セグメント データ ファイルには、セグメント内の最小オフセットを使用した名前が付けられ、ファイル拡張子は .log です。このようにして、指定されたオフセットを持つメッセージを検索するときに、二分探索を使用して、メッセージが配置されているセグメント データ ファイルを見つけることができます。
-
データ ファイル インデックス (セグメント化されたインデックス、スパース ストレージ)。Kafka は、セグメント化されたデータ ファイルごとにインデックス ファイルを作成します。ファイル名は、ファイル拡張子が .index であることを除き、データ ファイルと同じです。インデックス ファイルは、データ ファイル内のメッセージごとにインデックスを作成するのではなく、スパース ストレージを使用して、データの特定のバイトごとにインデックスを作成します。これにより、インデックス ファイルが多くのスペースを占有することがなくなり、インデックス ファイルがメモリ内に残ることができます。
Kafka の高度な用語分析
コントローラ
Kafka が開始されると、現在の Broker 情報が Zookeeper に登録されます。最初に登録した人がコントローラーです。登録されたスレーブ ノードのデータを (リスニング メカニズムを通じて) 読み取り、クラスターのメタデータ情報を生成し、これを配布します情報を他のノードサーバーに送信し、他のサーバーがクラスター内の他のメンバーの存在を認識できるようにします。
コーディネーター
Kafka のコーディネーターは、コンシューマー グループとプロデューサーの間のトランザクションの調整と管理を担当する重要なコンポーネントです。これにより、コンシューマ グループがパーティションを正しく割り当てて消費できるようになり、プロデューサ トランザクションの正しいコミットとリカバリが管理されるようになります。
-
消費者グループコーディネーター (グループコーディネーター) : 各消費者グループには消費者グループコーディネーターがいます。これは、消費者グループのさまざまな活動の調整と管理を担当する Kafka ブローカーです。コンシューマ グループ コーディネーターは次のタスクを実行します。
-
新しいコンシューマを登録する: コンシューマがコンシューマ グループに参加すると、コンシューマ グループ自体をコンシューマ グループ コーディネータに登録し、コンシューマ グループの割り当てポリシーを受け取ります。
-
パーティションの割り当て: コンシューマ グループ内のコンシューマの数が変化した場合 (新しいコンシューマの参加や古いコンシューマの離脱など)、コンシューマ グループ コーディネーターは、コンシューマにパーティションを再配布する責任を負います。パーティション割り当て戦略を使用して、ロード バランシングとフォールト トレランスを実現するためにコンシューマにパーティションを割り当てる方法を決定します。
-
コンシューマ グループのオフセットの管理: コンシューマ グループ コーディネーターは、各パーティション上のコンシューマ グループの消費オフセットを追跡および管理する責任もあります。コンシューマ グループのオフセットを Kafka にコミットし、切断またはリバランス後にコンシューマ グループが最後のオフセットから正しく消費を継続できるようにします。
-
プロデューサー トランザクション コーディネーター: Kafka には、Kafka トランザクションの調整の管理を担当するプロデューサー トランザクション コーディネーターもあります。プロデューサー トランザクション コーディネーターは次のタスクを実行します。
-
トランザクションの初期化: プロデューサはトランザクションを開始すると、プロデューサ トランザクション コーディネーターと対話して、トランザクション ID と対応するリーダー コピーを取得します。
-
トランザクションをコミットする: トランザクションが完了すると、プロデューサはトランザクションのコミット要求をプロデューサ トランザクション コーディネーターに送信します。コーディネーターは、トランザクション内のすべてのメッセージが正常に書き込まれたことを確認し、トランザクションのコミット ステータスを Kafka ログに書き込みます。
-
トランザクション回復: トランザクション中にプロデューサが失敗するかクラッシュした場合、プロデューサ トランザクション コーディネーターは、トランザクションの整合性を確保するために回復プロセスを調整する責任があります。
消費者グループ
Consumer Group は、メッセージ コンシューマを編成および管理するために使用されます。公式の紹介によると、コンシューマ グループは、Kafka によって提供されるスケーラブルでフォールトトレラントなコンシューマ メカニズムです。コンシューマ グループには複数のコンシューマ インスタンスが含まれており、各インスタンスはメッセージを並行して消費できます。メッセージ キュー システムは、高いスループットと負荷分散を実現するために、グループ内のコンシューマ インスタンスにメッセージを分散します。パーティションの数を超える同じコンシューマ グループ内のコンシューマはメッセージを消費できないことに注意してください。そのため、コンシューマの数は通常、パーティションの数と同じに設定されます。もちろん、追加のコンシューマはフェイルオーバーのバックアップとして使用することもできます。。
Kafka はコンシューマ グループ設計を使用して 2 つのメッセージ キュー モデルを同時に実装していることに言及する価値があります。すべてのインスタンスが同じグループに属している場合、それはキュー モデルです。すべてのインスタンスが異なるグループに属している場合、パブリッシュ/サブスクライブ モデル (1 対多) が実装されます。
リバランス
リバランスとは、コンシューマ グループ内のコンシューマ インスタンスが変更されたときに、メッセージ キュー システムが各コンシューマ インスタンスに分散されたメッセージを再分散するプロセスを指します。新しいコンシューマ インスタンスの追加、または障害やハートビート タイムアウトによる古いインスタンスの終了により、リバランスが発生します。再バランス処理には時間がかかるため、再割り当て期間中に一部のメッセージが処理されない場合があります。
リバランス プロセスは、結合と同期の2 つのステップに分かれています。
-
参加フェーズでは、すべてのコンシューマー インスタンスがブローカーのコンシューマー コーディネーター (グループ コーディネーター) に参加リクエストを送信します。すべての成功したリクエストを取得した後、コーディネーターはリーダーとなるコンシューマー インスタンスをランダムに選択し、グループ メンバー情報とトピック情報をリーダーに送信し、消費割り当て計画を策定する責任を負います。
-
同期フェーズでは、コンシューマ リーダーは消費計画の割り当てを開始します。つまり、どのコンシューマがどのトピックとどのパーティションを消費するかを決定します。割り当てが完了すると、リーダーは計画を SyncGroup リクエストにカプセル化して送信します。コーディネーター。非リーダーも SyncGroup リクエストを送信しますが、その内容は次のとおりです: 空。割り当て計画を受信した後、コーディネーターはその計画を SyncGroup の応答に詰め込み、各コンシューマーに送信します。このようにして、グループは、どのパーティションを使用する必要があるかを知っています。
メッセージ
Kafka メッセージは、固定長のヘッダーと可変長のメッセージ本文で構成されます。
ヘッダ部はマジック(ファイル形式)1バイトとCRC32(ボディメッセージ本文が正常かどうかを判定するために使用)4バイトで構成されます。magic の値が 1 の場合、magic と crc32: 属性の間にさらに 1 バイトのデータが存在します (圧縮するかどうか、圧縮形式などのいくつかの関連属性を保存します)。magic の値が 0 の場合、存在しません 属性 属性
本文は、次のような特定のキー/値メッセージを含む、N バイトで構成されるメッセージ本文です。
-
キー (オプション): メッセージのキー。パーティション化とメッセージの順序付けに使用されます。キーが指定されている場合、Kafka はキーのハッシュに基づいてメッセージを特定のパーティションにルーティングし、同じキーを持つメッセージの書き込みと読み取りが同じパーティションに行われるようにします。
-
値: 実際のメッセージの内容。通常はバイト配列または文字列です。これは、転送して処理する必要があるデータです。
-
オフセット: パーティション内のメッセージの一意の識別子。パーティション内のメッセージの位置を示します。コンシューマはオフセットを使用して消費の進行状況を追跡し、メッセージが見逃されないようにできます。
-
パーティション (オプション): メッセージが属するパーティション番号。パーティションが指定されていない場合、Kafka はプロデューサーによって構成されたパーティション化ポリシーに基づいてパーティションを自動的に割り当てます。
-
タイムスタンプ (オプション): メッセージのタイムスタンプ。メッセージが作成された時刻を示します。タイムスタンプは、メッセージが実際に生成された時刻であることも、プロデューサーがメッセージを送信するときに明示的に設定されたカスタム時刻であることもできます。
-
ヘッダー (オプション): メッセージに関連するメタデータを保存するために使用されるキーと値のペアのセット。ヘッダーには、メッセージのソース、タイプ、バージョンなどのさまざまなカスタム情報を含めることができます。
トピックのトピック(__consumer_offsets)
Kafka では、__consumer_offsets はコンシューマ グループのオフセット情報を格納するために使用される内部トピックです。これは、特定のトピックのパーティション内で消費する消費者の進行状況を追跡するために使用されます。__consumer_offsets トピックの各メッセージには、次の情報が含まれます。
-
コンシューマグループID
-
トピック名
-
パーティションID
-
コンシューマ グループ内のコンシューマのオフセット (オフセット)
-
メッセージ送信のタイムスタンプ (タイムスタンプ)
この内部トピックを維持することにより、Kafka はパーティション内のコンシューマ グループの使用の進行状況を追跡および管理し、コンシューマがメッセージを正しく処理して障害回復を達成できるようにします。コンシューマーは開始時にトピックからオフセット情報を読み取り、どのオフセットでメッセージの消費を開始するかを決定します。メッセージが処理され、コンシューマがオフセットをコミットすると、この情報もそれに応じて更新されます。同時に、Kafka のコンシューマー コーディネーターは、__consumer_offsets トピックの更新と保守を担当します。コンシューマがコンシューマ グループに参加したり脱退したりするためのリクエストと、コンシューマがオフセットを送信して取得するための操作を処理します。
データファイルとログファイル
データファイル:
Kafka では、データ ファイルは通常、実際のメッセージ データが保存されているKafka サーバー上のファイルを指します。Kafka は、セグメント化されたストレージを使用してメッセージを管理します。各トピックは複数のパーティションに分割され、各パーティションは一連のデータ ファイルに再分割されます。これらのデータ ファイルは、メッセージのコンテンツの保存に使用されます。メッセージがプロデューサーによって Kafka クラスターに送信されると、メッセージは適切に分割されたデータ ファイルに追加されます。コンシューマは、これらのデータ ファイルからメッセージを読み取ることができます。
ログファイル:
Kafka では、ログ ファイルは通常、メッセージを永続化するために使用されるKafka ブローカー上のファイルを指します。Kafka はメッセージの永続化にログを使用し、追加ベースのログ ストレージ モデルを使用します。各トピックの各パーティションには、メッセージを順番に保存する対応するログ ファイルがあります。ログ ファイル内のメッセージは、追加方式で書き込まれ、読み取られます。ログ ファイルが特定のサイズ制限または時間制限に達すると、Kafka はログ ファイルを閉じ、メッセージの保持を継続するために新しいログ ファイルを作成します。
ログインデックス
Kafka がログ レベルで TB レベルのデータをサポートできる理由は 2 つあります。1 つは順次追加ベースのログ書き込み + スパース ハッシュ インデックス(データ ファイルと同様、どちらも最適化にインデックスの概念を使用します)。Kafka のスパース ハッシュ インデックスは、メモリ スペースを節約しながらメッセージの位置と取得を高速化するために、キー メッセージ オフセットを一定の間隔で記録するデータ構造です。
メッセージが Kafka のログ ファイルに書き込まれると、メッセージはパーティションのログの末尾に順番に追加されます。各パーティションには対応するスパース ハッシュ インデックスがあり、重要なメッセージ オフセットが記録されます。これらのインデックスは、各メッセージのオフセットを記録しませんが、一定の間隔でいくつかのキー メッセージ (通常は連続メッセージ) のオフセットを記録します。スパース ハッシュ インデックスを使用する利点は、インデックスのサイズを大幅に削減できるため、メモリ領域を節約できることです。
コンシューマが特定のオフセットでメッセージを読み取る必要がある場合、まずスパース ハッシュ インデックスを通じてターゲット オフセットに最も近いレコードを見つけ、次にターゲット メッセージが見つかるまでログ ファイルを線形にスキャンします。この方法は完全なインデックス検索よりも遅くなりますが、スパース ハッシュ インデックスの存在により、全体的な検索速度は依然として非常に効率的になります。
Kafka のメカニズム分析
Kafkaのマルチレプリカの仕組みを詳しく解説
Kafka のレプリカ (レプリカ) は、Kafka ノードに障害が発生したときにデータが失われないようにするためのデータ冗長性と障害回復メカニズムを提供し、高スループットのデータ読み取りおよび書き込み操作をサポートします。
各パーティションには複数のコピーを持つことができ、複数のコピーは異なるブローカー ノードに分散されます。パーティションの最初のレプリカはリーダー レプリカ (リーダー レプリカ) と呼ばれ、他のレプリカはフォロワー レプリカ (フォロワー レプリカ) と呼ばれます。
リーダー レプリカ: 各パーティションのリーダー レプリカは、そのパーティションに対するすべての読み取りおよび書き込みリクエストを処理する責任があります。プロデューサはリーダー レプリカにメッセージを送信し、コンシューマはリーダー レプリカからメッセージを読み取ります。リーダー レプリカは、データをフォロワー レプリカに複製する役割も果たします。
フォロワー コピー: フォロワー コピーは、リーダー コピーのコピーです。リーダー レプリカからのデータを同期します。フォロワー レプリカはクライアントからの読み取りおよび書き込みリクエストを処理せず、冗長性とフェイルオーバーを提供するためにのみ使用されます。(同様のレプリカの概念を設計する場合、多くの分散システムはマスター ノードへの負荷を共有するために少なくとも読み取り機能を提供することは言及する価値があります。それに比べて、Kafka のレプリカ メカニズムはより厳密です)。
データ レプリケーション: リーダー レプリカはメッセージをローカル ログ (ログ) に書き込み、レプリケーション メカニズムを通じてそのメッセージをフォロワー レプリカのログにコピーします。レプリケーションでは、同期レプリケーションと非同期レプリケーションの 2 つのモードを使用できます。
-
同期レプリケーション: リーダー レプリカは、メッセージがコミットされたと見なす前に、メッセージが正常にレプリケートされたことをすべてのフォロワー レプリカが確認するのを待ちます。このモードは最も強力なデータ保証を提供しますが、書き込み遅延にある程度の影響を与えます。
-
非同期レプリケーション: リーダー レプリカは、ローカル ログにメッセージを書き込んだ後、フォロワー レプリカからの確認を待たずに、ただちに成功応答を返します。このモードでは書き込み遅延が短くなりますが、特定の状況下ではデータ損失が発生する可能性があります。
レプリカの同期: フォロワー コピーとリーダー コピーの一貫性を維持するために、Kafka はログベースのレプリケーション メカニズムを使用します。フォロワー レプリカは、リーダー レプリカからログ エントリをコピーし、それらを自分自身のログに順番に追加します。レプリケーション プロセスでは、まだコピーされていないログ セグメントのみをプルする効率的な増分プル方式が使用されます。
フェイルオーバー: リーダー レプリカに障害が発生すると、Kafka は自動的にフォロワー レプリカを新しいリーダーとして選択します。パーティション内のすべてのレプリカは、総称して AR (割り当てられたレプリカ) と呼ばれます。選択プロセス中、Kafka はパーティションの ISR (In-Sync Replica) セット、つまり、リーダー レプリカとのデータ同期を維持するフォロワー レプリカのセットを使用します。遅延したフォロワーは OSR (Outof-Sync Replicas) リストに保存され、新しく追加されたフォロワーも最初に OSR に保存されます。AR=ISR+OSR。ISR 内のフォロワー コピーのみが新しいリーダーになる資格があります。
-
リーダー レプリカに障害が発生した場合、Kafka は ISR からフォロワー レプリカを選択して新しいリーダーになります。すべての ISR がダウンしている場合、AR から最初に応答したレプリカがリーダーとして選択されるため、メッセージの損失または重複が発生することに注意してください。
-
フォロワー レプリカに障害が発生した場合、Kafka はそれを ISR から削除し、他のフォロワー レプリカとの同期を継続します。
簡単にまとめると、Kafka のコピー メカニズムはデータの冗長性と障害回復機能を提供し、各パーティションは複数のコピーを持つことができ、異なるノードに分散することができます。レプリカの役割はリーダーとフォロワーに分かれており、リーダーは実際の読み取りと書き込み、およびフォロワー レプリカへのデータの同期を担当します。同期と非同期の 2 つのモードがあります。フォロワーはデータの冗長性とフェイルオーバーの回復のみを担当します。すべてのレプリカは総称して AR と呼ばれます。一貫したデータ同期を持つ一連のフォロワーとリーダーは ISR と呼ばれ、その他は OSR と呼ばれます。リーダーに障害が発生した場合、ISR のレプリカがランダムに選択されてリーダーになります。ISR に障害が発生した場合、 AR 内の最初のレプリカが選択され、応答のコピーが選択されます。
レプリカのシャーディング ルール
Kafka がレプリカを割り当てるには、RangeAssignor と RoundRobinAssignor という 2 つのアルゴリズムがあります。デフォルトは RangeAssignor ですが、シャーディングの場所をカスタマイズすることもできます。
-
すべてのブローカー (合計 n ブローカーと仮定) と割り当てられるパーティションを並べ替えます。
-
i 番目のパーティションを (i mod n) 番目のブローカーに割り当てます
-
i 番目のパーティションの j 番目のレプリカを ((i + j) mod n) 番目のブローカーに割り当てます
Kafka のマルチパーティションおよびマルチレプリカのメカニズムの利点は何ですか?
-
スループットの向上: マルチパーティション メカニズムにより、メッセージを複数のパーティションで並行して処理できるため、全体的なスループットが向上します。各パーティションは独立したコンシューマ上で同時に処理できるため、システムの並列性と処理能力が向上します。
-
水平方向のスケーラビリティの実現: Kafka は、データを複数のパーティションに分散することで簡単に水平方向にスケーリングできます。各パーティションを異なるサーバーにデプロイして、負荷分散と水平拡張を実現し、高スループットと大規模なデータ処理のニーズを満たすことができます。
-
耐障害性の向上: マルチコピー メカニズムにより、各パーティションを複数のレプリカに複製できます。1 つのレプリカに障害が発生した場合、Kafka は読み取りおよび書き込み操作を他の利用可能なレプリカに自動的に切り替えて、高可用性とフォールト トレランスを実現します。さらに、マルチコピー機構によりデータの冗長性も実現され、1 つのコピーが破損した場合でもデータは引き続き利用可能です。
-
データの永続性の実現: マルチコピー メカニズムにより、データが複数のコピーに複製されることが保証され、それによってデータの永続性が実現されます。1 つのコピーが破損したり誤動作したりした場合でも、他のコピーからデータにアクセスして回復することができます。
-
メッセージのシーケンスとパーティショニングのサポート: マルチパーティション メカニズムにより、ビジネス ニーズに応じてメッセージをさまざまなパーティションに割り当てることができ、各パーティションはメッセージの順序を維持できます。これは、メッセージの順序を保証する必要があるアプリケーションにとって重要です。同時に、パーティションを使用してメッセージをグループ化および分離し、メッセージ フローをより適切に制御することもできます。
カフカの動物園飼育員の役割を知っていますか?
-
コーディネーターの選出: Zookeeper は、Kafka クラスター内のコーディネーター (Coordinator) とコントローラー (Controller) を選出する責任を負います。どちらも 1 つのブローカーによって同時にサービスを提供できます。コントローラーは、Kafka クラスター全体のステータスとメタデータを管理する責任を負い、ロード バランシングを実現するためにさまざまなブローカーにパーティションを割り当てる責任を負います。
-
構成管理: Kafka のクラスター構成情報 (トピック、パーティション、レプリカなど)、コンシューマー グループのオフセット、その他のメタデータは Zookeeper に保存されます。Kafka の各ブローカーとコンシューマーは、Zookeeper と対話して最新のクラスター構成情報を取得します。
-
ブローカーの登録と検出: Kafka のブローカーは、起動時にホスト名、ポート番号などの独自の情報を Zookeeper に登録します。同時に、消費者は Zookeeper を通じて利用可能なブローカー ノードを発見できます。
-
パーティションの割り当てと再バランス: 新しいブローカーがクラスターに参加するか、古いブローカーがオフラインになると、Zookeeper はコントローラーによるパーティションの再分散と再バランスを支援します。パーティション割り当て計画を維持し、この情報を各ブローカーに通知して、高いデータ可用性と負荷分散を確保します。
-
レプリカ管理: Zookeeper は、Kafka パーティションのレプリカ情報を追跡および管理します。レプリカのステータスを監視し、レプリカに障害が発生した場合にはレプリカの再割り当てと回復を行います。
-
クライアント セッション管理: Kafka コンシューマーとプロデューサーは、Zookeeper を通じてクラスターとのセッション接続を維持します。Zookeeper はクライアントのアクティビティを検出し、接続の失敗と回復を処理できます。
一般に、Zookeeper は、調整、構成管理、パーティション割り当て、コピー管理、クライアント セッション管理など、Kafka で重要な役割を果たし、Kafka クラスターの安定した動作とデータの一貫性を確保します。
カフカはなぜそんなに速いのでしょうか?
-
分散アーキテクチャ: Kafka は、データと負荷を複数のノードに分散して並列処理とスケーラビリティを実現できる分散アーキテクチャを採用しています。メッセージは複数のパーティションに分割され、各パーティションはクラスター内の異なるノードで処理できるため、水平方向のスケーリングと負荷分散が可能になります。
-
ゼロコピー テクノロジ: Kafka はゼロコピー テクノロジを使用して、メッセージの読み取りおよび書き込み時に不必要なデータ コピー操作を回避します。Kafka は、オペレーティング システムのファイル マッピング (mmap) メカニズムを使用して、ディスク上のメッセージをメモリに直接マップし、メモリとディスク間のデータ コピーのコストを削減し、読み取りおよび書き込みのパフォーマンスを向上させます。
-
バッチ処理: Kafka はメッセージのバッチ処理をサポートします。プロデューサは複数のメッセージをまとめて Kafka に送信でき、コンシューマは複数のメッセージをバッチで取得して処理することもできます。バッチ処理により、ネットワークのオーバーヘッドとシステム コールの数が削減され、スループットと効率が向上します。
-
効率的なディスク順次書き込み: Kafka メッセージはランダムに書き込まれるのではなく、ディスクに追加されます。このシーケンシャル書き込み方式により、ディスクの読み取りと書き込みがより効率的になり、シーク時間とディスクの断片化が減少し、ディスクの使用率とパフォーマンスが向上します。最新のオペレーティング システムは先読みおよび先行書き込みテクノロジを提供しているため、ほとんどの場合、ディスクへのシーケンシャル書き込みはメモリへのランダム書き込みよりも高速です。
-
メモリベースのストレージとキャッシュ: Kafka は、オペレーティング システムのページ キャッシュを使用してメッセージをキャッシュし、読み取りおよび書き込みのパフォーマンスを向上させます。人気のあるメッセージはメモリにキャッシュされるため、ディスク アクセスの数が減り、メッセージの読み取りが高速化されます。Kafka の書き込み速度がその消費速度と同程度の場合、生成および消費プロセス全体はディスク IO を経由せず、すべてメモリ操作になります。
-
効率的なレプリケーション メカニズム: Kafka のレプリケーション メカニズムはストリーミング レプリケーションを採用しており、非同期レプリケーションとバッチ レプリケーションを通じてレプリケーションの効率とスループットを向上させます。同時に、Kafka は複数のレプリカと ISR (In-Sync Replica) メカニズムも使用して、データの信頼性と高可用性を確保します。
簡単にまとめると、まず、マルチパーティション分散構造はマルチスレッドを最大限に活用します。2 つ目は、オペレーティング システムのファイル マッピング メカニズムを使用して、ディスク データをメモリに直接マッピングすることで、1 回限りのコピーのオーバーヘッドを削減し、データの読み取りおよび書き込みのパフォーマンスを向上させることです。3 つ目は、バッチ処理をサポートすることです。バッチ処理は、プロデューサーとコンシューマーの両方によって同時にサポートされ、ネットワークのオーバーヘッドとリクエストの数を削減します。第 4 に、ディスクのシーケンシャル書き込みはランダム書き込みよりも効率的です。5 番目に、ホット ニュースはメモリに保存され、読み取りと書き込みのパフォーマンスが向上します。
あまり知られていない知識を共有する
Kafka がページ キャッシュを使用せずに独自のキャッシュを管理しないのはなぜですか?
-
JVM 内のすべてはオブジェクトであり、データをオブジェクトに保存すると、いわゆるオブジェクトのオーバーヘッドと無駄なスペースが発生します。
-
JVM がキャッシュを管理する場合、キャッシュは GC の影響を受けます。また、ヒープが大きすぎると GC の効率が低下し、スループットが低下します。
-
プログラムがクラッシュすると、管理しているすべてのキャッシュ データが失われます。
Kafka のパフォーマンス: なぜ Kafka はとても「速い」のでしょうか? [1]、この記事を読んで非常によく書かれていると思ったので、ここに投稿しました。詳しく知りたい方はリンク先へ飛んでご覧ください
Kafka シナリオ分析
Kafka はどのようにして高可用性を確保しますか?
-
分散アーキテクチャ: Kafka は、複数のブローカー ノードにデータを分散して保存する分散アーキテクチャを採用しています。これにより、ブローカー ノードに障害が発生した場合でも、他の正常に動作しているブローカー ノードが引き続きサービスを提供できます。
-
マルチコピー メカニズム: Kafka はマルチコピー メカニズムを使用して、データの冗長性と可用性を確保します。各パーティションは、異なるブローカー ノードに分散される複数のレプリカで構成できます。レプリカが配置されているブローカーに障害が発生した場合でも、他のレプリカがサービスを引き継ぎ、データの可用性を確保できます。
-
コントローラー: Kafka クラスター内のコントローラーは、クラスター全体のステータスとメタデータの管理を担当します。ブローカー ノードに障害が発生するかオフラインになると、コントローラーはこの変化を検出し、パーティションやレプリカのリーダーシップを再分配するなどの対応する操作を実行して、データの高可用性と一貫性を確保します。
-
自動障害回復: Kafka には自動障害回復機能があります。ブローカー ノードに障害が発生するかオフラインになると、コントローラーはレプリカの再配布および回復プロセスを自動的にトリガーし、レプリカを他の利用可能なブローカー ノードに割り当てて、データの冗長性と可用性を確保します。
-
ハートビートとセッションの有効期限: Kafka とクライアント間の接続はハートビート メカニズムを通じて維持され、クライアントのアクティブ ステータスが定期的に検出されます。コンシューマーまたはプロデューサーのクライアントが長期間ハートビートを送信しない場合、コントローラーはそのクライアントのセッションが期限切れになったとみなし、そのパーティションを他のアクティブなコンシューマーに再配布します。
-
監視とアラーム: Kafka は、クラスターのステータス、パーティションの健全性、コンシューマーの進行状況をリアルタイムで監視できる豊富な監視インジケーターとアラーム メカニズムを提供します。これにより、潜在的な問題をタイムリーに検出して解決し、システムの可用性と安定性が向上します。
簡単に言うと4つのポイントに分かれます。1つ目はKafkaの分散構造で、複数のパーティションが異なるノードに分散されており、一部のノードがダウンしてもサービスは正常に提供されます。2 番目に、マルチコピー メカニズムにより、データの冗長性による高可用性が保証されます。第三に、Kafka クラスターのコントローラーの役割はクラスター全体のステータスとメタデータを管理し、ノードがオンラインまたはオフラインで監視されると、パーティションとレプリカのリーダーシップが再配分されます。4 つ目は、Kafka クラスターのコーディネーターです。これは、プロダクション側でデータのトランザクション操作を保証し、コンシューマー側でリバランス メカニズムを使用して、データがコンシューマー グループによってスムーズに消費されるようにします。
Kafka はメッセージが繰り返し消費されないようにするにはどうすればよいでしょうか?
-
Consumer Offset : Kafka は、各コンシューマ グループによって消費されるオフセット、つまり処理されたメッセージの位置を維持します。コンシューマーは現在のオフセットを定期的にコミットし、メッセージが正常に消費されたことを示します。Kafka はこのオフセットを保存し、再起動後に復元します。これにより、コンシューマは最後にコミットされたオフセットから消費し続けることができます。
-
コンシューマ グループ コーディネーター: Kafka のコンシューマ グループ コーディネーターは、コンシューマ グループのオフセットの追跡と管理を担当します。各コンシューマーのオフセット情報を内部または外部ストレージ システム (Zookeeper や Kafka 独自の内部トピック __consumer_offsets など) に保存します。Kafka は、コーディネーターの管理を通じて、コンシューマ グループ内の各コンシューマが最後のオフセットから正しく消費を継続できるようにします。
-
コンシューマ オフセットのコミット: コンシューマは、メッセージのバッチを消費した後にオフセットを手動で送信するか、自動送信設定を通じてオフセットを定期的に自動的に送信するかを選択できます。オフセットを手動でコミットすると、消費が失敗した場合やエラー処理が発生した場合にオフセットがコミットされなくなり、繰り返しの消費が回避されます。自動コミット オフセットは、メッセージを処理する操作が冪等であることを保証するために注意して使用する必要があります。
-
1 回限りのセマンティクス: Kafka では、トランザクションのプロデューサー API とコンシューマー API を導入し、アプリケーションが「1 回限り」のセマンティクスを実現できるようにします。トランザクションプロデューサーは、Kafka トランザクションにメッセージを書き込み、トランザクションのコミットを確認した後でのみメッセージをコンシューマーに公開できます。トランザクション コンシューマは、オフセットのアトミックな送信と、メッセージ処理後のトランザクション送信を通じてメッセージ処理の一貫性を保証します。
簡単に言うと、Kafka は主にコンシューマー オフセットを使用して、メッセージが繰り返し消費されないようにします。Kafka はコーディネーターと内部 TOPIC (__consumer_offsets) を内部的に使用して、コンシューマー インスタンスが繰り返し消費されないようにします。開発者は、消費オフセットを手動で送信して、消費が失敗した場合や例外が発生した場合にオフセットが送信されないようにして、繰り返しの消費を避けることができます。開発者は、コンシューマ側でべき等な処理を実行することにより、繰り返しの消費を避けることもできます。
Kafka はメッセージが消費される順序をどのように保証しますか?
Kafka は、パーティションおよびパーティション内のオフセットを通じてメッセージの順序を保証します。トピックは複数のパーティションにすることができますが、各パーティションのデータは順次です。プロデューサーによって送信されたメッセージはパーティションの最後に順次追加され、コンシューマーもデータを順次消費します。
つまり、トピックに複数のパーティションがある場合、メッセージの順序はパーティション内でのみ保証され、異なるパーティション間のメッセージの順序は Kafka によって保証されません。アプリケーションのロジックで厳密なグローバル順序付けが必要な場合は、関連するすべてのメッセージを同じパーティションに送信する必要があります。そうでない場合、アプリケーションはコンシューマー側で追加の処理を実行してグローバル順序付けを実現します。
Kafka はどのようにしてメッセージが失われないようにするのでしょうか?
-
永続ストレージ: Kafka はメッセージをメモリだけでなくディスクに永続的に保存します。各トピックのメッセージは複数のパーティションに書き込まれ、各パーティションは複数のレプリカを持つことができます。このようにして、ブローカーまたはディスクに障害が発生した場合でも、メッセージを他のコピーから回復できるため、メッセージの損失が回避されます。
-
レプリケーション メカニズム: Kafka はレプリケーション メカニズムを使用して、高可用性とフォールト トレランスを提供します。各パーティションのメッセージを複数のブローカー上で複製して、レプリカ セットを形成できます。レプリカ セット内の 1 つのレプリカはリーダーとして指定され、読み取りおよび書き込み操作を担当しますが、他のレプリカはフォロワーです。リーダー レプリカに障害が発生すると、フォロワーの 1 つが新しいリーダーとして選出され、メッセージの耐久性と可用性が確保されます。
-
書き込み確認 (Acknowledgement) : Kafka にメッセージを送信するとき、プロデューサーは、メッセージが正常に書き込まれたことの確認を待つことを選択できます。プロデューサは待機するレプリカの数を構成でき、指定された数のレプリカが正常に書き込まれた後でのみプロデューサは確認を受け取ります。このメカニズムにより、メッセージが十分なレプリカに書き込まれるようになり、メッセージ損失のリスクが軽減されます。
-
レプリカの同期: Kafka はレプリカ同期メカニズムを使用して、パーティションのレプリカが確実に同期されるようにします。メッセージが書き込まれると、リーダー レプリカはそのメッセージをすべてのフォロワー レプリカにコピーし、その確認応答を待ちます。リーダー レプリカは、すべてのフォロワー レプリカが正常に複製してメッセージを確認した後でのみ、メッセージの書き込みが成功したとみなします。この同期メカニズムにより、データの一貫性が保証され、データ損失の可能性が軽減されます。
-
コンシューマ ディスプレイスメントの送信: コンシューマはメッセージを消費するときに、消費されたディスプレイスメント (オフセット) を定期的に Kafka に送信します。このようにして、コンシューマが失敗した場合やコンシューマ グループに再参加した場合でも、最後に送信されたディスプレイスメントに基づいて消費を再開できます。オフセット送信を通じて、Kafka はコンシューマーの進行状況を追跡し、メッセージが 2 回消費されたり失われたりしないようにできます。
簡単に要約すると、Kafka のマルチコピー冗長データ メカニズムは、複数のノード上の複数のバックアップで使用できます。また、ACK メカニズムは、トランザクション メカニズムと同様に、プロデューサがメッセージを送信した後、終了リクエストを確認する前に一部またはすべてのレプリカがメッセージを受信することを選択できることを保証します。コンシューマは、オフセットを積極的に送信することで、メッセージの繰り返しの消費や損失を回避することもできます。
メッセージのバックログに対処する方法
-
コンシューマの処理能力を向上させる: コンシューマ インスタンスの数を増やすことで、コンシューマの同時処理能力を高めることができます。これにより、メッセージがより速く消費され、バックログが削減されます。
-
コンシューマの処理ロジックを調整する: コンシューマの処理ロジックが複雑な場合、処理速度が遅くなる可能性があります。コンシューマのコード ロジックを評価および最適化して、処理効率を向上させることができます。
-
パーティションの数を増やす: トピックのパーティションの数を増やすと、メッセージの並列性が向上します。このようにして、各パーティション内のメッセージが異なるコンシューマ インスタンスに均等に分散されるため、バックログの問題が軽減されます。
-
プロデューサの送信レートを調整する: プロデューサの送信レートが速すぎるためにメッセージ スクイーズが発生している場合は、コンシューマがメッセージを処理するのに十分な時間を確保できるように、プロデューサの送信レートを調整してメッセージ生成レートを下げることができます。
-
Kafka クラスターのリソースを増やす: Kafka クラスターのリソース (ディスク、ネットワーク帯域幅など) が不十分な場合、メッセージ処理が遅くなる可能性があります。全体的な処理能力を向上させるために、クラスターのリソースを増やすことを検討してください。
簡単にまとめると、通常の状況では消費圧力が高く、一時的に流通エリアと消費者数を拡大することで消費速度を高めることができます。私自身の経験に基づくフォローアップですが、メッセージバックログの問題を解決するのは難しいですか? このアイデアのコード最適化の詳細は完全に公開されており [2]、プロジェクトの困難さがまとめられています。
カフカのソースコード
制作側
NIO ネットワーク通信モジュール: Kafka が Java NIO に基づいた一連の工業生産グレードのネットワーク基盤となる通信モジュールを実装する方法
メモリ バッファ プールの設計: Kafka クライアントが数百万の同時実行をサポートする高スループットのバッファリング メカニズムを設計する方法
送信側スレッド: 重要な点は、Kafka クライアントがネットワーク通信を通じてメッセージのバッチを Kafka ブローカーにどのように送信するかということです。これには、ネットワーク通信、いくつかのパラメータ設定、およびネットワーク障害の処理に関する多くの詳細が含まれます。
クラスターのメタデータのプルと更新のメカニズム: クラスターのメタデータのプル コンポーネントとプルのタイミング、メタデータがクライアントにキャッシュされる方法、きめ細かいオンデマンドの読み込みとトピック メタデータの同期待機をサポートする方法。
サーバ
クラスター アーキテクチャ: Kafka ブローカーのクラスター アーキテクチャがどのように実装されるか、各ブローカーが起動後にクラスターを形成する方法、クラスター コントローラーがどのように選択されるか、障害回復高可用性アーキテクチャがどのように実装されるかなど。
サーバー側ネットワーク通信モジュール: Kafka サーバー側ネットワーク通信モジュールの実装方法、Reactor 設計モデルと超高同時実行性をサポートする Kafka の Reactor ベースのネットワーク アーキテクチャの理解、アクセプター スレッド、プロセッサ スレッド、 RequestChannel、IO スレッド プール、およびその他のネットワーク 基礎となる通信コンポーネントの実装とリクエスト処理プロセス全体のソース コード。
パーティションとレプリカ: マルチコピー冗長性と高可用性アーキテクチャを実装する方法、リーダーとフォロワーのデータがどのように同期されるか、レプリカが送信される方法、およびそれらの間の HW と LEO がどのように変更されるか、リーダーの後にシステムの高可用性を確保する方法ブローカーが失敗してダウンする、レプリカ マネージャーがレプリカを管理する方法、ブローカーがメタデータ キャッシュを非同期で更新する方法など。
ロード バランシングとスケーリング アーキテクチャ: データがクラスターのブローカー マシンに均等に分散されるようにする方法、トピックとブローカーのパーティションをスケーリングする方法。
ログ ストレージ アーキテクチャ: Kafka が効率的に保存する方法、ディスクの読み取りと書き込みがどのように実装されるか、ログのストレージ構造とは何か、OS キャッシュ、ゼロ コピー、スパース インデックス、シーケンシャル書き込み、および超高スループット ストレージをサポートするその他の優れた設計を使用する方法建築。
消費者側
消費プロセス: コンシューマの初期化方法、サーバーとの通信方法、コンシューマのpoll()メソッドがデータを消費する方法。
コンシューマ グループ管理: コンシューマ グループの概念、ステート マシン フロー、コンシューマが起動後にグループに参加する方法、コンシューマ グループ管理の全プロセス、コンシューマ グループのメタデータ管理の設計原則など。
コーディネーターのメカニズム: コンシューマー コーディネーターの仕組み、コンシューマー コーディネーターがコンシューマー リーダーを選出する方法、コンシューマー リーダーがパーティション割り当て計画を策定する方法、コンシューマー コーディネーターがパーティション割り当て計画を発行する方法、コンシューマーがコンシューマー コーディネーターにハートビートを定期的に送信する方法、など待ってください。
メッセージ リバランス メカニズム: いくつかのリバランス シナリオ、およびリバランス ソース コード プロセス分析。
__consumer_offsets : トピック内のトピック。
サブスクリプション ステータスとオフセット操作: コンシューマのサブスクリプション ステータスがトピック パーティションとオフセットの間の対応関係をどのように保存および追跡するか、オフセットの取得および送信方法などを理解します。
メッセージキューを設計するにはどうすればよいですか?
メッセージ キューを設計するときは、次の重要な側面を考慮できます。
-
要件と目的の定義: メッセージ キューの目的、予想されるスループット、遅延要件、データ サイズ制限、その他の要件を明確にします。解決しようとしている問題と達成したい目標を理解することは、適切な設計の方向性を決定するのに役立ちます。
-
適切なメッセージ キュー ミドルウェアを選択する: ニーズと使用法に基づいて、適切なメッセージ キュー ミドルウェアを選択します。Kafka、RabbitMQ、ActiveMQ など、多くのオープン ソースおよび商用メッセージ キュー ミドルウェアから選択できます。機能、信頼性、パフォーマンス、拡張性、コミュニティ サポートなどの側面を考慮してください。
-
メッセージ形式とプロトコルを定義する: メッセージ構造、データ フィールド、および考えられるメッセージ ヘッダーとメタデータを含むメッセージ形式とプロトコルを設計します。これはメッセージの一貫性とスケーラビリティに役立ち、消費者に有益な情報を提供します。
-
メッセージの永続性と信頼性を考慮する: メッセージの損失を防ぐためにメッセージをディスクに永続化する必要があるかどうかを判断します。一部のメッセージ キュー ミドルウェアには、障害が発生した場合でもメッセージが失われないようにするための永続化オプションが用意されています。
-
メッセージの順序を考慮する: アプリケーションにとってメッセージの順序が重要である場合は、順序付けされたメッセージ配信をサポートするメッセージ キュー ミドルウェアを選択し、ニーズに応じて適切なメッセージ パーティショニングと順序保証メカニズムを設計する必要があります。
-
メッセージの分割とスケーリングを検討する: 大量のメッセージと高いスループットが予想される場合は、メッセージの分割とスケーリングの方法を検討する必要があります。これにより、システムの並列性とスケーラビリティが向上し、メッセージが効率的に処理されるようになります。
-
適切なセキュリティ メカニズムを実装する: 認証、アクセス制御、データ暗号化などを含むメッセージ セキュリティを考慮します。メッセージの機密性と完全性を保護するためのニーズに基づいて、適切なセキュリティ メカニズムを選択します。
-
監視と管理: メッセージ キューのパフォーマンス、スループット、待ち時間、その他の指標をリアルタイムで監視できるように、監視と管理のメカニズムを設計します。これは、問題を迅速に特定してトラブルシューティングするのに役立ちます。
メッセージ キューを設計するには、複数の要素を包括的に考慮し、実際のニーズとアプリケーション シナリオに基づいて決定を下す必要があります。これらのガイドラインは、信頼性が高く、パフォーマンスが高く、スケーラブルなメッセージ キュー システムの設計を開始するのに役立ちます。
読みました、前回の記事は6月27日、この記事は7月23日、ざっくり書いたのは21日、ずっといじって月曜に初投稿しました。 1月。この更新頻度は確かに少し遅いですが、今後も時間をかけて取り組んでいきます。ブロガーさん、ほぼ一ヶ月が経ちました(笑)色々なことがありましたが、平凡だった先週を除けば、残りの二週間は私にとって興奮と驚きの連続でした。私自身、新たな目標とモチベーションが湧いてきました。今後は仕事、生活、勉強を両立させていきます。この世界はとても面白いです。本気です。
私は怠け者です。正直に言うと、ここ数週間は勉強する時間が十分ではありませんでした。仕事と生活にもっと集中してきました。先週は残業もしてしまい、とても迷惑でした。「人生の面では、もしかしたら私のメンタリティがまた変わったのかもしれません。なぜ最近なのかわかりませんが、インスピレーションを与える言葉をたくさん読んだり、これまであえてしなかったようなことをするようになりました。それはとても大胆で、真剣です」結果はかなり良くて、とにかくとても幸せです(笑)、素晴らしい気分です、私の精神がより前向きになったように感じます。結果はどうであれ、自分の意志に逆らわずにもっと頑張ってやるよ、さあ!私の人生信条を改めて申し上げます。この苦しくて息苦しい世界に幸せの花を咲かせ、この美しい世界に祝福を捧げます!!
参考文献
[1]
https://mp.weixin.qq.com/s/kMIhPW2uLdy-mgS9sF6agw: https://link.juejin.cn/?target=https%3A%2F%2Fmp.weixin.qq.com%2Fs%2FkMIhPW2uLdy-mgS9sF6agw
[2]
https://juejin.cn/post/7209657931124555834: https://juejin.cn/post/7209657931124555834