【カフカエントリーから廃墟シリーズ4】カフカ建築徹底プロデューサー作戦

前回のブログでは、Kafkaの基本的なワークフローとストレージメカニズムの概要を説明しましたが、実際には分散システムの独自の視点から考えたものでした。このブログでは、Kafkaのプロデューサー関連の戦略を紹介しています。最終的な分析では、サポート分散システムの特性[ 高いスケーラビリティ、高可用性、高い同時実行性、大容量ストレージ ]の観点。

パーティション戦略

Kafkaには、トピックパーティションごとにN個のレプリカがあります。N(1以上)は、トピックレプリケーションファクター(レプリカフィルター)の数です。Kafkaは、複数のコピーメカニズムを通じて自動フェイルオーバーを実装します。ブローカーがKafkaクラスターで失敗した場合、コピーメカニズムはサービスの可用性を確保できます。パーティションの場合、N個のレプリカのうち、1つのレプリカがリーダーで、他のレプリカがフォロワーです。リーダーはパーティションのすべての読み取りおよび書き込みリクエストを処理し、フォロワーはリーダー上のデータを受動的に複製します。
ここに画像の説明を挿入

パーティションの理由

なぜ分割するのですか?以前のブログ[Kafka入門から中止シリーズ3まで] Kafkaアーキテクチャは詳細です。ワークフローとストレージメカニズムが詳細に導入されています。もう一度強調しましょう。

  • 高いスケーラビリティ:クラスタ内で拡張すると便利です。各パーティションは、配置されているマシンに合わせて調整できます。トピックは複数のパーティションで構成できるため、クラスタ全体が任意のサイズのデータ​​に適応できます
  • 高い同時実行性:パーティション単位で読み書きできるため、同時実行性を向上でき、トピックの複数のパーティションに同時にメッセージを送信できます。
  • 高可用性:もちろん、高可用性と高いスケーラビリティーにより、クラスター全体が安定し、同時状況下でメッセージが失われないことも期待しています。データの信頼性を確保するために、各パーティションの複数のコピーを確保してメッセージが失われることはありません。リーダーが配置されているブローカーに障害が発生するかダウンすると、リーダーがないため、対応するパーティションはクライアント要求を処理できません。このとき、コピーの役割が反映されます。フォロワーから新しいリーダーが選出され、続行されますクライアント要求の処理

上の図に示すように、分散クラスターの特性を反映できます。実際、Kafkaだけでなく、すべての分散ミドルウェアにもこの概念があります。たとえば、ElasticSearchにはノードノード、インデックス、シャーディング、レプリケーションもあります。 Kafkaのブローカーに対応して、トピック、パーティション、レプリカはすべてBeldenに接続されています。

ゾーニングの原則

プロデューサーはプッシュモードを使用してメッセージをブローカーにパブリッシュし、各メッセージはパティションに追加されます。これはディスクへの順次書き込みです(ディスクへの順次書き込みはメモリへのランダム書き込みよりも効率的であり、Kafkaのスループットレートを保証します)。プロデューサーがブローカーにメッセージを送信するとき、パーティションがあるため、プロデューサーのメッセージの送信先となるパーティションをどのようにして知ることができますか?プロデューサは、パーティションアルゴリズムに従って、どのパーティションに格納するかを選択します。
ここに画像の説明を挿入
コード構造から、それが実際に3つの方法、つまり、メッセージが送信されるパーティションを決定する3つのルーティングメカニズムに要約できることがわかります。

  1. パーティションを指定する場合は、指定した値を直接パーティション値として使用します。
  2. パーティション値が指定されていないがキーがある場合、キーのハッシュ値の残りとトピックのパーティション番号を取得して、パーティション値を取得します。
  3. パーティション値もキー値もない場合、最初の呼び出しで整数がランダムに生成され(後続の呼び出しごとにこの整数が増分されます)、この値とトピックで使用可能なパーティションの総数が取得され、パーティション値が取得されます。これは、よく呼ばれるラウンドロビンアルゴリズム [ポーリングアルゴリズム]です。

メッセージがパーティションに送信される方法を理解した後、高いスケーラビリティと高い同時実行性を解決しました。また、問題、高いスケーラビリティを確保する方法、つまりデータを確実に送信する方法についても考える必要があります。

データの信頼性保証

