カフカを簡単かつ深く理解する ---- 10,000 語の要約

1. カフカの紹介


Kafka は本質的に MQ (メッセージ キュー) であり、メッセージ キューを使用する利点は次のとおりです。

分離:キューの両側の処理を独立して拡張または変更できるようにします。
回復可能性: メッセージを処理しているプロセスが停止した場合でも、システムが復元された後、キューに追加されたメッセージは引き続き処理できます。
バッファリング: メッセージの生成と消費の処理速度が一貫していない問題の解決に役立ちます。
柔軟性とピーク処理能力: 突然の過負荷リクエストによって完全に崩壊することはなく、メッセージ キューにより主要コンポーネントが突然のアクセス圧力の急増に耐えることができます。
非同期通信: メッセージ キューを使用すると、ユーザーはメッセージをキューに入れることができますが、すぐには処理できません。

まず、メッセージ キューの利点を紹介します。 

メッセージキュー:

メッセージ キュー非同期処理

主にSMS通知、端末ステータスプッシュ、アプリプッシュ、ユーザー登録などに使用されます。

同期処理:

 同期的に処理する場合、前のステップが完了するまで待ってから次のステップを実行する必要があるため、ネットワーク速度が非常に遅くなりますが、在庫と注文、SMS、統計の間で在庫を生産者として使用できますか? ? メッセージ キューを追加し、注文、テキスト メッセージ、統計の 3 つの (コンシューマ) スレッドがそれぞれ独自のタスクを処理できるようにすると、そのスレッドがインベントリから削除されます (プロデューサーは生産後すぐに戻り、その後生産に移ります)それをメッセージ キューに入れてから、消費するようにコンシューマ スレッドに通知します)。そのため、段階的に行う必要はありません。

待っている

非同期処理:

 非同期処理の利点: 結果をより速く返し、待ち時間を減らし、同時処理を実現し、システム全体のパフォーマンスを向上させます。
メッセージ キュー モードは次のとおりです。
(1) 1 ~ 1: 読み取り後すぐにメッセージをキューから削除します。
(2) 1 対多: このモデルはパブリッシュ/サブスクライブ モデルであり、メッセージ キューの要素は繰り返し使用できます。メッセージを削除するタイミングについては、メッセージの生存期間を設定できます。たとえば、Kafka では、メッセージが 24 時間後に削除されるように設定できます。

メッセージキューフロー制御(ピーククリッピング)

フラッシュ セール シナリオの注文ステータスでは、メッセージ キューを使用してゲートウェイとバックエンド サービスを分離し、トラフィック制御を実現し、バックエンド サービスを保護します。

メッセージ キューの最大制限数を設定します。最大数に達すると、ゲートウェイはメッセージ キューにメッセージを生成しなくなります。

このように考えることができます。製品フラッシュ セール イベントがあり、製品の数が 100 で、メッセージ キューの数が 100 に達すると、フラッシュ セール成功メッセージは生成されなくなり、フラッシュ セール失敗メッセージが生成されます。フラッシュセールに成功し、商品を手に入れることができるのは1~100人のユーザーのみです。

そこでサーバー設計の観点から考えてみると、ある瞬間、私たちはフラッシュセールのサービスを提供するプロデューサーであり、メッセージキューの数が100に達したら生産を停止し、クライアントはオンラインフラッシュセールに移行することになります。ショッピングを実行するには、メッセージ キューからプルします。メッセージ キューが空である (つまり、商品が 0 である) ことがわかると、フラッシュ セールの失敗が返されます。

メッセージキューサービスの分離

システム A はデータ配布を担当し、他のシステムはシステム A が提供するインターフェイスを呼び出してデータを処理します。新しいシステムが追加されると、システム A は新しいシステムを呼び出すようにコードを変更し、新しいシステム用の新しいインターフェイスを実装する必要があります。電話すること。このアプローチはシステム間で高度に連携しています。

  

システム A は、メッセージ キューを使用して MQ にデータを配布します。コンシューマは、必要に応じて MQ からメッセージを取得し、不要な場合は MQ の消費をキャンセルできます。

メッセージキューのパブリッシュとサブスクライブ

関連するメッセージを受信するには、ユーザーは最初に登録する必要があります。

 

 たとえば、ゲーム内のクロスサーバー:
(1) 今日使用できるドラゴン殺しのナイフが何本残っているかをブロードキャストします。
(2) ユーザーによって竜殺しのナイフが暴発したというニュースを放送します。

メッセージキューの高い同時バッファリング


これは、メッセージ キュー フロー制御 (ピーク クリッピング) に似ています。違いは、サイズ制限がないことと、バックエンドの処理能力が 1 秒あたり 50,000 件であるのに対し、80,000 件のアクセスがあるなど、ある時点でバックエンドの処理能力を超えるアクセスが発生する可能性があることです。ある時点で 1 秒あたりの速度が低下する可能性があり、故障の原因となります。

この状況に対応して、すべてのメッセージがメッセージ キューに入れられ、メッセージ キューはデータをディスクに固定する機能を提供し、バックエンドへのピーク データの短期的な影響を軽減します。

