生産失敗 | Kafka のメッセージ送信が数十秒も遅延する原因は、実は...

生産失敗 | Kafka のメッセージ送信が数十秒も遅延する原因は、実は...

以前、私は「理由は分かっているが、理由は分からない。Kafka がバージョン 2.8 で Zookeeper を「放棄」した理由」という記事で、公式が Zookeeper を放棄することを決定した理由を説明しました。当時、Zookeeper は非常に安定しており、基本的に問題はないだろうと反論する読者もいたことを覚えています。 Double Eleven 期間中に遭遇した問題は、Zookeeper の「脆弱性」を証明しており、Zookeeper の脆弱性は Kafka クラスターに深刻な影響を及ぼすことになります。

1. 断層現象

ダブルイレブンショッピングフェスティバルの期間中、私が担当していた Kafka クラスターの応答時間が 10 ~ 30 秒に急上昇し、メッセージの書き込みに深刻な影響が出ました。

ログ分析により、大規模なパーティションリーダー選挙が行われていたことが判明しました。 __consumer_offsets トピックのパーティションでも、多数のパーティション リーダー選出が実行され、メッセージの送信がほぼ停止し、多数のコンシューマー グループの再バランス調整がトリガーされ、クラスター全体がほぼ麻痺しました。最終的に、根本的な原因が判明しました。ブローカー ノードと Zookeeper 間のセッションがタイムアウトし、多数のパーティションの再選出がトリガーされたのです。

この記事では、この失敗をきっかけに、Kafka における Zookeeper の役割と「犯人」を特定するプロセスを分析します。これがトラブルシューティングのヒントになれば幸いです。

2. ZookeeperはKafkaで重要な役割を果たす

障害分析に入る前に、まず Kafka アーキテクチャ設計における Zookeeper の役割について説明します。

コアコンセプト: Kafka の設計者は Zookeeper の使用に非常に慎重です。つまり、コントローラーの選択とブローカー ノードの障害のリアルタイム検出には Zookeeper に依存する必要がありますが、Zookeeper への依存を可能な限り減らすように努めています。

Zookeeper をベースにしたプログラム開発の場合、通常、Zookeeper 内のディレクトリ レイアウトを確認することで、Zookeeper によって実行される機能がわかります。 Zookeeper における Kafka のストレージ ディレクトリ構造を次の図に示します。

上記の各ノードは、Kafka のコア動作メカニズムに関連付けられています。手がかりを追って探索することができます。この記事では、/brokers ディレクトリのレイアウトと機能に焦点を当てる必要があります。ディレクトリの詳細は次のとおりです。

  • /controller Kafka コントローラーに関する情報。 Kafka コントローラーの選択は Zookeeper に依存します。
  • /brokers/ids/{id} は、永続ノード /brokers/ids の下に多数の一時ノードを作成します。各ノードはブローカー ノードを表します。ノードのコンテンツには、ポート、バージョン、リスニング アドレスなどのブローカーの基本情報が格納されます。
  • /brokers/topics/{トピック}/partitions/{パーティション}/state

Kafka バージョン 2.8 未満では、Kafka のトピック内のルーティング情報は最終的に Zookeeper に保存され、各ブローカー ノードは起動後にデータのコピーをメモリにキャッシュします。 /brokers ノードの各子ノードは特定のトピックを表します。トピックのメタデータには、主にパーティションの数と各パーティションのステータス情報が含まれます。各パーティションのステータス情報には主に次のものが含まれます。

  • controller_epoch 現在のクラスター コントローラーのエポックは、コントローラーの選択回数を示し、コントローラーの「バージョン番号」として理解できます。
  • リーダー 現在のパーティションのリーダーが配置されているブローカー ID。
  • Leader_epoch パーティションの Leader_epoch は、パーティション リーダーが選出される回数を示します。 0 から始まり、パーティション リーダーの選出が発生するたびに 1 ずつ増加します。 Kafka は、レプリカの進行状況を示すために依存関係ウォーターマークに依存する低バージョンによって発生する可能性のあるデータ損失とデータ不整合の問題を解決するために、リーダー エポック メカニズムを導入しています。これについては、後続の記事で詳しく分析します。
  • isr パーティションの isr セット。
  • version には、状態パーティション状態データ構造のバージョン番号が格納されます。このフィールドは無視できます。

Zookeeper にも同様の「設計パターン」があり、これは Zookeeper 内に一時的なノード + イベント監視メカニズムを作成して、データのリアルタイムの動的認識を実現するというものです。 /brokers/ids を例に挙げます。

  • Kafka ブローカー プロセスが起動すると、Zookeeper に一時ノード /brokers/ids/{id} が作成されます。ここで、id はブローカー番号です。
  • Kafkaブローカープロセスが停止すると、ブローカーとZookeeper間のセッションがタイムアウトすると、作成された一時ノードが自動的に削除され、ノード削除イベントが生成されます。
  • Kafka コントローラーは、/brokers/ids ディレクトリ内のノードの追加および削除イベントを自動的に監視します。ブローカーがオフラインまたはオンラインになると、コントローラーはそれをリアルタイムで認識し、必要なアクションを実行します。