プロデューサーから送信されたデータを指定されたトピックに確実に送信できるようにするには、トピックの各パーティションで、プロデューサーから送信されたデータを受信した後で、ack(確認応答)をプロデューサーに送信する必要があります。プロデューサーがackを受信した場合、次のラウンドを送信します。それ以外の場合は、データを再送信します。
ここに画像の説明を挿入

ACK応答メカニズム[ACK送信タイミング]

Kafkaは、ユーザーに3つのレベルの信頼性を提供します。ユーザーは、信頼性とレイテンシの要件を比較検討できます。プロデューサーがリーダーにデータを送信するとき、データの信頼性レベルはrequest.required.acksパラメーターで設定できます。

  1. request.required.acks = 0、プロデューサーは成功メッセージのリーダーのフィードバックなしでリーダーにデータを継続的に送信します。この場合、データ伝送効率は最高ですが、データの信頼性は実際に最低です。送信プロセス中にデータが失われたり、リーダーがダウンしたときにデータが失われたりする可能性があります。[ 最高の伝送効率、最低の信頼性 ]

  2. request.required.acks = 1、これはデフォルトの状況です。つまり、プロデューサーはリーダーにデータを送信し、リーダーはローカルログに正常に書き込み、クライアントに正常に戻ります。このとき、ISRの他のコピーにはメッセージをプルする時間がありませんでした。リーダーがダウンしている場合、今回送信されたメッセージは失われます。伝送効率、信頼性
    ここに画像の説明を挿入

  3. request.required.acks = -1(すべて)、プロデューサーはデータをリーダーに送信します。データを受信した後、リーダーは、ISRリストのすべてのコピーがデータを同期するまで(強い整合性)、プロデューサーに成功メッセージを返します。成功メッセージが受信されなかった場合、データの送信に失敗したと見なされると、データは自動的に再送信されます。これは最も信頼できるソリューションです。もちろん、パフォーマンスも影響を受けます。[ 伝送効率が低く、信頼性が高い ]同時に、ブローカーがackを送信する前にフォロワーの同期が完了した後でリーダーが失敗すると、データが重複する
    ここに画像の説明を挿入

request.required.acks = -1の場合は注意が必要です。データの信頼性を向上させたい場合は、request.required.acks = -1を設定しながら、パラメーターmin.insync.replicasも連携して効果を最大化する必要があります。min.insync.replicasこのパラメーターは、ISR内のレプリカの最小数を設定するために使用されます。デフォルト値は1です。このパラメーターは、request.required.acksパラメーターが-1に設定されている場合にのみ有効になります。ISR内のレプリカの数がmin.insync.replicasで構成された数より少ない場合、クライアントは例外を返します:org.apache.kafka.common.errors.NotEnoughReplicasExceptoin:同期レプリカが必要数よりも少ないため、メッセージは拒否されます。パラメータmin.insync.replicasを2に設定すると、ISR内のレプリカの実際の数が1(リーダーのみ)の場合、信頼性は保証されません。リーダーがackを送信した後にダウンした場合、メッセージは損失。したがって、メッセージの損失を防ぐために、クライアントの書き込み要求を拒否する必要があります

レプリカ同期戦略[ACK送信条件]

では、ackを送信する前に、いくつのfollerコピーが同期されるのでしょうか。既存の2つのソリューションは2番目のソリューションを選択します。1番目のソリューションはマシンリソースを占有しすぎて大量のデータ冗長性を引き起こし、ネットワーク遅延はKafkaにほとんど影響しません。
ここに画像の説明を挿入

ISR選挙戦略

完全なレプリカ同期スキームを採用した後、ackを送信するタイミングは次のように決定されます。リーダーがデータを受信し、すべてのフォロワーがデータの同期を開始しますが、次の状況を想像してください。ある種の障害のためにフォロワーが存在し、遅延がリーダーと同期できない場合、リーダーは、ACKを送信する前に、同期が完了するまで待機する必要があります。この問題を解決するには?ISRのコンセプトを紹介します

  • すべてのコピー(レプリカ)は、まとめて割り当てられたレプリカまたはARと呼ばれます
  • ISRはARのサブセットです。リーダーはISRリストを維持します。フォロワーはリーダーからのデータの同期にいくらかの遅延があります(タイムアウトしきい値はパラメーターreplica.lag.time.max.msによって設定されます)。しきい値を超えるフォロワーはISRから除外されます。 OSR(非同期レプリカ)リストをデポジットすると、新しく追加されたフォロワーが最初にOSR保存されます
  • AR = ISR + OSR、つまり、すべてのコピー=利用可能なコピー+バックアップコピー
  • ISRリストには、リーダー+リーダーと同期しているフォロワーが含まれます。リーダーが失敗すると、ISRから新しいリーダーが選出されます