たとえば、バックエンドの処理能力が 50,000 で、ある短い時点 (1 秒など) でデータ アクセスが 80,000 に達した場合、メッセージ キューはより多くのデータをディスクにキャッシュし、バックエンドは依然として 50,000 のデータを処理します。インパクト ポイントが後退すると、アクセス データが減少し、30000 に達すると、メッセージ キューはキャッシュされたデータをバックエンドに入れて処理します。

たとえば、kafka ログ サービスや監視レポートなどです。

2. Kafka のアーキテクチャ 

Kafka はリーダー コピーにのみデータを書き込み、リーダー コピーからのみデータを書き込みます。 a i=4>データを取得します。リーダーが失敗した場合、新しいリーダーが選択されます ( フォロワー レプリカから選択され、同じトピック内にある必要があります)。
この利点は、MySQL のマスターとスレーブの関係に似ています。データはホストに書き込まれますが、データの読み取り方法は異なります。Kafka はホストからのデータのみを読み取ることができます。

1.Kafka は、プロデューサーと呼ばれる任意の数のプロセスからのメッセージを保存します。したがって、データは、異なる 2.Topic トピックの下の異なる Partition パーティションにパブリッシュできます。
パーティション内では、これらのメッセージはインデックス付けされ、タイムスタンプとともに保存されます。コンシューマと呼ばれる他のプロセスは、パーティションからのメッセージをサブスクライブできます。
3.Kafka は 1 つ以上のサーバーで構成されるクラスター上で実行され、パーティションはクラスター ノード全体に分散できます。
 

2.1 Kafka のいくつかの重要な概念


プロデューサー:メッセージ プロデューサー。Kafka ブローカーにメッセージを送信するクライアント。
コンシューマ: メッセージ コンシューマ、Kafka ブローカーからメッセージを取得するクライアント。
コンシューマ グループ: コンシューマ グループ (CG)。コンシューマ グループ内の各コンシューマは、消費機能を向上させるために、さまざまなパーティション内のデータを消費する責任があります。パーティションはグループ内の 1 つのコンシューマによってのみ使用でき、コンシューマ グループは相互に影響しません。すべてのコンシューマは特定のコンシューマ グループに属します。つまり、コンシューマ グループは論理サブスクライバです。

(注意!!! 同じコンシューマ グループが同じトピックをサブスクライブする場合、同じコンシューマ グループがメッセージ キューのコンテンツを消費している場合、グループ内の 1 つのコンシューマのみが一度に消費できます。消費グループ内のすべてのコンシューマは同時に消費できません)
ブローカー:Kafka マシンはブローカーです。クラスター (kafka クラスター) は複数の Broker で構成されます。ブローカーは複数のトピックに対応できます。
トピック: はキューとして理解できます。トピックはメッセージを分類します。プロデューサーとコンシューマーは同じトピックに直面します。

(実際、この設計は主に論理ストレージとして理解されています。たとえば、特定のパブリック アカウントのコンテンツはトピックに保存され、各パーティションは物理的に存在します)
パーティション:スケーラビリティを実現し、同時実行性を向上させるために、非常に大きなトピックを複数のブローカー (サーバーなど) に分散できます。トピックは複数のパーティションに分割でき、同じトピックを複数のパーティションに分割できます。異なるサーバーに分散されます。パーティションのデータは繰り返されません。各パーティションは順序付けされたキューであり、その表現は 1 つずつのフォルダーです。

(物理的に表現されたストレージ ユニット)
レプリケーション:各パーティションには複数のコピーがあり、コピーの役割はバックアップ タイヤとして機能します。 。メイン パーティション (リーダー) に障害が発生した場合、スペア タイヤ (フォロワー) が選択されて引き継ぎ、リーダーになります。 Kafka のレプリカのデフォルトの最大数は 10 であり、レプリカの数はブローカーの数を超えることはできません。フォロワーとリーダーは確実に異なるマシン上にあり、同じマシンには (それ自体を含む) 1 つのレプリカのみを保存できます。同じパーティション。
メッセージ: メッセージ。送信される各メッセージの本文。
リーダー: 各パーティションの複数のコピーの「マスター」コピー、プロデューサーがデータを送信するオブジェクト、およびコンシューマーがデータを消費するオブジェクト全員がリーダーです。
フォロワー: 各パーティションの複数のコピーの「スレーブ」コピーは、リーダーからのデータをリアルタイムで同期し、リーダー データとの同期を維持します。リーダーが失敗すると、フォロワーが新しいリーダーになります。
オフセット: コンシューマによって消費される位置情報。データが消費される場所を監視します。コンシューマが電話を切って再開すると、次から続行できます。消費場所。消費。同じトピック、異なるパーティション、それらのオフセットは独立しています。
ZooKeeper: Kafka クラスターが適切に動作するには、ZooKeeper に依存します。ZooKeeper は、Kafka がクラスター情報を保存および管理するのに役立ちます。

! ! ! Kafka クラスターを開始するときは、kafka を開始する前にまず Zookeeper を開始する必要があることに注意してください。

2.2 ワークフロー

