生産失敗 | 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 のキーワードの解釈: データ、イノベーション、オープンな協力

推薦する

インターネット開発の新時代ではSEO最適化の多様化が必要

インターネット時代の漸進的な発展により、SEO の需要が高まっています。SEO 技術の普及と検索エン...

3分でASOを理解!運営やプロモーションが初めての方はこちらをご覧下さい!

この記事は 1,300 語の長さで、3 分ほどかけて読むことをお勧めします。 ASOとは何ですか?何...

金融業界のデジタル変革にはマルチクラウド戦略が第一の選択肢

デジタル変革のプロセスが加速するということは、多くの金融機関がクラウドへの移行という問題に直面するこ...

A5ウェブマスターネットワーク第8回タオバオアフィリエイトオンライン収益トレーニング登録

トレーニングの紹介タオバオアフィリエイトは現在、オンラインでお金を稼ぐ最も人気のある方法です。また、...

ビッグデータによるパーソナライズされた推奨に関する私の理解

この記事を書こうと思ったのは、一方では昨日、ようやくXiang Liang著の「推薦システム実践」を...

絶対に失敗しないSEO最適化戦略の2番目のポイントは、98%の人が無視している

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスCen Huiyu は ...

#BlackFriday# zgovps: 年間わずか 12.9 ドル、米国 AS4837/日本 IIJ/ドイツ BGP、ハイエンド ハードウェア、爆発的なパフォーマンス

zgovps は、年間 12.9 ドルという低価格の特別ブラックフライデー プロモーションを開始しま...

インターネットは格闘技の世界のようなものです。いまだに何人のウェブマスターがさまよっているのでしょうか?

人がいるところに武術の世界があります。どうやってやめることができますか?これは映画「微笑む誇り高き放...

Bilibili UPマスターのデジタルコレクションの代金を誰が支払うのでしょうか?

テンセントのデジタルコレクションプラットフォーム「Huanhe」は、開始から1年後に正式に撤退を発表...

ウェブサイトを検索エンジンの検索結果の上位3位にランクインさせる

ウェブサイトの最適化、特にウェブサイトのキーワードランキングの最適化として、検索エンジンで上位 3 ...

Googleの検索結果には、同じドメイン名のウェブサイトがどんどん表示される

マット・カッツは2007年にこう言いました。特定の種類の検索(難解な用語やロングテールの用語など)で...

lisahost: 10% オフ、(3 つのネットワーク) US cn2 gia VPS、ネイティブ IP、最低 2 元

Lisahost はサーバーのハードウェアを大規模にアップグレードし、より手頃な価格でパフォーマンス...

Baidu SEO:「ウェブサイトのクロール頻度」を気にする必要があるのはなぜですか?

月給5,000~50,000のこれらのプロジェクトはあなたの将来です毎日、何万もの URL が検索エ...

SEO の考え方を取り入れた記事の書き方について簡単に説明します

記事はウェブサイト全体のコンテンツの一部であり、すべての記事がウェブサイト全体のコンテンツを構成しま...

2022年のモバイルライブストリーミングアプリケーション市場の洞察

世界のモバイルライブストリーミングアプリケーションの収益は、2020年以降2年連続で急成長を遂げてい...