[51CTO.com クイック翻訳] Apache Kafka は、人気の分散データ ストリーム プラットフォームです。これは、New Relic (データ インテリジェンス プラットフォーム)、Uber、Square (モバイル決済会社) などの大企業で、スケーラブルで高スループット、信頼性の高いリアルタイム データ ストリーム システムの構築に広く使用されています。たとえば、New Relic の運用環境では、Kafka クラスターは 1 秒あたり 1,500 万件を超えるメッセージを処理でき、合計データ レートは 1 Tbps に近づいています。 Kafka はデータ ストリームの処理を大幅に簡素化するため、多くのアプリケーション開発者やデータ管理の専門家からも支持を得ています。ただし、大規模なシステムでの Kafka の適用はより複雑になります。消費者がデータフローに追いつけない場合、メッセージは表示される前に消えてしまうことがよくあります。同時に、自動データ保持、高トラフィックのパブリッシュ/サブスクライブ (pub/sub) モードなどの制限により、システムのパフォーマンスに影響が出る可能性があります。データ ストリームを保存するシステムが必要に応じて拡張できなかったり、安定性が信頼できない場合、睡眠や食事に支障が出ることが頻繁にあると言っても過言ではありません。 上記の複雑さを軽減するために、Kafka クラスターが高スループットを処理するための New Relic の 20 のベスト プラクティスを共有したいと思います。次の 4 つの側面について詳しく説明します。 - パーティション
- 消費者
- プロデューサー
- ブローカー
Kafkaの概念とアーキテクチャを素早く理解するKafka は効率的な分散メッセージング システムです。パフォーマンスの面では、データの冗長性と復元力が組み込まれており、高いスループットとスケーラビリティも備えています。機能面では、自動データストレージ制限をサポートし、アプリケーションのデータ変換を「ストリーム」方式で提供し、「キーと値」のモデリング関係に従ってデータストリームを「圧縮」することができます。 さまざまな *** プラクティスを理解するには、まず次のキーワードを理解しておく必要があります。 - メッセージ: Kafka 内のレコードまたはデータの単位。各メッセージにはキーと対応する値があり、オプションのメッセージ ヘッダーが含まれる場合もあります。
- プロデューサー: プロデューサーは Kafka トピックにメッセージを公開します。プロデューサーは、ランダムなポーリング方法やメッセージ キーに基づくパーティション分割アルゴリズムなど、トピック パーティションに公開する方法を決定します。
- ブローカー: Kafka は分散システムまたはクラスターとして実行されます。クラスター内の各ノードはブローカーと呼ばれます。
- トピック: トピックは、公開されるデータ レコードまたはメッセージのカテゴリです。コンシューマーはトピックをサブスクライブして、トピックに書き込まれたデータを読み取ります。
- トピック パーティション: 異なるトピックは異なるパーティションに分割され、各メッセージにはオフセットが割り当てられます。通常、各パーティションは少なくとも 1 回または 2 回複製されます。各パーティションにはリーダーがあり、各フォロワーには 1 つ以上のレプリカ (つまり、データのコピー) が保存されます。この方法により、ブローカーの障害を防ぐことができます。クラスター内のすべてのブローカーはリーダーおよびフォロワーとして機能できますが、ブローカーはトピック パーティションのレプリカを最大 1 つ持つことができます。リーダーは、すべての読み取りおよび書き込み操作を実行するために使用できます。
- オフセット: 単一パーティション内の各メッセージにはオフセットが割り当てられます。オフセットは、パーティション内のメッセージの一意の識別子として使用できる単調に増加する整数です。
- コンシューマー: コンシューマーはトピック パーティションをサブスクライブして、Kafka からさまざまなトピック メッセージを読み取ります。次に、消費アプリケーション プロセスはメッセージを受信して、指定された作業を完了します。
- 消費者グループ: 消費者は論理的に消費者グループに分けられます。トピック パーティションは、グループ内のすべてのコンシューマーに均等に分散されます。したがって、同じコンシューマー グループ内では、すべてのコンシューマーが負荷分散された方法で動作します。つまり、同じグループ内のすべての消費者がすべてのメッセージを見ることができます。コンシューマーが「オフライン」状態の場合、パーティションは同じグループ内の別のコンシューマーに割り当てられます。これを「リバランス」と呼びます。もちろん、グループ内のコンシューマーがパーティションの数よりも多い場合、一部のコンシューマーはアイドル状態になります。逆に、グループ内のコンシューマーの数がパーティションの数より少ない場合、一部のコンシューマーは複数のパーティションからメッセージを受信する可能性があります。
- 遅延: コンシューマーの速度がメッセージが生成される速度に追いつけない場合、コンシューマーはパーティションからメッセージを読み取ることができないため遅延が発生します。遅延は、パーティション ヘッダーの後ろのオフセット数として表されます。遅延状態から回復する(「追いつく」)のにかかる時間は、コンシューマーが 1 秒あたりに処理できるメッセージの速度によって異なります。式は次のとおりです。
時間 = メッセージ / (1 秒あたりの消費率 - 1 秒あたりの生成率) パーティションのベストプラクティス- パーティションのデータ レートを理解して、適切なデータ ストレージ スペースが確保されていることを確認します。ここでの「パーティション データ レート」とは、データが生成されるレートを指します。つまり、平均メッセージ サイズと 1 秒あたりのメッセージを掛けて計算されます。データ レートによって、特定の期間内に保証できるデータ ストレージ容量 (バイト単位) が決まります。データ レートがわからないと、特定の期間にデータを保存するために必要なスペースの量を正確に計算することはできません。同時に、データ レートは、遅延を発生させずに単一の消費者がサポートする必要がある最大パフォーマンス値も識別できます。
- 他のアーキテクチャ要件がない限り、トピックを書き込むときにランダム パーティショニングを使用します。大規模な操作を行う場合、パーティション間でデータ レートが異なると管理が難しくなる可能性があります。その理由は次の3つの側面から来ています。
- まず、「ホット」(スループットが高い)パーティションのコンシューマーは、必然的に同じグループ内の他のコンシューマーよりも多くのメッセージを処理するため、処理とネットワークのボトルネックが発生する可能性があります。
- 次に、データ レートが最も高いパーティションに最大予約領域を構成すると、トピック内の他のパーティションのディスク使用量がそれに応じて増加します。
- 3 番目に、パーティションのリーダー関係に基づいて実装されたバランシング ソリューションは、リーダー関係をすべてのブローカーに単純に配布するよりも複雑です。同じトピックでは、「ホット」パーティションは他のパーティションの 10 倍の重量を「運ぶ」ことになります。
トピック パーティションの使用方法の詳細については、「Kafka トピック パーティション分割の効果的な戦略」を参照してください。 消費者のためのベストプラクティス- コンシューマーが Kafka 0.10 より古いバージョンを実行している場合は、今すぐアップグレードする必要があります。バージョン 0.8.x では、コンシューマーは Apache ZooKeeper を使用してコンシューマー グループを調整しますが、多くの既知のバグにより、長時間再バランス状態になったり、再バランス アルゴリズムの障害 (「再バランス ストーム」と呼びます) に直接つながったりする可能性があります。したがって、再バランス調整中は、同じグループ内の各コンシューマーに 1 つ以上のパーティションが割り当てられます。再バランス ストームの間、パーティションの所有権はコンシューマー間で引き続き渡されるため、どのコンシューマーもパーティションの所有権を実際に取得できなくなります。
- 高速なデータ流入を処理するために、コンシューマーのソケット バッファーを調整します。 Kafka バージョン 0.10.x では、パラメータ receive.buffer.bytes のデフォルト値は 64 kB です。 Kafka バージョン 0.8.x では、パラメータ socket.receive.buffer.bytes のデフォルト値は 100 kB です。両方のデフォルト値は、特にブローカーとコンシューマー間の帯域幅遅延積がローカル エリア ネットワーク (LAN) より大きい場合、高スループット環境には小さすぎます。レイテンシが 1 ミリ秒以上の高帯域幅ネットワーク (10 Gbps 以上など) の場合は、ソケット バッファ サイズを 8 MB または 16 MB に設定することを検討してください。メモリが不足している場合は、少なくとも 1 MB に設定することを検討してください。もちろん、これを -1 に設定することもできます。これにより、基盤となるオペレーティング システムが実際のネットワーク状況に基づいてバッファー サイズを調整できるようになります。ただし、「ホット」パーティションを起動する必要がある消費者にとっては、自動チューニングはそれほど高速ではない可能性があります。
- 必要に応じてバックプレッシャーを実装するために、高スループットのコンシューマーを設計します。一般的に、システムがその能力の範囲内でのみデータを処理するようにし、プロセスが中断またはハングしたり、消費グループがオーバーフローしたりする可能性があるデータによるシステムの過負荷を回避する必要があります。 Java 仮想マシン (JVM) で実行する場合、コンシューマーは固定サイズのバッファー (Disruptor パターンを参照: http://lmax-exchange.github.io/disruptor/files/Disruptor-1.0.pdf) を使用し、できればオフヒープ メモリを使用する必要があります。固定サイズのバッファにより、コンシューマが大量のデータをスタックにプッシュすることがなくなり、JVM がメッセージ処理という重要なジョブを実行する代わりに、ガベージ コレクションの実行にすべての時間を費やすことがなくなります。
- JVM 上でさまざまなコンシューマーを実行する場合、ガベージ コレクションがそれらに及ぼす影響に注意してください。たとえば、ガベージ コレクションの一時停止が長時間続くと、ZooKeeper セッションがドロップされたり、コンシューマー グループが再バランス状態になったりする可能性があります。ブローカーについても同様です。ガベージ コレクションが長時間停止すると、クラスターが切断されるリスクがあります。
プロデューサーのためのベストプラクティス- さまざまな確認を待機するようにプロデューサーを構成します。これにより、プロデューサーはメッセージが実際にブローカーのパーティションに送信されたかどうかを知ることができます。 Kafka 0.10.x では、設定は acks です。 0.8.x では、request.required.acks です。 Kafka はレプリケーションを通じてフォールト トレランスを提供するため、単一ノードの障害やパーティション リーダー関係の変更がシステムの可用性に影響を与えることはありません。プロデューサーを ack (または「fire and forward」) で構成しないと、メッセージが暗黙的に失われる可能性があります。
- 各プロデューサーの再試行を構成します。デフォルト値は 3 ですが、これはもちろん非常に低い値です。ただし、正しい設定はアプリケーションによって異なります。つまり、データ損失を一切許容しないアプリケーションの場合は、Integer.MAX_VALUE (有効かつ最大) に設定することを検討してください。これにより、ブローカーのリーダー パーティションが生成要求にすぐに応答できない状況に対処できるようになります。
- 高スループットのプロデューサーの場合は、バッファ サイズ、特に buffer.memory と batch.size (バイト単位) を調整します。 batch.size はパーティションごとに設定されるため、プロデューサーのパフォーマンスとメモリ使用量はトピック内のパーティションの数に関係する可能性があります。したがって、ここで設定する値は、プロデューサーのデータ レート (メッセージのサイズと数)、生成するパーティションの数、使用可能なメモリの量など、いくつかの要因によって異なります。バッファを大きくすることが必ずしも良いことではないことに注意してください。プロデューサーが何らかの理由で失敗した場合 (たとえば、リーダーの応答が確認応答よりも遅い場合)、ヒープ上にバッファリングされたより多くのデータをガベージ コレクションする必要があります。
- 生成されたメッセージの数、平均メッセージ サイズ、消費されたメッセージの数などのメトリックを追跡するようにアプリケーションをインストルメント化します。
*** ブローカーの実践- 各ブローカーで、トピックに必要なメモリと CPU リソースを削減します。ログ圧縮 (https://kafka.apache.org/documentation/#compaction を参照) を正常に実装するには、各ブローカーのスタック (メモリ) と CPU サイクルの両方が必要です。失敗したログ圧縮データが増え続けると、ブローカーのパーティションにリスクが生じます。ブローカーの log.cleaner.dedupe.buffer.size と log.cleaner.threads を調整できますが、両方の値が各ブローカーのスタック使用量に影響することに注意してください。ブローカーが OutOfMemoryError 例外をスローすると、ブローカーは閉じられ、データが失われる可能性があります。バッファ サイズとスレッド数は、クリアする必要があるトピック パーティションの数、およびそれらのパーティション内のメッセージのデータ レートとキー サイズによって異なります。 Kafka バージョン 0.10.2.1 以降では、ログ クリーナーのログ ファイルで ERROR エントリを監視することが、スレッドで発生する可能性のある問題を検出する最も信頼性の高い方法です。
- ネットワーク スループットによってブローカーを監視します。送信 (TX) および受信 (RX) トラフィック、ディスク I/O、ディスク容量、CPU 使用率を監視してください。容量計画は、クラスターの全体的なパフォーマンスを維持するための重要なステップです。
- クラスター内のブローカー全体にパーティションのリーダーシップを分散します。リーダーには通常、大量のネットワーク I/O リソースが必要です。たとえば、レプリケーション係数を 3 に設定して実行すると、リーダーは最初にパーティション データを取得し、次に 2 セットのコピーを他の 2 つのフォロワーに送信し、次にデータを必要とする複数のコンシューマーに送信する必要があります。したがって、この例では、単一のリーダーがフォロワーの少なくとも 4 倍のネットワーク I/O を使用します。さらに、リーダーはディスクを読み取る必要があるかもしれませんが、フォロワーは書き込みのみが必要です。
- 同期レプリカ (ISR) の縮小、レプリケーション不足のパーティション、および優先されないリーダーについてブローカーを監視することを怠らないでください。これらはすべて、クラスター内の潜在的な問題の兆候です。たとえば、単一のパーティションで ISR が頻繁に縮小される場合、パーティションのデータ レートが、コンシューマーや他のレプリカ スレッドにサービスを提供するリーダーの能力を超えていることを示します。
- 必要に応じて、Apache Log4j (https://github.com/apache/kafka/blob/trunk/config/log4j.properties) のさまざまなプロパティを変更します。 Kafka のブローカー ログは大量のディスク領域を消費しますが、これを完全にオフにすることはできません。事故後、イベントのシーケンスを再構築する必要がある場合があり、その場合、ブローカー ログが最善、あるいは唯一の方法になります。
- 自動トピック作成を無効にするか、未使用のトピックの消去戦略を確立します。たとえば、設定された x 日間の期間内に新しいメッセージが表示されない場合は、トピックを無効と見なし、クラスターから削除する必要があります。これにより、クラスターで作成される追加のメタデータの管理に費やす時間が節約されます。
- 高いスループットを維持しているブローカーの場合は、ディスク サブシステムからの読み取りを回避するために十分なメモリを提供します。可能な限り、オペレーティング システムのキャッシュからパーティション データを直接取得するようにしてください。ただし、これは、コンシューマーが追いつくことができることを確認する必要があり、遅れているコンシューマーはディスクから読み取ることを強制されることを意味します。
- 高スループットのサービス レベル目標 (SLO) を持つ大規模なクラスターの場合は、ブローカーのサブセットごとに異なるトピックを分離することを検討してください。分離する必要があるトピックをどのように決定するかは、完全に独自のビジネス ニーズによって異なります。たとえば、同じクラスターを使用する複数のオンライン トランザクション処理 (OLTP) システムがある場合、各システムのトピックをブローカーの異なるサブセットに分離すると、潜在的なインシデントの影響範囲を制限するのに役立ちます。
- 古いクライアントでは新しいトピック メッセージ形式を使用します。クライアントの代わりに、各ブローカーに追加の形式変換サービスをロードする必要があります。もちろん、*** はこのような状況を避けるように努めるべきです。
- ローカル ホストでブローカーをテストすれば、実際の運用環境でのパフォーマンスが反映されると考えるのは間違いです。レプリケーション係数が 1 のループバック インターフェイスを介したパーティションのテストは、ほとんどの運用環境とは大きく異なることに注意してください。ループバック インターフェイスのネットワーク遅延はほとんど無視できるほど小さく、レプリケーションが行われない場合、リーダーからの確認応答を受信するまでの時間は大幅に変化する可能性があります。
追加リソース上記の提案が Kafka をより効果的に使用するために役立つことを願っています。 Kafka の専門知識を高めたい場合は、クラスターの操作に関する詳細については、Kafka ドキュメントの「操作」セクションを参照してください。さらに、Confluent (https://www.confluent.io/) では、Kafka をより深く理解できるように、さまざまなオンライン ディスカッションを定期的に開催し、公開しています。 原題: Apache Kafka を大規模に活用するための 20 のベスト プラクティス、著者: Tony Mancill [51CTOによる翻訳。パートナーサイトに転載する場合は、元の翻訳者と出典を51CTO.comとして明記してください。 |