異なるパーティションのオファーレットは独立しています。
Kafka のメッセージは、トピック によって分類されます。プロデューサーはメッセージを生成し、コンシューマーはメッセージを消費します。それらはすべて、次のことに向けられています。同じトピック。 (つまり、先ほど説明したトピックは論理的な確率です)
トピックは論理的な概念であり、パーティションは物理的な概念です。各パーティションはログ ファイルに対応し、ログ ファイルの保存場所はプロデューサーが作成したデータです。プロデューサーによって生成されたデータはログ ファイルの末尾に継続的に追加され (逐次書き込み)、各データには独自のオフセットがあります。
コンシューマ グループ内の各コンシューマは、消費したオフセットをリアルタイムで記録するため、エラーが回復したときに最後の位置から消費を続行できます。

オフセットはパーティションに記録されます。このオフセットはコンシューマー消費の位置を表すため、エラーから回復するときに最後の位置から消費を継続できます。
デフォルトのログの場所は: /tmp/kafka-logs

2.3 ファイルストレージ

Kafka ファイル ストレージも、主に、対応するログ ファイルとインデックス ファイルを通じて特定のメッセージ ファイルを保存することによって、ローカルに保存されます。

プロデューサーはメッセージ ファイルをログ ファイルに追加し続けます。ログ ファイルが大きすぎて位置決め効率が低下することを防ぐために、Kafka のログ ファイルは 1G を分割点として使用します。.log ファイルのサイズが 1G を超えると、 .log ファイルが作成され、大きなファイル内のメッセージの場所をすばやく見つけるために、Kafka はシャーディングとインデックス作成のメカニズムを採用して位置決めを高速化します。

kafka がログを保存する場所、つまりファイルが保存される場所には、消費オフセットと特定のパーティション情報が存在します。パーティション情報には、主に .index ファイルと .log ファイルが含まれます。
要約すると、トピックには複数のパーティションがあり、1 つのパーティションがログ ファイルに対応します。プロデューサーによって生成されたデータがトピックに書き込まれると、そのデータはトピックのパーティション、つまりログ ファイルに書き込まれます。 、ログ ファイルは複数のセグメントに分割されており、1 つのセグメントは 2 つのファイル (index および .log ファイル) に対応します。

2.4 コピーの原則


レプリケーション メカニズム (レプリケーション) はバックアップ メカニズムとも呼ばれ、通常、ネットワークに接続された複数のマシンに同じデータ コピーを保存する分散システムを指します。コピー メカニズムの利点は次のとおりです。

はデータの冗長性を提供します (つまり、可用性が向上します)。
高いスケーラビリティを提供します (より高い読み取りリクエストをサポートします)。
データの局所性を改善します (システムの遅延を削減します)。
現在、Kafka は、コピー メカニズムによってもたらされる最初の利点のみを認識しています。それは、高可用性と高耐久性を実現するためにデータの冗長性を提供することです。

Kafka 運用環境では、各ブローカーがトピックごとに異なるパーティションの異なるコピーを保存する場合があるため、単一のブローカーが数百または数千のコピーを持つことはごく普通のことです。

たとえば、3 つのブローカーを持つ Kafka クラスター上のレプリカの分散が示されています。トピック 1 パーティション 0 の 3 つのコピーは 3 つのブローカーに分散され、他のトピック パーティションのコピーもデータの冗長性を実現するために異なるブローカーに分散されます。
 

上記を要約すると、各ブローカーは Kafka サーバーに対応し、1 つのブローカーは複数のトピックのパーティションを保存します。複数のブローカーがあり、各タイプのトピックのパーティションが複数の Kafka サーバー (ブローカー上) に保存されている場合、おそらくたとえば、トピック 1 のフォロワー コピーはブローカー 2 に保存され、トピック 1 のリーダー コピーはブローカー 3 に保存されます。データが複数の Kafka サーバーに冗長分散されている場合、特定のサーバーがダウンすると、

トピックのリーダー コピーがオフラインになっている場合、他の Kafka サーバー (ブローカー) を使用してフォロワーをリーダー コピーとして選択できます。以前オフラインだったコピーがオンラインになると、それはフォロワーとして Kafka クラスターに追加されます。

 

Kafka はリーダーベースのレプリカ メカニズムです。 

1. Kafka では、レプリカはリーダー レプリカとフォロワー レプリカの 2 つのカテゴリに分類されます。各パーティションが作成されると、リーダー レプリカと呼ばれる 1 つのレプリカが選択され、残りのレプリカは自動的にフォロワー レプリカと呼ばれます。


2. Kafka コピー メカニズムのフォロワー コピーは、外部にサービスを提供しません。


3. リーダー コピーが停止するか、リーダー コピーが存在するブローカーがダウンすると、Kafka は ZooKeeper が提供する監視機能を利用してそれをリアルタイムで感知し、直ちにリーダーの新しいラウンドを開始してフォロワー コピーから選択します。 . 新しいリーダーとしての一人。古いリーダー コピーを再起動した後は、クラスターにフォロワー コピーとしてのみ追加できます。
 