上記の予備的な紹介の後でも、Kafka は依然として Zookeeper に大きく依存しており、特に Kafka コントローラーの選択とブローカー ノードの生存ステータスはすべて Zookeeper に依存しています。

Kafka コントローラーは、Kafka クラスター全体の「頭脳」です。それが変化すれば、その影響の範囲と程度は想像できる。次の障害分析により、より直感的なプレゼンテーションが可能になります。

注意: この記事は主に障害分析のプロセスについて説明しています。 Kafka コントローラーの選出方法と leader_epoch レプリカ同期メカニズムに関する以降の情報は、「Kafka の原則と実践」コラムで紹介されます。どうぞお楽しみに。

3. 問題分析

メッセージを送信する際の応答時間が長いことに気づいたとき、私の最初の反応は、スレッド スタックをチェックして、ロック ブロックがないかどうかを確認することでした。しかし、スレッド スタックを確認したところ、Kafka がリクエストを処理するために使用するスレッド プールのほとんどが取得タスクでブロックされており、「実行する作業がない」状態になっていることがわかりました。

これは、クライアントのメッセージ送信要求が Kafka のキューに到達しておらず、ネットワークの読み取りと書き込みの処理専用のスレッド プールもアイドル状態であることを意味します。何故ですか?

メッセージ送信側のレイテンシは非常に高いですが、サーバー スレッドは非常にアイドル状態です。これはちょっと変ですか?

サーバー ログの確認を続けると、多数のトピック (システム トピック __consumer_offsets トピックでもリーダー選出が行われていました) が見つかりました。ログは次のとおりです。

コア ログ: リーダー エポックから開始 多数のパーティションがリーダー選挙を実行しています。

Kafka では、リーダー パーティションのみが読み取りおよび書き込み要求を処理できます。フォロワー パーティションは、リーダー パーティションからデータをコピーし、リーダー ノードがクラッシュした後にリーダーの選出に参加するだけです。そのため、リーダー選出中にパーティションはクライアントの書き込み要求を処理できず、送信側には再試行メカニズムがあるため、メッセージ送信の遅延が非常に大きくなります。

では、どのような状況で大量のトピックが再選されるのでしょうか?

現在のクラスターのコントローラー ノードを見つけて state-change.log を確認すると、次のログが見つかります。

多数のパーティションのステータスが OnlinePartition から OfflinePartition に変更されました。

ヒント: ログに従って、ソース コードを確認し、これらのメソッドの呼び出しチェーンを見つけて、対象のログを見つけることができます。

引き続き、Controller ノードの下の controller.log を確認し、重要なログを見つけます。

コアログの解釈:

  • [コントローラー id=1] 8 のブローカー失敗コールバック (kafka.controller.KafkaController) コントローラーはオンライン クラスターからノード 8 を削除しました。コントローラーはなぜノード 8 を削除したのですか?

次に、手がかりに従って、以下に示すようにノード 8 のログを確認します。

コア ログの解釈: ブローカーと Zookeeper 間のセッションがタイムアウトし、一時ノードが削除されたことが判明しました。

セッションがタイムアウトする理由を調べる前に、まずセッション タイムアウトが Kafka クラスターに与える重大な影響について見てみましょう。

/brokers/ids の下のノードが削除された場合、Kafka コントローラーはそれを適時に取得し、対応する処理を実行できます。

ここで考慮すべき状況が 2 つあります。

3.1 通常のブローカーノードは削除される

処理エントリは、KafkaController の onBrokerFailure メソッドです。コードの詳細は次の図に示されています。

通常のブローカーが zk から削除されると、Kafka コントローラーはノードに割り当てられたすべてのパーティションのステータスを OnlinePartition から OfflinePartition に変更し、パーティションの再選択をトリガーします。

拡張知識ポイント: __consumer_offsets パーティションがリーダーを再選出すると、多数のコンシューマー グループが再バランスをトリガーします。その背後にあるメカニズムは次のとおりです。

コンシューマー グループは、ブローカー側でグループ コーディネーターを選出する必要があります。選出アルゴリズムは次のとおりです。コンシューマ グループ名のハッシュコードはトピック __consumer_offsets のキューの合計数を法として計算され、残りは __consumer_offsets パーティションにマップされます。パーティションのリーダーが配置されているブローカー ノードは、コンシューマー グループのグループ コーディネーターとして機能します。

パーティションのリーダーが変更されると、対応するコンシューマ グループは、コンシューマ グループの再バランス調整をトリガーするために、新しいグループ コーディネーターを再選択する必要があります。

3.2 コントローラノードが削除される

Zookeeper から削除されたブローカー ID が Kafka コントローラーである場合、影響はさらに大きくなります。メインエントリは次の図に示されています。