このメカニズムでは、ISRは常に動的で安定したクラスターです。メッセージが到着した後、リーダーは最初にそれを読み取り、次にそれを各フォロワーにプッシュして、ISR内の各コピーが同期状態にあることを確認します。リーダーが切断すると、すぐにISRから取得できます。メッセージを処理する新しいリーダーを選出します。

障害処理メカニズム[コピー同期の保証]

データ信頼性保証戦略では、パーティションとレプリカ、および動的ISRとackメカニズムを通じてメッセージの信頼性を確保する方法を学びました。次に、障害が発生したときにクラスターを通常の状態に戻す方法を詳しく説明します

HW&LEOの基本概念

ここに画像の説明を挿入
HWとLEO間のメッセージフロープロセスは次のとおりです
ここに画像の説明を挿入
。Kafkaのレプリケーションメカニズムは、完全な同期レプリケーションでも、純粋な非同期レプリケーションでもありません。実際、同期レプリケーションでは、このメッセージがコミットされる前に、動作しているすべてのフォロワーがレプリケートされている必要があります。このレプリケーション方法は、最も遅いフォロワーに制限され、スループットレートに大きな影響を与えます。非同期複製モードでは、フォロワーがリーダーからデータを非同期に複製します。データがリーダーによってログに書き込まれている限り、データはコミットされたと見なされます。この場合、フォロワーがまだ複製されておらず、リーダーの後ろにいる場合、リーダーは突然ダウンします。データが失われ、信頼性が低下しますISRを使用するKafkaの戦略により、信頼性とスループットのバランスが取れています[ レプリケーションを同期し、低速のレプリカを削除する ]

障害同期メカニズム

さまざまなマシンに障害が発生した場合、ISRがクラスターとメッセージをどのように処理するかを見てみましょう。これらはフォロワーの障害とリーダーの障害に分けられます。

  • フォロワーが失敗した場合、フォロワーは失敗後に一時的にISRから追い出されます。フォロワーが回復した後、フォロワーはローカルディスクに記録された最後のハードウェアを読み取り、ログファイルのHWより高い部分をインターセプトし、リーダーからハードウェアから開始します同期します。フォロワーのLEOがパーティションのHW以上になった後、つまりフォロワーがリーダーに追いついた後、ISRに再参加できます。
  • リーダーが失敗しますリーダーが失敗した後、ISRから新しいリーダーが選択されます。その後、複数のコピー間のデータの整合性を確保するために、残りのフォロワーは最初にログファイルのHWより高い部分を切り取ります、そして新しいリーダーからのデータを同期します。

全体として、すべてのコピーと同期された最新のハードウェアが優先されます。ただし、これは単なる処理方法であり、データが繰り返されたり失われたりしないことを保証するものではありません。データの重複のケースを見てみましょう:リーダーがダウンしています:シナリオを考えます:acks = -1、ISRコピーの一部が同期を完了します。次の図に示すように、電話を切ります。follower1がメッセージ4と5を同期し、follower2がメッセージ4を同期します。同時に、follower2がリーダーとして選出されます。
ここに画像の説明を挿入
このようにしデータ重複の現象発生するため、HW&LEOメカニズムはコピーが同期されていることのみを保証できますが、データが繰り返されたり失われたりしないことを保証することはできません。すべてを保証したい場合は、ACKレベルを組み合わせて食べる必要があります。

リーダー選挙

障害が発生した可能性がある場合、リーダーがハングしたときに、次の戦略に従って新しいリーダーを選出する必要があります。KafkaはZooKeeperの各パーティションのISRを動的に維持し、このISRのすべてのレプリカはリーダーと同期されます、ISRのメンバーのみがリーダーとして選出できます。

もちろん、極端なケースもあります。ISRが少なくとも1人のフォロワー(リーダーを含むISR)の場合、Kafkaはコミットメッセージが失われないことを確認できますが、すべてのレプリカの1つのパーティションがハングアップした場合、当然、データが失われないことを保証できません。この場合、リーダー選挙はどのように行うのですか?通常、2つのオプションがあります。

  • ISR内のレプリカが回復するのを待って、それをリーダーとして選択します[ 高信頼性 ]
  • 最初にリカバリされたレプリカ(ISRである必要はありません)をリーダーとして選択します [ 高可用性 ]