2.5 パーティションとトピックの関係

  • パーティションは 1 つのトピックのみに属します。
  • トピックには複数のパーティションを含めることができます。
  • 同じトピックの異なるパーティションには異なる内容があり、各パーティションには独自の独立したオフセットがあります。
  • 同じトピックの異なるパーティションを異なるノードのブローカーに配置できます。
  • パーティション化ルールを適切に設定すると、同じトピックに関するメッセージを異なるパーティションに均等に分類できます。

2.6 プロデューサー

プロデューサーはデータへの入り口です。プロデューサーは、データを書き込むときに常にリーダーを探し、フォロワーにデータを直接書き込みません。

2.6.1 パーティションを水平方向に拡張可能

Kafka のメッセージ構成は、実際にはトピック - パーティション - メッセージの 3 レベルの構造です。トピック内の各メッセージは特定のパーティションにのみ保存され、複数のパーティションには保存されません。

パーティショニングの役割は主に、負荷分散機能を提供し、システムの高い拡張性を実現することです。異なるノードのマシンに異なるパーティションを配置でき、データの読み取りおよび書き込み操作もパーティションの粒度で実行されるため、各ノードのマシンはそれぞれのパーティションの読み取りおよび書き込み要求処理を独立して実行できます。このように、パフォーマンスが不十分な場合、新しいノード マシンを追加することでシステム全体のスループットを向上させることができます。

パーティショニングの原則: プロデューサーによって送信されたデータは、ProducerRecord オブジェクトにカプセル化する必要があります。
このオブジェクトにはいくつかのパラメータを指定する必要があります:

トピック: 文字列型、NotNull。
パーティション: int 型、オプション。
タイムスタンプ: ロングタイプ、オプション。
キー: 文字列タイプ、オプション。
値: 文字列タイプ、オプション。
ヘッダー: 配列タイプ、Null 可能。

2.6.2 パーティション戦略

いわゆるパーティション戦略は、プロデューサーがメッセージを送信するパーティションを決定するアルゴリズムです。 Kafka はデフォルトのパーティショニング戦略を提供しており、カスタム パーティショニング戦略もサポートしています。

分割の理由

  • クラスタ内での便利な拡張: 各パーティションは、それが配置されているマシンに適応するように調整され、トピックは複数のパーティションで構成できるため、クラスタ全体が適応できます。適切なデータに
  • 同時実行性を向上させることができます: パーティション単位で読み取りと書き込みを行います。マルチパスに似ています。

2.6.2.1 ポーリング戦略


ラウンドロビン戦略、つまり順次割り当て。たとえば、トピックの下に 3 つのパーティションがある場合、最初のメッセージはパーティション 0 に送信され、2 番目のメッセージはパーティション 1 に送信され、3 番目のメッセージはパーティション 2 に送信されます。 4 番目のメッセージが生成され、パーティション 0 に割り当てられると、再び開始されます。

ポーリング戦略は、負荷分散のパフォーマンスが非常に優れています。常にメッセージがすべてのパーティションに最大限に均等に分散されるようにすることができるため、デフォルト
これは、状況下で最も合理的なパーティショニング戦略
であり、最も一般的に使用されるパーティショニング戦略の 1 つでもあります。

2.6.2.2 ランダム性戦略 - ランダム性戦略


「ランダム」とは、以下の図に示すように、任意のパーティションにメッセージをランダムに配置することを意味します。​ 

 ランダム戦略は、古いバージョンのプロデューサーによって使用されていたパーティショニング戦略であり、新しいバージョンではポーリングに変更されました。

2.6.2.3 メッセージキーによる順序保持戦略 - キー順序付け戦略


Kafka では、メッセージごとにメッセージ キー (略してキーと呼ばれます) を定義できます。このキーは非常に便利で、顧客コード、部門番号、ビジネス ID など、明確なビジネス上の意味を持つ文字列にすることができ、メッセージのメタデータを表すためにも使用できます。特に Kafka がタイムスタンプをサポートしていなかった時代には、シナリオによっては、エンジニアがメッセージ作成時刻をキーに直接カプセル化していました。キーを使用してメッセージを定義すると、各パーティションではメッセージ処理が順次行われるため、同じキーを持つすべてのメッセージが同じパーティションに入ることが保証されます。 , したがって、この戦略はメッセージ キーによる順序保持戦略と呼ばれます。 key1 — 同じパーティションに属します key2 — 同じパーティションに属します




 

2.6.2.4 デフォルトのパーティション ルール。
  1. パーティションを指定する場合は、パーティションを直接入力します。
  2. パーティションが指定されていないがキーが指定されている場合、パーティションはキーのハッシュを使用して選択されます。
  3. パーティションもキーも指定されていない場合は、ポーリング 1 を使用してパーティションに入ります。

2.7 消費者

従来のメッセージ キュー モデルメッセージは消費されるとキューから削除されます。1 つのダウンストリーム コンシューマによってのみ消費できます。消費。このモデルのスケーラビリティは、下流の複数のコンシューマがこの共有メッセージ キューからメッセージを「取得」する必要があるため、非常に貧弱です。パブリッシュ/サブスクライブ モデルでは、複数のコンシューマがメッセージを消費できますが、各サブスクライバがトピックのすべてのパーティションをサブスクライブする必要があるため、あまりスケーラビリティが高くないという問題があります。この完全なサブスクリプション方法は柔軟性がなく、メッセージの実際の配信効果にも影響します。