コントローラー ノードのセッションがタイムアウトすると、一時ノード/コントローラー ノードが削除され、Kafka コントローラーの選択がトリガーされます。最終的には、すべてのブローカー ノードが、ノード/コントローラーの削除、追加、またはノード データの変更に関する通知を受信します。 KafkaController の onControllerFailover メソッドが実行され、Zookeeper 関連のイベント リスナーが再登録され、パーティション ステート マシンとレプリカ ステート マシンが停止して再起動され、各パーティションで自動リーダー パーティション選出がトリガーされます。

それは、新しい皇帝、新しい大臣、そしてすべてがまた始まる、と説明することができます。

3.3 Zookeeperセッションタイムアウトの根本原因のトラブルシューティング

サーバー ログを確認すると、次のログが表示されます。

コア ログの解釈: クライアントのソケット接続が閉じられました... 接続がクライアントによってアクティブに閉じられたことを示します。

では、なぜクライアントはハートビートを積極的にオフにするのでしょうか?ハートビート処理のルーチンでは、クライアントは定期的にハートビート パケットをサーバーに送信する必要があります。サーバーが指定された時間内にハートビート パケットを受信または処理しない場合は、タイムアウトになります。

調べる唯一の方法はソースコードを読むことです。 Zookeeper クライアントのソース コードを調べたところ、次のような設計があることがわかりました。クライアントはまずすべてのリクエストをキューに入れ、次に送信スレッド (SendThread) を介してキューからリクエストを取得し、サーバーに送信します。キーコードは次のとおりです。

zk 更新操作が多数ある場合、ハートビート パケットが時間内に処理されない可能性があります。 Zookeeper セッション タイムアウトが発生する前に、クラスターは ISR の広い領域で拡大および縮小し、zk を頻繁に更新するため、クライアント ハートビート タイムアウトが発生します。この問題は、次のコードでも再現できます。

この一連の分析の結果、Zookeeper セッション タイムアウトによるメッセージ送信の大幅な遅延とコンシューマー グループの大規模な再調整の根本的な原因が判明しました。これで今回の共有は終了です。また次回お会いしましょう。

<<:  Kubernetes クラスタ ロギングの基本を簡単に説明します

>>:  Oracle のキーワードの解釈: データ、イノベーション、オープンな協力

推薦する

アリババクラウド、データ書き込み効率を100倍向上させるTSDBをリリース

IoT のシナリオでは、大量の時系列データ (時系列データと呼ばれる) が毎瞬生成されます。このデー...

ライブストリーミングに関する 7 つの「恐ろしい」予測

ライブストリーミングは、過去から未来への旅の途中の立ち寄り場所です。これまではテキスト、画像、音声、...

2019年のデジタル中国指数レポートが発表され、クラウドの利用、GDP、デジタル経済の発展の間に強い相関関係があることが示された。

5月21日、2019年テンセントグローバルデジタルエコシステムカンファレンスが開催されました。テンセ...

SEO はコンテンツと外部リンク ページの要素だけではありません。

多くの友人は、コンテンツと外部リンク以外のSEOに関することは、一時的な流行に過ぎないと考えています...

同じキーワードに対する異なるユーザーニーズの調査

中国文化は奥深く広大です。日常のやり取りやコミュニケーションの中で、1 つの単語に複数の意味があるこ...

小紅書のブランドマーケティング推進メカニズムの分析

新しい消費時代において、ブランドがインターネット上のさまざまなマーケティングおよびプロモーション プ...

アリババの統合思考をビデオで分析

数日前、私はアリババが発売しようとしているボックスが市場に大きな影響を与えるかどうかに注目していまし...

webhats 10ドル/月 2Gメモリ/50Gハードディスク/500Gトラフィック/4IP

VPS の価格動向はますます悪化しています。海外ではハードウェアが安すぎる、海外では帯域幅が十分かつ...

クラウドの回復力に関するガイド: セキュリティを最大化し、ダウンタイムを最小化する

当然のことながら、クラウドの弾力性は 2020 年代の IT の流行語となっています。サイバー攻撃や...

分散型で高可用性のメタデータ収集の原則

導入:メタデータの収集は、メタデータ製品の中核部分です。収集効率をどのように向上させるかについては慎...

山東省金農プロジェクトが「クラウドコンピューティング」導入をリード

近年、山東省は農業の情報化において大きな進歩を遂げました。ハイライトは、山東省の「黄金農業プロジェク...

エッジコンピューティングがトレンドである理由

この記事はLeiphone.comから転載したものです。再印刷が必要な場合は、Leiphone.co...

ユーマン実践:ホットワードをうまく活用して正確なトラフィックを誘導する

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますホットワー...

企業がSEO最適化を効果的に行うには

はじめに:SEO最適化は現在最も費用対効果の高いインターネットマーケティング手法であり、最もホットな...