以前、私は「理由は分かっているが、理由は分からない。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 ディレクトリのレイアウトと機能に焦点を当てる必要があります。ディレクトリの詳細は次のとおりです。
Kafka バージョン 2.8 未満では、Kafka のトピック内のルーティング情報は最終的に Zookeeper に保存され、各ブローカー ノードは起動後にデータのコピーをメモリにキャッシュします。 /brokers ノードの各子ノードは特定のトピックを表します。トピックのメタデータには、主にパーティションの数と各パーティションのステータス情報が含まれます。各パーティションのステータス情報には主に次のものが含まれます。
Zookeeper にも同様の「設計パターン」があり、これは Zookeeper 内に一時的なノード + イベント監視メカニズムを作成して、データのリアルタイムの動的認識を実現するというものです。 /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 を確認し、重要なログを見つけます。 コアログの解釈:
次に、手がかりに従って、以下に示すようにノード 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 のキーワードの解釈: データ、イノベーション、オープンな協力
Racknerd は、「St. Patrick's」(聖パトリックの日)のために 2G メモ...
[51CTO.com クイック翻訳] 過去 40 年近くにわたって、SQL はリレーショナル データ...
ハイブリッド クラウドの概念実証は、展開が IT およびビジネスのニーズを完全に満たしていることを確...
業界が成長すると、Alibaba Cloud はエコシステムを構築します。業界がエコシステムを構築し...
Jiuxian.com、Goujiu.com、Hongjiuke.comなどのワイン販売ウェブサイト...
UK2 グループの子会社である UK2.NET (1998 年から運営) には、年間支払いがわずか ...
速度の向上とレイテンシの短縮は、5G とエッジ コンピューティングの組み合わせが今日非常に人気となっ...
私は起業家情報ネットワークの編集者です。今日は、スパイダーを誘惑して、ウェブサイトのコンテンツとスナ...
ビジネスが成長するにつれて、コンピューティング インフラストラクチャの拡大によって障害のリスク ポイ...
moonvmはどうですか? moonvm 台湾アポルはどうですか? moonvm は、台湾の hin...
Baidu News Searchは最近、検索結果の表示スタイルだけでなく、表示される検索結果の数に...
ウェブサイトのインクルージョンは、すべての基礎です。インクルージョンがなければ、何も語れませんので、...
インターネット上のさまざまな業界のウェブサイトの中には、消費者が2度目を購入することがほとんどない業...
海外メディアの報道によると、ハッカーらが欧米のオタクが集まるフォーラム「4chan」でハリウッド女優...
この本を書く目的は、お金を稼ぐためでも、皆さんと学び、コミュニケーションをとるためでもありません。私...