コンシューマ グループが複数のトピックをサブスクライブする場合、グループ内の各インスタンスはトピックのすべてのパーティションをサブスクライブする必要はありません。一部のパーティションのメッセージのみを消費します。コンシューマ グループは互いに独立しており、相互に影響を及ぼさないため、相互に干渉することなく同じトピックのセットにサブスクライブできます。ブローカー側のメッセージ保持メカニズムと組み合わせることで、Kafka の Consumer Group は、前述のスケーラビリティの低さの問題を完全に回避します。 Kafka は Consumer Group メカニズムのみを使用していると言えますが、同時に従来のメッセージ エンジン
システムの 2 つの主要なモデルを実装しています。

すべてのインスタンス (コンシューマ) が同じグループに属している場合、ポイントツーポイント メッセージ キュー モデルが実装されます。
すべてのインスタンス (コンシューマ) が異なるグループに属している場合、次に、それが実装するのはパブリッシュ/サブスクライブ モデルです。
 

2.7.1 消費方法


コンシューマはプル モードを使用してブローカからデータを読み取ります。

プル モードでは、コンシューマの消費能力に基づいて、適切なレートでメッセージを消費できます。プル モードの欠点は、Kafka にデータがない場合、コンシューマーがループにはまり、空のデータを返し続ける可能性があることです。
コンシューマーはブローカーからデータを積極的に取得するため、長いポーリングを維持する必要があります。このため、Kafka コンシューマーはデータを消費するときに期間パラメーターのタイムアウトを渡します。現在、使用可能なデータがない場合、コンシューマは一定期間待機してから戻ります。この期間がタイムアウトになります。

2.7.2 パーティション割り当て戦略


コンシューマは複数のトピックをサブスクライブし、複数のパーティションを使用できます。1 つのパーティションは、複数のコンシューマ (同じコンシューマ グループ) による読み取りをサポートしません。

コンシューマ グループには複数のコンシューマがあり、トピックには複数のパーティションがあるため、必然的にパーティションの割り当てが必要になります
。つまり、どのコンシューマがそのパーティションを担当するかを決定する必要があります。パーティションの消費。コンシューマ グループ内のコンシューマの数が変化すると
、リバランスもトリガーされます。

Kafka には 4 つの割り当て戦略があり、パラメーターpartition.assignment.strategy によって構成できます。デフォルトは Range + CooperativeSticky です。

RoundRobin: クラスタ内のすべてのトピックに対して、ポーリング方式でコンシューマにパーティションを順番に割り当てます。
範囲、デフォルトは範囲です: トピックごとに、パーティション数 / コンシューマの数によって各コンシューマが消費するパーティションの数を決定します。分割できない場合、最初の数人のコンシューマがさらに 1 つのパーティションを消費します (パーティションの数をコンシューマの数で均等に割ることが最善です。そうしないと、トピックの数が増加するにつれてデータ スキューが大きくなります)深刻な)。
スティッキー: まず、パーティションは可能な限り均等にコンシューマに配置されます。同じコンシューマ グループ内のコンシューマに問題が発生した場合、元の割り当てが維持されます。パーティションは変更しません。
CooperativeSticky: 消費を止めずに増分再バランスを行います。


(1) RangeAssignor の割り当て戦略


RangeAssignor 割り当て戦略の原理は、コンシューマの総数とパーティションの総数に対して整数除算演算を実行してスパンを取得し、パーティションを割り当てることです。
パーティションがすべてのコンシューマーにできるだけ均等に分散されるように、スパンに従って均等に分散されます。

各トピックについて、RangeAssignor 戦略は、コンシューマ グループ内のこのトピックを購読しているすべてのコンシューマを名前順に辞書編集順に並べ替えてから、
各コンシューマの固定パーティションを分割します。範囲が均等に分散されていない場合、辞書編集上の順序が最も高いコンシューマに、もう 1 つのパーティションが割り当てられます

n=パーティション数/コンシューマ数、m=パーティション数%コンシューマ数と仮定すると、最初の m 個のコンシューマにはそれぞれ n+1 個のパーティションが割り当てられ、次の
(コンシューマの数 - m) 各コンシューマには n 個のパーティションが割り当てられます。

コンシューマ グループ内にトピック t0 と t1 をサブスクライブする 2 人のコンシューマ C0 と C1 があり、各トピックに 4 つのパーティションがあり、すべてのパーティションがサブスクライブされていると仮定します。
次のように識別できます。 :t0p0、t0p1、t0p2、t0p3、t1p0、t1p1、t1p2、t1p3。最終的な割り当て結果は次のとおりです。

