【編集後記】Kafka を大規模に利用する場合、さまざまな問題に遭遇することがよくあります。たとえば、ビッグ データ クラスター内の一部のジョブでは、常にいくつかのタスクが遅く、その結果、タスク全体が遅延することがあります。この状況は通常、より複雑です。具体的な遅延を知るには、Kafka クラスターのどのポイントでエンドツーエンドの遅延が増加する可能性があるかを知る必要があります。 以下の内容は、Confluent 公式サイトのブログ記事から翻訳したものです。 Kafka を使用する際のエンドツーエンドのレイテンシーを理解する上で役立つことを願っています。 不正検出、支払いシステム、株式取引プラットフォームは、高速で予測可能なデータ配信を必要とする多くの Apache Kafka ユースケースのほんの一部です。たとえば、オンライン バンキング取引の不正検出は、優れた顧客エクスペリエンスを維持するために、各取引に 50 ~ 100 ミリ秒を超えるオーバーヘッドを追加することなく、ビジネス価値を提供するためにリアルタイムで実行する必要があります。 Kafka の用語では、データ配信時間はエンドツーエンドのレイテンシによって定義されます。これは、コンシューマーが Kafka に生成されたレコードを取得するのにかかる時間です。レイテンシ目標は、ターゲットレイテンシと、この目標を達成することの重要性として表現されます。たとえば、レイテンシの目標は次のように表現できます。Kafka から 99% の時間でエンドツーエンドのレイテンシを 50 ミリ秒に抑えたい。 これにより、可用性、耐久性、スループットの目標が向上します。高い耐久性と高いスループットという 2 つの目標を達成するには、一定のトレードオフを行う必要があります。課題は、レイテンシの制限を維持しながらアプリケーションのスループットを拡張し、許容可能なブローカー レイテンシでクライアントおよび複製されたリクエストを処理するために Kafka クラスターのサイズを調整することです。レイテンシはハードウェアやクラウド プロバイダーの選択によっても異なるため、独自の環境で特定のレイテンシ目標を達成するには、クライアントを監視および調整できる必要があります。 注: 通常、ブローカーが配置されているネットワーク領域は、実際にはレイテンシに大きな影響を与えます。もちろん、これは可用性とレイテンシーの間のトレードオフに依存します。 以前、私たちは「Apache Kafka デプロイメントの最適化」というホワイト ペーパーを作成しました。このホワイト ペーパーには、さまざまな目標を最適化するために Kafka デプロイメントを構成するためのガイドラインが記載されています。 この投稿は、エンドツーエンドのレイテンシに対する直感と理解をさらに深め、レイテンシの制限を維持しながらアプリケーションのスループットを構成および拡張するのに役立ちます。 エンドツーエンドのレイテンシを理解する エンドツーエンドのレイテンシとは、アプリケーション ロジックが KafkaProducer.send() を呼び出してメッセージを生成してから、そのメッセージが KafkaConsumer.poll() を介してアプリケーション ロジックによって消費されるまでの時間を指します。 次の図は、Kafka プロデューサーから Kafka ブローカー ノードまでのシステム内のレコードのパス、レプリカのレプリケーション、そしてコンシューマーが最終的にメイン パーティション ログで特定のメッセージを取得する様子を示しています。 したがって、エンドツーエンドの遅延は主に次のコンポーネントで構成されます。
以下の内容では、これら 5 つの遅延段階の具体的な意味をそれぞれ説明します。通常、特定のクライアント構成やアプリケーション ロジックの設計はエンドツーエンドの遅延に大きく影響するため、遅延に最も大きな影響を与える要因を正確に特定する必要があります。
プロデュース時間とは、アプリケーションが KafkaProducer.send() を通じてレコードを生成してから、メッセージを含むプロデューサー要求がリーダーレプリカが配置されているブローカーに送信されるまでの時間を指します。 (そのため、プロデューサーのネットワーク環境と、対応するトピックパーティションのリーダーコピーが配置されているブローカーのネットワークが、プロデュース時間の遅延に影響を与える可能性があります) Kafka プロデューサーは、同じトピック パーティションの下にあるメッセージのグループをまとめてバッチにパッケージ化し、ネットワーク I/O パフォーマンスを向上させます。 (必要に応じて、生産者のバッチサイズを調整できます) デフォルトでは、プロデューサーはバッチをすぐに送信するため、通常、バッチには大量のメッセージが含まれません。バッチ処理の効率を向上させるために、プロデューサーは通常、linger.ms の遅延を小さく設定して、十分なメッセージ レコードを 1 つのバッチにカプセル化できるようにします。 linger.ms イベントが経過するか、バッチ サイズが最大値 (batch.size のパラメーター値) に達すると、バッチは完了したと見なされます。 プロデューサーも圧縮 (compression.type) をオンにすると、Kafka プロデューサーは完了したバッチを圧縮します。バッチが完了する前に、プロデューサーによって指定された圧縮タイプと以前に観測された圧縮率に基づいてバッチのサイズが推定されます。 リーダー レプリカに送信された未確認のプロデューサー リクエストの数が最大値 (max.inflight.requests.per.connection=5) に達した場合、プロデューサーでのバッチ処理の待機時間が長くなる可能性があります。したがって、ブローカーがプロデューサーのリクエストに応答する速度が速いほど、プロデューサーの待機時間は短くなります。
公開時間とは、内部 Kafka プロデューサーがブローカー ノードにプロデューサー要求を送信してから、対応するメッセージがリーダー レプリカ ログに到着するまでの時間を指します。リクエストがブローカー ノードに到着すると、接続を担当するネットワーク スレッドがリクエストを取得し、リクエスト キューに格納します。リクエスト ハンドラー スレッドの 1 つがキューからリクエストを取得して処理します。 (ブローカー ノードの 2 つの関連パラメータ num.thread と num.io.thread に対応) したがって、公開時間には、プロデューサー要求のネットワーク時間、ブローカー上のキューイング時間、およびメッセージをログに追加するのに要した時間 (通常はページ キャッシュ アクセス時間も) が含まれます。ブローカーの負荷が低い場合、ネットワークとログ追加書き込み時間が公開時間に影響します。ブローカーの負荷が増加すると、キューの遅延の増加が公開時間に大きな影響を与えます。
コミット時間とは、リーダー レプリカからすべての同期レプリカにメッセージをコピーするのにかかる時間を指します。 Kafka はコミットされたメッセージのみをコンシューマーに公開します。つまり、メッセージはすべての ISR に含まれている必要があります。フォロワー レプリカ内のメッセージは、リーダー レプリカから並行して取得されます。通常のクラスターでは、レプリカが同期していない状態になることは通常望ましくありません (もちろん、一部のビジネス シナリオでは短期的な非同期が発生する可能性があります)。つまり、メッセージがコミットされるまでの時間は、ISR 内で最も遅いフォロワー レプリカを持つブローカーが元帳ブローカー ノードからレコードを取得してフォロワー レプリカ ログに書き込むのにかかる時間と等しくなります。 データをコピーするために、フォロワーが配置されているブローカーはリーダー ノードにフェッチ要求を送信します。正確に言うと、コンシューマーもフェッチ要求を使用してメッセージを取得します。ただし、公式ブローカーはレプリカ レプリケーションのフェッチ要求のデフォルト構成を最適化しています。リーダー レプリカはできるだけ早く要求を送信し、使用可能なバイトがある限り (replica.fetch.min.bytes パラメータによって制御)、または replica.fetch.wait.max.ms 条件が満たされると、フェッチ要求を開始します。コミット時間は主にレプリカ構成パラメータとクラスターの現在の負荷によって影響を受けます。
新しいオフセットが明示的に宣言されるか、新しいコンシューマーが最新のオフセットから消費しない限り、Kafka 内のメッセージは生成された順序で消費されます。同じパーティション内で、コンシューマーは後続のメッセージを読み取る前に、以前に公開されたメッセージを消費する必要があります。メッセージを送信するときに、コンシューマーのオフセットが送信されたメッセージの N メッセージ後であると仮定すると、キャッチアップ時間はコンシューマーが N 個のメッセージを消費するのにかかる合計時間になります。 リアルタイム処理アプリケーションを構築する場合、キャッチアップ時間を 0 に設定するのが最適です。つまり、メッセージが送信されると、コンシューマーはすぐにメッセージを読み取ることができます。消費者が常に遅れをとる場合、エンドツーエンドのレイテンシは無限大になる可能性があります。したがって、キャッチアップ時間は通常、コンシューマーがプロデューサーのスループットに追いつくことができるかどうかによって決まります。
トピック パーティションにサブスクライブしているコンシューマーは、リーダー コピーからさらにデータを取得するためにポーリングを続けます。フェッチ時間は、リーダー コピーが配置されているブローカー ノードからメッセージ レコードを取得するのにかかる時間です。フェッチ要求への応答を形成し、応答でレコードを KafkaConsumer.poll() に返すために十分なデータが揃うまで待機する必要がある場合があります。デフォルト設定では、コンシューマーのフェッチ待ち時間が最適化されています (fetch.min.bytes=1)。つまり、1 バイトしか利用できない場合でも、または fetch.max.wait.ms の短いタイムアウト後に、フェッチ要求がデータで応答します。
次の図は、Kafka クライアントによって観測されるレイテンシ (一般にプロデューサー レイテンシとコンシューマー レイテンシと呼ばれる) とエンドツーエンド レイテンシの関係を示しています。 プロデューサーのレイテンシは、KafkaProducer.send() 呼び出しから生成されたメッセージが確認されるまでの時間です。メッセージの確認は、メッセージの耐久性を制御する acks の構成によって異なります。
したがって、プロデューサーのレイテンシには、生成時間、公開時間 (acks >= 1 の場合)、コミット時間 (acks=all の場合)、およびプロデューサーの応答がブローカーからプロデューサーに返されるまでにかかる時間が含まれます。 上の図は、acks パラメータを変更するとプロデューサーの遅延が削減される理由を明確に示しています (実際には、プロデューサーの遅延からいくつかの遅延概念を削除して、公開とコミットを削減します)。ただし、プロデューサーの acks パラメータをどのように構成しても、公開時間とコミット時間は常にエンドツーエンドのレイテンシの一部になります。 コンシューマーのレイテンシとは、コンシューマーがブローカー ノードへのフェッチ要求を開始し、ブローカー ノードがコンシューマーに応答を返すまでにかかる時間を指します。計算方法は、KafkaConsumer.poll() によって返される時間です。コンシューマーのレイテンシには、主に上図のフェッチ時間が含まれます。 エンドツーエンドのレイテンシの制御 メッセージのライフ サイクルについて考えると、エンドツーエンドのレイテンシを制御するということは、実際にはメッセージがシステム内を循環するのにかかる合計時間を制御することになります。多くの Kafka クライアントおよびブローカー パラメータのデフォルト値では、すでにレイテンシが最適化されています。たとえば、人工的な待機時間を削減してバッチ処理機能を向上させます (linger.ms、fetch.min.bytes、replica.fetch.min.bytes パラメータを適切に調整する)。その他の遅延は、ブローカー側のキュー待機時間から発生する可能性があります。この遅延を制御するには、ブローカーの負荷 (CPU またはスループット) を制御する必要があります。通常、ブローカー ノードの基本的な監視インジケーターに常に注意を払う必要があります。 システム全体を見ると、全体的なエンドツーエンドのレイテンシには、システムのすべての部分 (プロデューサー、ブローカー、コンシューマー) がアプリケーション ロジックに必要なスループットを確実に維持できることも必要です。 たとえば、アプリケーション ロジックが 100 MB/秒でデータを送信しているが、何らかの理由で Kafka コンシューマーのスループットが数秒間 10 MB/秒に低下した場合、それ以前に生成されたメッセージのほとんどは、コンシューマーが追いつくまでシステム内でより長く待機する必要があります。この時点で、スループットを向上させるために Kafka クライアントを拡張する効率的な方法、つまりブローカー リソースを効率的に利用してキューの待機時間と時折発生するネットワーク輻輳を削減する方法が必要になります。 理想的には、レイテンシを制限するということは、すべてのレイテンシが目標値を下回ることを保証することを意味します。しかし、実際の運用環境では、予期しない障害やピーク負荷により、このような厳格な保証は不可能です。ただし、すべてのメッセージ レイテンシを目標レイテンシの 95 ~ 99% 未満に保ちながら、95 パーセンタイル レイテンシ ターゲットを達成するようにアプリケーションを設計し、システムを調整することができます。高パーセンタイル レイテンシは、レイテンシ スペクトルの末端に位置するため、テール レイテンシとも呼ばれます。 ターゲットレイテンシに使用するパーセンタイルが大きいほど、アプリケーションの最悪のパフォーマンスを軽減または許容するためにより多くの労力が必要になります。たとえば、時折発生する大きなリクエストによってすべてのリクエストがブロックされ、全体的なレイテンシが増加する可能性があります。これはヘッドオブラインブロッキングと呼ばれます。同時に、多数の低レートクライアントが Kafka に同時にプロダクションまたは消費リクエストを送信したり、すべてのクラスターメタデータを更新したりする可能性があり、これによってもリクエストキューが通常よりも長くなり、通常よりも深刻なテール遅延が発生します。この動作はマイクロバースト(マイクロバースト、おそらく石を伝って水が滴るという意味)と呼ばれます。 さまざまなクライアント構成でのレイテンシテスト 以下のコンテンツでは、実験結果を使用して、Kafka クライアント構成とスループット スケーリング手法がパフォーマンスに与える影響を説明します。私たちは、Kafka に組み込まれている Trogdor テスト フレームワークと、プロデューサーおよびコンシューマー ベンチマークである ProduceBench と ConsumeBench を使用して、プロデューサーとコンシューマーの実験テストを実施します。 すべてのテストは、レプリケーション係数が 3 の 9 つのブローカーの Kafka クラスターで実行されました。これにより、最大 2 つのノードで同時に障害が発生してもメッセージが失われないことが保証されます。 Kafka クラスターは、2 TB の EBS (Elastic Block Storage) を使用して、AWS r5.xlarge インスタンス上で実行されます。 Kafka のブローカー ノードは、より強力なフォールト トレランスを実現するために、同じリージョン内の 3 つのアベイラビリティ ゾーン (AZ) に分散されています。各トピック パーティションのレプリカは異なる AZ に配置され、Kafka クライアント構成では SASL 認証と SSL 暗号化が使用され、ブローカーは PLAINTEXT を使用して通信します。 トピック: 分散クラスター内のノードが異なる可用性ゾーンにある場合、レイテンシが増加する可能性があることに注意してください。もちろん、これはレイテンシとフォールト トレランスの観点から検討する必要があり、クラウド ベンダーのアベイラビリティ ゾーン間のレイテンシも考慮する必要があります。 私たちの実験では、次のデフォルト以外のクライアント構成とその他の仕様を使用しました。 このテスト シナリオでは追加の遅延が発生します。複数の可用性ゾーンでは、可用性ゾーン間のレプリカによりコミット時間が長くなる可能性があります。クライアントでもブローカーでも、SSL 暗号化にはオーバーヘッドがあります。同時に、SSL はデータ転送にゼロ コピー機能を使用できないため、コンシューマーがメッセージを取得するときに追加のオーバーヘッドが発生します。 これらの要因はレイテンシに影響しますが、企業内ではこのようなアーキテクチャ上の考慮が必要になる場合もあるため、この展開構造はテストに使用されます。 持続設定がレイテンシに与える影響 レイテンシ目標を他の要件と重ね合わせる場合は、まず永続性要件を考慮すると便利です。データの重要性のため、通常はある程度の永続性が必要になります。 耐久性を最適化すると、遅延レプリケーションのオーバーヘッド (コミット時間) が追加され、ブローカーへのレプリケーション負荷が増加してキューの遅延が増加するため、エンドツーエンドのレイテンシが増加します。
レプリケーション係数は、Kafka の永続性保証の中核です。 Kafka クラスターに保存されるトピックのコピーの数を定義します。レプリケーション係数 = N は、データ損失なしで最大 N-1 のブローカー障害を許容できることを意味します。 N=1 ではエンドツーエンドの遅延を最小限に抑えることができますが、持続性の保証は最も低くなります。 レプリカの数を増やすと、バックアップのオーバーヘッドが増加し、ブローカーに追加の負荷がかかります。クライアント帯域幅がブローカー側で均等に分散されている場合、各ブローカーは N * w 書き込み帯域幅と r + (N - 1) * w 読み取り帯域幅を使用します。ここで、w はブローカー上のクライアント書き込み帯域幅の使用量、r は読み取り帯域幅の使用量です。 したがって、エンドツーエンドのレイテンシに対する N の影響を軽減する最善の方法は、各ブローカーの負荷が均等になるようにすることです。これにより、コミット時間は最も遅いフォロワー レプリカによって決定されるため、コミット時間が短縮されます。 Kafka ブローカーがディスク帯域幅または CPU を過剰に使用すると、フォロワーがリーダーより遅れ始め、コミット時間が長くなります。 (実際、最小 ISR がレプリカの数にデフォルト設定されている場合、フォロワーとリーダーが同期していないときにリーダー ノードがダウンすると、トピック自体が使用できなくなることにも注意してください。) 通常のクライアント トラフィックへの干渉を減らすために、レプリカ同期メッセージ トラフィックには別のリスナーを使用することをお勧めします。また、フォロワー ブローカーの I/O 並列処理を増やし、レプリカ フェッチ スレッドの数 number.replica.fetchers を増やして、バックアップ パフォーマンスを向上させることもできます。
複数のレプリカを構成する場合でも、プロデューサーは Acks パラメータを通じて信頼性レベルを構成する必要があります。 acks=all を設定すると、最も強力な信頼性の保証が提供されますが、前述したように、ブローカーが PRODUCE 要求に応答するのにかかる時間も長くなります。 ブローカー側からの応答が遅いと、通常、単一のプロデューサーのスループットが低下し、その結果、プロデューサーの待機時間が長くなります。これは、プロデューサー側が応答されないリクエストの数 (max.inflight.requests.per.connection) を制限するためです。 たとえば、acks=1 の環境では、9 つのプロデューサーを開始し (また、9 つのコンシューマーを実行)、スループットは 195 MB/秒に達しました。 Acks が all に切り替えられると、スループットは 161MB/s に低下します。より高い ack レベルを設定するには、通常、以前のスループット レベルを維持し、プロデューサー内の待機時間を最小限に抑えるために、プロデューサー プログラムを拡張する必要があります。
min.insync.replicas は、PRODUCE 要求が成功するためにメッセージが書き込まれる必要があるブローカー側の ISR レプリカの最小数を定義するため、重要な永続性パラメータです。このパラメータは可用性に影響しますが、エンドツーエンドのレイテンシには影響しません。したがって、小さい値を選択してもコミット時間は短縮されず、レイテンシも短縮されません。 レイテンシ目標を満たしながらスループットを拡張する
Kafka クライアントのスループットを最適化することは、バッチ処理を最適化することを意味します。 Kafka プロデューサーは、複数のメッセージを 1 つのバッチに収集する一種のバッチ処理を内部的に実行します。 各バッチは均一に圧縮され、ログ全体に書き込まれたり、ログから読み取られたりします。つまり、メッセージのバックアップもバッチで実行されます。 バッチ処理により、コストがクライアントとブローカー間で分散されるため、各メッセージのコストが削減されます。一般的に、バッチが大きいほど、このオーバーヘッド削減の効果は大きくなり、ネットワークとディスクの I/O も削減されます。 別の種類のバッチ処理では、複数のバッチを単一のネットワーク要求/応答に収集して、ネットワーク データ転送の量を削減します。これにより、クライアントとブローカーの両方でのリクエスト処理のオーバーヘッドが削減されます。このタイプのバッチ処理では、バッチが大きいほどネットワーク転送 I/O 量が少なくなり、CPU とディスクの使用率が低くなり、最終的にスループットを最適化できるため、スループットが向上し、待ち時間が短縮されます。さらに、バッチ サイズを大きくすると、各メッセージのコストが削減され、システムが同じ数のメッセージを処理するのにかかる合計時間が短縮されるため、エンドツーエンドのレイテンシも削減されます。 ここでのレイテンシとスループットのトレードオフとは、待機時間を人為的に増やすことによってメッセージをパッケージ化する能力を向上させることを指します。しかし、ある時点を超えると、人工的な待機時間の増加により、バンドル メカニズムから得られるレイテンシの利点が相殺されるか、カバーされる可能性があります。したがって、レイテンシ目標によって実装できるパケット化のレベルが制限され、達成可能なスループットが低下し、レイテンシが増加する可能性があります。達成可能なスループットまたはエンドツーエンドのレイテンシを削減する場合は、クラスターを拡張することで、より多くのスループットまたは処理能力を獲得(「購入」)できます。
プロデューサーの場合、バッチ処理は batch.size (16KB) と linger.ms (0) の 2 つのパラメータによって制御されます。前者はバッチ サイズを制御し、後者は遅延を制限します。アプリケーションが Kafka クラスターに頻繁にデータを送信する場合、linger.ms=0 が設定されている場合でも、バッチ全体ができるだけ早く埋められます。アプリケーション生成データの頻度が低い場合は、linger.ms を増やすことでバッチ サイズを増やすことができます。 コンシューマーの場合、fetch.min.bytes(1) を調整して、各コンシューマーが各フェッチ応答で受信するデータの量を制限できます。これは、ブローカーがフェッチ応答で返すデータの最小量を指定します。また、fetch.max.wait.ms(500) を調整して、データを待機するためのタイムアウトを設定できます。フェッチ応答のデータが多いほど、フェッチ要求の数は少なくなります。 バッチ処理では取得できるデータの最小量が定義されるため、プロデューサー側でのバッチ処理も間接的にプロデュースおよびフェッチ要求の数に影響します。 デフォルトでは、Kafka プロデューサーとコンシューマーは人工的な待機時間なしで設定されており、その目的はレイテンシを削減することであることに注意してください。ただし、レイテンシを最小限に抑えることが目標であっても、linger.ms 値を 0 以外の値 (5 ~ 10 ミリ秒など) に設定することをお勧めします。もちろん、これを行うには前提条件があります。
次の実験は両方のシナリオを示しています。 90 個のプロデューサーを開始し、108 個のパーティションを持つトピックにメッセージを送信しました。実稼働側の全体的なスループットのピークは 90MB/秒です。それぞれ異なるプロデューサー構成に対応するテストを 3 回実行しました。 与えられた合計スループットに対して比較的多数のプロデューサーがあるため、linger.ms = 0 の場合、プロデューサー側でバッチ処理は行われません。 linger.ms を 0 から 5 に調整すると、バッチ処理能力が向上します。Kafka に対して開始されるプロデューサー リクエストは 2800 から 1100 に減少します。これにより、プロデューサーのレイテンシが 50% と 99% 減少します。 batch.size を大きくしても、プロデューサーの待機時間には直接影響しません。これは、プロデューサーがバッチを埋めるのにかかる時間が linger.ms 制限を超えることはないためです。私たちの実験では、プロデューサーあたりのスループットが非常に低いため、batch.size を 16 KB から 128 KB に増やしてもバッチ サイズの増加には影響がありません。予想どおり、プロデューサーのレイテンシは 2 つの構成間で変化しませんでした。 要約すると、レイテンシを最小限に抑えることが目標である場合は、デフォルトのクライアント バッチ構成を維持し、linger.ms を可能な限り増やすことをお勧めします。テールレイテンシを気にする場合は、パッケージング レベルを調整して、リクエストの送信速度と大きなリクエストの影響の可能性を減らすのが最適です。 人工的な遅延を追加しないことでバッチ処理の効率を向上 バッチ処理がうまく機能しないもう 1 つの理由は、プロデューサーが多数のパーティションにメッセージを送信することです。メッセージが同じパーティションに送信されない場合、それらを 1 つのバッチにまとめることはできません。したがって、通常は、各プロデューサーが限られた数のパーティションにのみメッセージを送信するように設計するのが最適です。 または、Kafka 2.4 プロデューサーへのアップグレードを検討してください。このバージョンでは、まったく新しい Sticky パーティショナーが導入されています。このパーティショナーは、人工的な待機を導入することなく、キーなしトピックのパッケージ化効果を向上させることができます。
全体的な生産および消費スループットが変わらない場合でも、クライアントの数が増えるとブローカーの負荷が大きくなります。これは、クライアントの数が多いと、Kafka に送信される METADATA リクエストの数が増え、より多くの接続を維持する必要があり、ブローカーのオーバーヘッドが大きくなるためです。 50% または平均レイテンシの影響と比較すると、クライアント数の増加はテールレイテンシに大きな影響を与えます。 各プロデューサーは最大で max.inflight.requests.per.connection 個の PRODUCE リクエストを単一のブローカーに送信し、各コンシューマーは最大で FETCH リクエストを 1 つのブローカーに一度に送信します。クライアントの数が増えると、ブローカーに同時に送信される PRODUCE および FETCH リクエストの数も増え、リクエストが瞬間的に影響を受ける可能性が高くなり、テール レイテンシが増加します。 コンシューマーの数は通常、トピック パーティションの数と、コンシューマーに大きな遅延が生じないようにするという目標によって決まります。しかし、処理能力を拡大するために、多数のプロデューサーを導入するのは簡単です。 スループットを考慮してプロデューサー インスタンスの数を増やすと、逆の効果が生じる可能性があります。プロデューサーによってパッケージ化されるメッセージが少なくなり、各プロデューサーが処理するメッセージが少なくなるため、送信速度が遅くなるためです。同時に、プロデューサーは、同じ数のメッセージをバッチに蓄積するのに、より長い時間待機する必要があります。 私たちの実験では、プロデューサーの数を 90 から 900 に増やしましたが、スループットは変化せず、90 MB/秒でした。 プロデューサー構成として batch.size=16KB、linger.ms=5、acks=all を使用し、実験結果は次のとおりです。 結果によると、プロデューサーの数を増やすと (90 -> 900)、中央値のレイテンシは 60% 増加し、99 パーセンタイルのレイテンシはほぼ 3 倍に増加しました。 レイテンシの増加は、プロデューサー側のパッケージング効果の劣化によるものです。 テール レイテンシの増加は、リクエストの瞬間的な影響が大きいためであり、ブローカー側のレイテンシが増加し、プロデューサー側は応答を受信するまでより長い時間待機する必要があります。 900 人のプロデューサーによるテストでは、ブローカーは PRODUCE リクエストに完全に圧倒されました。リクエストの処理に費やされる時間は、ブローカーの CPU 使用率のほぼ 100% を占めます。さらに、SSL を使用するため、リクエスト レベルのオーバーヘッドがさらに発生します。 プロデューサーを追加してスループットを向上させる場合は、単一のプロデューサーのスループットを向上させること、つまりバッチ処理の効果を向上させることを検討できます。いずれにしても、多くのプロデューサーインスタンスが作成される可能性があります。たとえば、大企業では数万台に及ぶデバイスに関する統計メトリクスを収集します。この時点で、ブローカーを使用して複数のクライアントからのリクエストを収集し、それらをより効率的な PRODUCE リクエストに変換して Kafka に送信することを検討できます。ブローカーの数を増やして、単一のブローカーへのリクエスト負荷を軽減することもできます。 消費者数の増加に関する注意事項 コンシューマーをスケーリングする場合、同じコンシューマー グループ内のコンシューマーがオフセット情報とハートビートをブローカー ノード (コントローラー ノード) に送信することに注意してください。オフセット コミットが間隔 (auto.commit.interval.ms) で実行される場合、コンシューマー グループ内のコンシューマーが増えると、オフセット コミット レートが増加します。オフセット コミットは基本的に内部の __consumer_offsets へのリクエストを生成するため、特に auto.commit.interval.ms 値が小さい場合は、コンシューマーの数が増えるとブローカーへのリクエスト負荷が増加します。 圧縮構成の影響 デフォルトでは、Kafka プロデューサーは圧縮を行いません。 compression.type パラメータは、圧縮が必要かどうかを決定できます。 圧縮を行うと、メッセージを圧縮するためにプロデューサー側で追加のオーバーヘッドが発生し、検証を行う際にブローカー側で解凍を行うと追加のオーバーヘッドが発生し、コンシューマー側で解凍を行うとオーバーヘッドも発生します。 注: 通常、データが正常に消費されない原因となる圧縮の競合を回避するために、ブローカー側の圧縮パラメータをプロデューサーに設定する必要があります。この方法では、ブローカーは圧縮されたログを直接書き込むだけで済みます。 圧縮により CPU オーバーヘッドは増加しますが、データの処理に必要な帯域幅が大幅に削減され、ブローカーの負荷が軽減されるため、エンドツーエンドのレイテンシが削減される可能性があります。圧縮はバッチレベルで行われるため、パッケージングが優れているほど、圧縮も優れています。 パーティションが増えるとレイテンシが増加する可能性がある トピックのパーティションは、Kafka における並列処理の単位です。異なるパーティションに送信されたメッセージは、プロデューサーによって並列に送信され、異なるブローカーによって並列に書き込まれ、異なるコンシューマーによって並列に読み取られる可能性があります。したがって、パーティションの数が多いほど一般的にスループットは高くなりますが、スループットの観点からのみ見ると、ブローカーごとに 10 個のパーティションを持つ Kafka クラスターで最大スループットを達成できます。アプリケーション ロジックをサポートするには、さらにトピック パーティションが必要になる場合があります。 ただし、パーティションが多すぎると、エンドツーエンドのレイテンシが増加する可能性があります。トピックあたりのパーティション数が多いほど、プロデューサーで実行されるバッチ処理が少なくなります。各ブローカーのトピック パーティションの数が多いほど、フォロー レプリカごとに要求をフェッチする際のオーバーヘッドが大きくなります。各フェッチ要求は対象のパーティションを列挙する必要があり、各リーダー レプリカは状態をチェックし、要求された各パーティションからデータをフェッチする必要があるため、通常はディスク I/O が少なくなります。したがって、パーティションが増えるとコミット時間が長くなり、CPU 使用率が高くなり、最終的にはキューの遅延が長くなる可能性があります。 コミット時間の増加と CPU 負荷の上昇により、少数のトピック パーティションからのみ生成および消費するクライアントであっても、同じ Kafka クラスターを共有するすべてのクライアントのエンドツーエンドのレイテンシが増加する可能性があります。 このテストでは 2 つのトピックを使用します。トピックには 5MB/秒のデータを生成する 9 つのプロデューサーがあり、9 つのコンシューマーに対応するコンシューマー グループがあります。この実験は数日間続き、各ステップを 1 時間実行しながら、このトピックのパーティション数を 108 から 7200 (ブローカーあたり 8000) に徐々に増やしました。 2 番目のトピックには、実験の実行全体を通じて 9 つのパーティションと 9 つのプロデューサーがあります。各プロデューサーは、1 つのパーティションと対応するコンシューマー グループ (パーティションごとに 1 つ) にメッセージを生成します。トピックは 1 秒あたり 512 バイトのデータを生成します。 次の図は、9パーティションのトピックにアクセスするクライアントの99パーセンタイルのエンドツーエンドのレイテンシに対するパーティションの数の影響を示しています。各ブローカーのパーティションの数が増えると、クライアントのエンドツーエンドのレイテンシがほぼ直線的に増加します。パーティションの数を増やすと、ブローカーのCPU負荷が増加し、固定数のパーティションとのみ対話するクライアントであっても、すべてのクライアントの複製が遅くなり、エンドツーエンドのレイテンシが増加します。 遅延を減らすために、パーティションの総数を減らすか、クラスターを拡張することにより、各ブローカーのパーティションの数を制限することが最善です。フェッチャースレッドの数を増やすことで、コミット時間を改善することもできます。 レイテンシに対するブローカーノードの負荷の影響 ブローカーの負荷がキューイングの遅延を増加させる方法についてすでに議論しています。これにより、エンドツーエンドのレイテンシが増加します。リクエストレートの上昇がキューイングの遅延を悪化させる理由を簡単に確認できます。 ブローカーノードの高いリソース使用率(ディスクまたはCPU)は、キューレイテンシが高くなり、リソースの使用率とともにレイテンシが指数関数的に増加する可能性があります。これは、キューイング理論で説明できる既知のプロパティです。キングマンの公式は、リソースの待ち時間がリソースの忙しさ/リソースのアイドル性に比例していることを証明しています(時間リソースの割合はビジーです)/(時間リソースの%はアイドル状態です)。 リソースの利用とともにレイテンシは指数関数的に増加するため、ブローカーのリソースが100%の利用に近づいている場合、高レイテンシーが表示される場合があります。各ブローカーのリソース使用量を削減し(ブローカーごとの接続、リクエスト、パーティションの数を減らすなど)、クラスターを拡張して各ブローカーノードのリソース使用量を減らすことにより、この場合は遅延を大幅に削減できます。ブローカー全体に負荷を均等に分配することは非常に便利であることがよくあり、パーティションのレプリカを均等にまたは負荷に基づいて配布すると、尾のレイテンシーも減少します。 したがって、通常、KAFKAクラスターの責任者チームは、ブローカーノードの高リソース利用(ディスクとCPU)を自動的に検出し、クラスター上のパーティションをバランスさせる必要があります。クラウドベンダーが提供するKafkaサービスを使用する場合、クラウドサービスが関連する作業を行うため、そのようなインシデントを回避できます。 要約する 接続の数、パーティションの数、要求レートの数を制限しながら、各ブローカーの使用を制限することが可能であることを実証しました。 境界のテールレイテンシは、クライアント(接続と要求)からのバーストまたはアプリケーション動作の違いを減らすために特別な注意が必要です。 均等にロードされたブローカーノードは、最も遅いブローカーの影響を受けるため、テールレイテンシを最小限に抑えるためにも重要です。 |
<<: クラウド セキュリティにおけるエンドポイント セキュリティの役割
>>: 企業でハイブリッド クラウドを導入する 3 つの方法のうち、どれが適切でしょうか?
お気に入りで「価格を比較」をクリックすると、さまざまなショッピングモールの550Dの価格が出てきまし...
新しいウェブサイトを検索エンジンに素早くインデックスさせるにはどうすればよいでしょうか。これは、多く...
低価格 VPS 業界の屠殺業者である virmach は、すでに低価格戦略を展開している中で、今月、...
インターネットは巨大な金鉱です。適切なターゲットを見つければ、確実に利益を上げることができます。しか...
欧州からの新しいデータ規制は、クラウド コンピューティングを使用する企業にいくつかの問題を引き起こす...
地方病院のウェブサイトの運営モードは、地理、文化などの要因の影響を受け、ネットワークの面でも比較的単...
1 初期段階でドメイン名を選択するにはどうすればいいですか?ドメイン名は覚えやすいものにしてください...
ブログプロモーションを行う医療SEO担当者は、Sina Blogと39 Blogをよくご存知だと思い...
序文最近、Kubernetes を学習しながら、ポッドデータの永続化を実現したいと考えています。調査...
さまざまなモバイル デバイスの急速な発展に伴い、多くの問題や課題にも直面しています。たとえば、ソフト...
SharkTech (Shark Host)、最新のプロモーションメール: ロサンゼルス データ セ...
プログラミング言語のランキングの推移(写真提供:テンセントテクノロジー)テンセントテクノロジーニュー...
versaweb.com は、ハイブリッド スマート サーバー製品シリーズの開発を開始しました。簡単...
私は地域の人材ネットワークで働くという栄誉に恵まれ、人材ネットワークについてある程度の理解を持ってい...
今朝、コンピューターの電源を入れると、seclists で衝撃的なスレッドを見つけました: http...