ISR内のレプリカが回復するのを待つ必要がある場合、使用できない時間が比較的長くなる可能性があります。ISR内のすべてのレプリカを回復できない場合、またはデータが失われた場合、このパーティションは使用できなくなります。最初に回復されたレプリカをリーダ​​ーとして選択します。このレプリカがISR内のレプリカでない場合は、コミットされたメッセージがすべて含まれていない可能性があり、結果としてメッセージが失われます。デフォルトでは、Kafkaは2番目の戦略unclean.leader.election.enable = trueを使用するか、このパラメーターをfalseに設定して最初の戦略を有効にすることができます

正確に1回のセマンティクス

レプリカ間の同期確保するための障害回復メカニズムと、データの信頼性確保するためのACKメカニズム理解した後、データ送信のべき等性を確保する方法について説明します。

  • サーバーのACKレベルを-1に設定すると、プロデューサーとサーバーの間でデータが失われないようにすることができます。つまり、AtLeast Onceのセマンティクスです。AtLeast Once は、データが失われないことを保証できますが、データが繰り返されないことは保証できません
  • サーバーのACKレベルを0に設定すると、プロデューサーの各メッセージが1度だけ送信されることを保証できます。つまり、最大1回のセマンティクス

いくつかの非常に重要な情報については、消費者はデータが繰り返されたり失われたりしないこと、つまりExactly Onceセマンティクスを要求します。バージョン0.11より前のKafkaはこれについて何もできません。データが失われないことを保証するだけで、ダウンストリームコンシューマーはデータをグローバルに重複排除します。複数のダウンストリームアプリケーションの場合、それぞれをグローバルに個別に重複排除する必要があるため、パフォーマンスに大きな影響があります。

べき等

Kafkaバージョン0.11では、べき等性という主要な機能が導入されました。いわゆるべき等性とは、プロデューサーが繰り返しデータをサーバーに送信する回数に関係なく、サーバーが保持するのは1つだけであることを意味します。べき等性を少なくとも1回のセマンティクスと組み合わせて、カフカのExactly Onceセマンティクスを構成します。つまり、少なくとも1回+べき等=正確に1回

べき等を有効にするには、Producerのパラメーターのenable.idompotenceをtrueに設定するだけです。Kafkaのべき等性の実現は、元のダウンストリームのニーズをアップストリームのデータに置き換えることです。べき等性がオンになっているプロデューサーには、初期化時にPIDが割り当てられ、同じパーティションに送信されるメッセージにはシーケンス番号が付随します。ブローカーは<PID、Partition、SeqNumber>をキャッシュします。同じ主キーを持つメッセージが送信されると、ブローカーは1つだけ保持します。ただし、再起動するとPIDが変更され、パーティションごとに主キーも異なるため、べき等性はパーティション間およびセッション間で1回のみを保証できません

プロデューサー業務

パーティション間のクロスセッションデータトランザクションを実現し、再起動によるPIDの重複を防ぐために、トピックのグローバルに一意のトランザクションIDを導入し、PIDプロデューサーが取得したIDとトランザクションバインドする必要があります。このようにして、プロデューサーを再起動すると、進行中のTransactionIDを通じて元のPIDを取得できます。トランザクションを管理するために、Kafkaは新しいコンポーネントのトランザクションコーディネーターを導入しました。プロデューサーは、トランザクションコーディネーターとやり取りすることで、トランザクションIDに対応するタスクステータスを取得します。トランザクションコーディネーターは、すべてのトランザクションをKafkaの内部トピックに書き込む役割も果たします。これにより、サービス全体が再起動された場合でも、トランザクションステータスが保存されるため、進行中のトランザクションステータスを復元できます。継続するように。

総括する

このブログでは、パーティション化メカニズムからデータ信頼性メカニズム、障害回復メカニズムまで、カフカのプロデューサー戦略を詳細に説明し、最後にメッセージの正確な一度のセマンティクスを実装する方法を説明します。カフカの主な戦略は依然としてプロデューサー側に集中しているようです。理解するのはもっと複雑です。ただし、リソースをスケジューリングと交換することは有益であり、複雑なスケジューリングによってリソースを節約することは有益です。

コンテンツの一部はhttps://gitbook.cn/books/5ae1e77197c22f130e67ec4e/index.htmlから引用されています

おすすめ

転載: blog.csdn.net/sinat_33087001/article/details/108397968