コンシューマ C0: t0p0、t0p1、t1p0、t1p1
コンシューマ C1: t0p2、t0p3、t1p2、t1p3
この分布は非常に均一であるため、この配分戦略はこのような優れた特性を維持できるでしょうか?別の状況を見てみましょう。
上の例の両方のトピックにパーティションが 3 つだけあると仮定すると、サブスクライブされたすべてのパーティションは t0p0、t0p1、t0p2、
t1p0、t1p1、 t1p2 の最終的な割り当て結果は次のとおりです。

コンシューマ C0: t0p0, t0p1, t1p0, t1p1
コンシューマ C1: t0p2, t1p2
このような割り当てと不均等がはっきりとわかります。同様の状況が拡大すると、一部の消費者が過負荷になる可能性があります。
別の RoundRobinAssignor 戦略の割り当て効果を見てみましょう。

概要:
パーティションの数をコンシューマーの数で均等に除算できるようにすることが最善です。そうでないと、トピックの数が増加するにつれてデータの偏りが大きくなります。深刻

(2)RoundRobinAssignor割り当て戦略


RoundRobinAssi の割り当て戦略の原則は、コンシューマ グループ内のすべてのコンシューマのパーティションと、コンシューマがサブスクライブしているすべてのトピックをアルファベット順に並べ替えて
、それらを 1 つずつ割り当てることです。パーティションは各コンシューマに順番に割り当てられます。
に対応する RoundRobinAssignor 割り当て戦略の Partition.assignment.strategy パラメータ値は org.apache.kafka.C1ients.Consumer.RoundRobinAssignor です。

同じコンシューマ グループ内のすべてのコンシューマのサブスクリプション情報が同じ場合、RoundRobinAssignor 割り当て戦略の分割は
均等に分散されます。

例: コンシューマ グループ内にトピック t0 と t1 をサブスクライブしている 2 人のコンシューマ C0 と C1 があり、各トピックに 3 つのパーティションがあるとします。その場合、サブスクライブされたすべての
パーティションは次のようになります。 t0p0、t0p1、t0p2、t1p0、t1p1、t1p2 として識別されます。最終的な割り当て結果は次のとおりです。

コンシューマ C0: t0p0、t0p2、t1p1
コンシューマ C1: t0p1、t1p0、t1p2
同じ消費グループ内のコンシューマの場合 サブスクライブされた情報の場合が異なる場合、パーティション割り当てを実行するときに完全なポーリング割り当てにならず、パーティションが不均一に分散される可能性があります。コンシューマがコンシューマ グループ内のトピックをサブスクライブしていない場合、コンシューマはパーティションを割り当てるときにこのトピックのパーティションを割り当てることができません。

例: コンシューマ グループに 3 人のコンシューマ (C0、C1、C2) がいて、合計 3 つのトピック (t0、t1、t2) をサブスクライブしているとします。これらの 3 つのトピックはそれぞれ < a i=1> 1、2、および 3 パーティション。つまり、コンシューマ グループ全体が 6 つのパーティション (t0p0、t1p0、t1p1、t2p0、t2p1、および t2p2) をサブスクライブします。具体的には、コンシューマ C0 はトピック t0 をサブスクライブし、コンシューマ C1 はトピック t0 と t1 をサブスクライブし、コンシューマ C2 はトピック t0、t1、および t2 をサブスクライブし、 > そして最後の割り当て結果は次のとおりです:


コンシューマ C0: t0p0
コンシューマ C1: t1p0
コンシューマ C2: t1p1、t2p0、t2p1、t2p2
RoundRobinAssignor 戦略は完全ではないことがわかりますが、パーティション t1p1 はコンシューマ C1 に割り当てられる可能性があるため、この割り当ては実際には最適な解決策ではありません。

したがって、注意すべき点があります。RoundRobinAssignor 戦略を使用する場合、コンシューマーは同じトピックをサブスクライブする必要があります。

(3) StickyAssignor の割り当て戦略


StickyAssignor の割り当て戦略を見てみましょう。「sticky」という単語は「スティッキー」と翻訳できます。Kafka はバージョン 0.11.x からこの割り当て戦略を導入しました
。主な目的は 2 つあります。
(1) パーティションの割り当ては可能な限り均等である必要があります。
(2) パーティションの割り当ては可能な限り一貫している必要があります。最後の割り当てで可能です。同じです。

2 つの目標が矛盾する場合、最初の目標が 2 番目の目標より優先されます。

これら 2 つの目標を考慮すると、StickyAssignor 割り当て戦略の具体的な実装は、RangeAssignor と RoundRobinAssignor の 2 つの割り当て戦略よりもはるかに複雑です
。 StickyAssignor 割り当て戦略の実際の効果を見てみましょう。

コンシューマ グループに 3 人のコンシューマ (C0、C1、C2) があり、彼ら全員が 4 つのトピック (t0、t1、t2、t3) をサブスクライブし、各トピックに 2 つのトピックがあるとします。
パーティション。つまり、コンシューマ グループ全体が 8 つのパーティション (t0p0、t0p1、t1p0、t1p1、t2p0、t2p1、t3p0、および t3p1) をサブスクライブします。 最終的な配布結果は次のとおりです。

コンシューマ C0: t0p0、t1p1、t3p0
コンシューマ C1: t0p1、t2p0、t3p1
コンシューマ C2: t1p0、t2p1 この時点でコンシューマ C1 がコンシューマ グループから離れると仮定すると、コンシューマ グループはリバランス操作を実行し、消費パーティションが再分配されます。 が RoundRobinAssignor 割り当て戦略を採用する場合、この時点での割り当て結果は次のようになります。


コンシューマ C0: t0p0, t1p0, t2p0, t3p0
コンシューマ C2: t0p1, t1p1, t2p1, t3p1
割り当て結果に示すように、 RoundRobinAssignor 割り当て戦略は、コンシューマ C0 および C2 に従って再ポーリングされ、割り当てられます。現時点で
が StickyAssignor 割り当て戦略を使用している場合、割り当て結果は次のようになります。

コンシューマ C0: t0p0, t1p1, t3p0, t2p0
コンシューマ C2: t1p0, t2p1, t0p1, t3p1
割り当て結果が表示されます すべて最後の割り当てにおける消費者 C0 と C2 への割り当て結果は保持され、元の消費者 C1 の「負担」が残りの 2 つの消費者 C0 と C2 に割り当てられ、C0 と C2 の最終的な配分はバランスが保たれます。

パーティションの再割り当てが発生した場合、同じパーティションについて、以前のコンシューマと新しく割り当てられたコンシューマが異なる可能性があります。
前のコンシューマは処理の途中です。新しく割り当てられたコンシューマで再度繰り返す必要がありますが、これは明らかにシステム リソースの無駄です。

StickyAssignor 割り当て戦略は、その名前の「st1cky」に似ており、割り当て戦略にある程度の「スティッキー性」を持たせ、
の 2 つの割り当てを行います。可能な限り同じ状態に保ち、システムリソースの損失やその他の異常事態の発生を軽減します。

ここまでは、消費者の購読情報が同じ場合の分析でしたが、購読情報が異なる場合の
の処理を​​見てみましょう。

たとえば、同じコンシューマ グループ内に 3 つのコンシューマ (C0、C1、および C2) があり、クラスタ内に 3 つのトピック (t0、t1、および t2) があります。これらの 3 つのトピックはそれぞれ
1、2、3 パーティション。つまり、クラスターには 6 つのパーティション (t0p0、t1p0、t1p1、t2p0、t2p1、および t2p2) があります。コンシューマ
C0 はトピック t0 をサブスクライブし、コンシューマ C1 はトピック t0 と t1 をサブスクライブし、コンシューマ C2 はトピック t0、t1、および t2 をサブスクライブします。このとき
RoundRobinAssignor 割り当て戦略が使用されている場合、最終的な割り当て結果は RoundRobinAssignor 割り当て戦略を使用した場合と同じになります。

RoundRobinAssignor 割り当て戦略の割り当て結果

コンシューマ C0: t0p0
コンシューマ C1: t1p0
コンシューマ C2: t1p1、t2p0、t2p1、t2p2
このとき、StickyAssignor の割り当て戦略が採用された場合、最終的な割り当て結果は次のようになります。
StickyAssignor 割り当て戦略の割り当て結果

コンシューマ C0: t0p0
コンシューマ C1: t1p0、t1p1
コンシューマ C2: t2p0、t2p1、t2p2
これが最適な解決策であることがわかります (コンシューマ C0 はトピック t1 および t2 をサブスクライブしていないため、トピック t1 および t2 のパーティションを割り当てることができません。コンシューマ C1 についても同じことが推測できます)。

この時点でコンシューマ C0 がコンシューマ グループを離れる場合、RoundRobinAssignor 割り当て戦略の割り当て結果は次のようになります。

コンシューマ C1: t0p0, t1p1
コンシューマ C2: t1p0, t2p0, t2p1, t2p2
RoundRobinAssignor 戦略がコンシューマの割り当てを保持していることがわかります。 C1 と C2 の元の 3 つのパーティション、t2p0、t2p I、および t2p2 のうちの 1 つです。

StickyAssignor 割り当て戦略が使用される場合、割り当て結果は次のようになります。

コンシューマ C1: t1p0, t1p1, t0p0
コンシューマ C2: t2p0, t2p1, t2p2
StickyAssignor 割り当て戦略が消費を保持していることがわかります。またはC1 と C2 の元の 5 つのパーティションの割り当て: t1p0、t1p1、t2p0、
t2p1、t2p2。

StickyAssignor 割り当て戦略を使用する利点の 1 つは、パーティションの再割り当てを「スティッキー」にし、不要なパーティションの移動を減らすことができることです(つまり、
パーティションが削除される前にコンシューマが割り当てられ、その後、パーティションが削除される前にコンシューマに割り当てられる)
StickyAssignor 割り当て戦略は他の 2 つの割り当て戦略よりも優れていますが、この戦略のコード実装も非常に複雑なので紹介しません。

2.8 データの信頼性保証


プロデューサーによって送信されたデータが指定されたトピックに確実に送信されることを保証するために、トピックの各パーティションは、プロデューサーによって送信されたデータを受信した後、プロデューサーに ACK (受信を確認する ACKnowledge) を送信する必要があります。プロデューサーが ACK を受信すると、次のラウンドの送信を実行します。そうでない場合は、データを再送信します。
 

2.8.1 レプリ​​カデータの同期戦略

リーダーが ACK を送信する前に、フォロワーとリーダーが同期されていることを確認します。これにより、リーダーが電話を切った後、データを失うことなく新しいリーダーをフォロワーの中から選出できます。

 

2.8.1.1 ISR(同期レプリカセット)


推測? ? ?

2 番目の解決策を使用して ack を同期した後、リーダーがデータを受信すると、すべてのフォロワーがデータの同期を開始しますが、1 人のフォロワーが何らかの障害によりリーダーと同期できない場合、リーダーは永遠に待機する必要があります。同期が完了するまで送信できません。現時点でこの問題を解決するにはどうすればよいですか?

解決する! ! !

リーダーは、リーダーと同期しているフォロワーのセットである動的 ISR (同期レプリカ セット) を維持します。ISR 内のフォロワーがデータ同期を完了すると、リーダーに ack を送信します。リーダーとデータを長時間同期すると、フォロワーは ISR から追い出され、しきい値は、replica.lag.time.max.ms パラメーターによって設定されます。リーダーが失敗すると、ISR から新しいリーダーが選出されます。
 

2.8.2 ACK 応答メカニズム

Kafka はユーザーに 3 つの信頼性レベルを提供しており、ユーザーは信頼性と遅延の要件の間のトレードオフに基づいて次の構成を選択できます。

ACKパラメータの設定:

0:プロデューサーはブローカーの ACK を待ちません。これにより、遅延が最小限になります。ブローカーは、データがディスクに書き込まれる前に、データを受信するとすぐに戻ります。ブローカーが失敗するとデータが失われます。


1:プロデューサーはブローカーからの ACK を待ち、パーティションのリーダーが正常に配置された後に ACK を返します。フォロワーの同期が成功する前にリーダーが失敗すると、データが失われます。


-1 (すべて):プロデューサーはブローカーの ACK を待ち、パーティションのリーダーとフォロワーがすべて正常に配置された後でのみ ACK を返します。ただし、Broker が ACK を送信し、Leader が失敗すると、データの重複が発生します。
 

 2.8.3 信頼性指標


1. パーティション コピー。信頼性を向上させるためにさらにパーティションを作成できますが、パーティションが多すぎるとパフォーマンスのオーバーヘッドも発生します。一般的に、3 つのコピーで、ほとんどのシナリオの信頼性要件を満たすことができます。

(たとえば、パーティションが多すぎる場合、kafka はこれらのパーティションを維持し、それを確実にするために多数のコピーを作成する必要があります。パーティションが多すぎても、パーティションが破損した場合に失われるデータははるかに少なくなりますが、同じパフォーマンスでも大幅に低下します。メンテナンスのためにパーティションのコピーを同期する必要があるためです)


2. ACKS、プロデューサーによって送信されたメッセージの信頼性。つまり、メッセージがブローカーに到達し、複数のコピーの永続化を完了する必要があることを確認する必要があります。

(ただし、ack がすべてのコピーの永続性と同期を確保したい場合、実際にはパフォーマンスの低下を引き起こします。理解できない場合は、ack 応答メカニズムにアクセスして、もう一度確認してください。)


3. 保証 メッセージがブローカーに到着した後、コンシューマにはメッセージが消費されない原因となる問題が発生する可能性があるため、コンシューマにも特定の保証が必要です。


4.enable.auto.commit のデフォルトは true で、これはオフセットを自動的に送信することを意味します。自動送信はバッチで実行され、時間枠があります。この方法では、繰り返し送信やメッセージ損失の問題が発生するため、高信頼性要件の場合は手順を使用してください。提出。高い信頼性要件が求められるアプリケーションの場合、異常な消費によりメッセージが失われるよりも、繰り返し消費する方が良いでしょう。


要約する


トピックに複数のパーティションがあるシナリオでは、Kafka は同じパーティション内のメッセージの順序のみを保証できますが、異なるパーティション間のメッセージの順序は保証できません。
一般に、3 つのコピーを構成すると、ほとんどのニーズを満たすことができます。
コンシューマは複数のトピックをサブスクライブし、複数のパーティションを使用できますが、1 つのパーティションは複数のコンシューマ (同じコンシューマ グループ) による読み取りをサポートしません。

 

        すべてのコンシューマがグループに属している場合、それは 1 対 1 およびポイントツーポイントの消費であり、各コンシューマが異なるグループに属している場合、メッセージはすべてのコンシューマにブロードキャストされます。これは実際にはパーティションに従って分割されます。パーティションはコンシューマ グループ内の 1 つのコンシューマによってのみ使用できますが、複数のコンシューマ グループ内のコンシューマによって同時に使用できます (競合は発生しません)。各コンシューマには対応するパーティションがあります。したがって、トピックの場合、同時に消費する同じグループ内のパーティション コンシューマの数を超えることはできません。そうしないと、一部のコンシューマがデータを消費できなくなります。
 

おすすめ

転載: blog.csdn.net/txh1873749380/article/details/134784969