Kafkaの障害から、Kafkaの高可用性の原理を理解しました

Kafkaの障害から、Kafkaの高可用性の原理を理解しました

[[408030]]

問題は Kafka の停止から始まりました。

私は金融テクノロジー企業に勤めていますが、金融決済分野でより普及している RabbitMQ は会社では使用されていません。代わりに、最初からログ処理用に設計された Kafka を使用します。そのため、私は Kafka の高可用性の実装と保証について常に興味を持っていました。 Kafka が導入されて以来、システム内で使用される Kafka は、利用できなくなることなく安定して稼働しています。

しかし、最近、システム テスターから、Kafka コンシューマーがメッセージを受信できないことがあるという報告がよく寄せられています。管理インターフェースにログインすると、3 つのノードのうち 1 つがクラッシュしていることがわかります。しかし、高可用性の概念によれば、3 つのノードのうち 2 つはまだ使用可能であるのに、クラスター全体のコンシューマーがメッセージを受信できないのはなぜでしょうか?

この問題を解決するには、まず Kafka の高可用性実装から始める必要があります。

Kafka のマルチコピー冗長設計

リレーショナル データベースに基づいて設計された従来のシステムでも、Zookeeper、Redis、Kafka、HDFS などの分散システムでも、高可用性を実現する方法は通常、冗長設計を採用し、冗長性によってノード障害や使用不可の問題を解決することです。

まず、Kafka の概念を簡単に見てみましょう。

論理モデル

  • ブローカー (ノード): Kafka サービス ノード。簡単に言えば、ブローカーは Kafka サーバー、つまり物理ノードです。
  • トピック: Kafka では、メッセージはトピック別に分類されます。各トピックにはトピック名があります。プロデューサーはトピック名に基づいて特定のトピックにメッセージを送信し、コンシューマーはトピック名に基づいて対応するトピックからメッセージを消費します。
  • パーティション: トピックはメッセージを分類するための単位ですが、各トピックはさらに 1 つ以上のパーティションに分割でき、パーティションは 1 つのトピックにのみ属することができます。トピックとパーティションはどちらも論理的な概念です。たとえば、メッセージ 1 とメッセージ 2 の両方がトピック 1 に送信された場合、それらは同じパーティションまたは異なるパーティション (つまり、同じトピックの異なるパーティションには異なるメッセージが含まれる) に入り、その後、パーティションに対応するブローカー ノードに送信されます。
  • オフセット: パーティションは、メッセージの送信のみを許可し、送信は許可しないキューとして見ることができます (Kafka はパーティション内のメッセージが順番に並んでいることのみを保証します)。メッセージはキューの末尾に追加されます。パーティションに入る各メッセージには、パーティション内のメッセージの位置を識別するオフセットが設定されます。コンシューマーはオフセットを使用して、消費するメッセージを識別します。

それはそんなに簡単なのでしょうか?はい、上記のマルチレプリカアーキテクチャ図に基づいて、Kafka の高可用性が実現されます。ブローカーがダウンしても心配する必要はありません。このブローカーのパーティションのコピーは他のブローカー ノードに残っています。リーダーが死んだらどうなるのでしょうか?次に、フォロワーの中からリーダーを選出するだけで、生産者と消費者は新しいリーダーと再び楽しく遊ぶことができます。これは高可用性です。

まだ疑問があるかもしれませんが、何部あれば十分でしょうか?フォロワーとリーダーが完全に同期していない場合はどうなりますか?ノードがダウンした後のリーダー選出ルールは何ですか?

直接的な結論:

何部あれば十分でしょうか?

レプリカの数が増えるほど、Kafka の可用性が高まります。ただし、レプリカが増えると、ネットワークとディスクのリソースの消費量が増え、パフォーマンスが低下します。一般的に、高可用性を確保するには 3 つのレプリカで十分です。極端な場合には、レプリケーション係数パラメータを増やすことができます。

フォロワーとリードが完全に同期されていない場合はどうなりますか?

フォロワーとリーダーは完全に同期されているわけではありませんが、完全に非同期でもありません。代わりに、ISR メカニズム (In-Sync Replica) を使用します。各リーダーは、基本的にリーダーと同期されているフォロワーを格納する ISR リストを動的に維持します。ネットワークまたは GC の理由によりフォロワーがリーダーへのデータ プル リクエストを開始できない場合、フォロワーはリーダーと同期されなくなり、ISR リストから除外されます。したがって、ISR リスト内のフォロワーはすべて、リーダーに追随できるコピーです。

ノードがダウンした後のリーダー選出ルールは何ですか?

Zookeeper の Zab、Raft、Viewstamped Replication、Microsoft の PacificA など、分散関連の選出ルールは数多くありますが、Kafka のリーダー選出の考え方は非常にシンプルです。上記の ISR リストに基づいて、クラッシュが発生すると、すべてのレプリカが順番に検索されます。見つかったレプリカが ISR リストにある場合、そのレプリカがリーダーとして選出されます。さらに、前のリーダーが退位したことを確認する必要があります。そうしないと、スプリットブレイン状況 (リーダーが 2 人) が発生します。どうやって保証するのですか? Kafka は、コントローラーを設定することで、リーダーが 1 つだけであることを保証します。

Ackパラメータは信頼性を決定します

さらに、Kafka の高可用性に関する面接に必要な知識ポイントは、request.required.asks パラメータです。

Asks パラメータはプロデューサー クライアントの重要な構成であり、メッセージを送信するときに設定できます。このパラメータには、0、1、および All の 3 つの設定可能な値があります。

最初の値は 0 に設定されており、プロデューサーがメッセージを送信した後、メッセージがデッドかアライブかは関係ないことを意味します。これは送信して忘れるようなもので、私たちは自分が言ったことに対して責任を負いません。無責任であれば、メッセージが失われ、可用性も失われる可能性があります。

2 番目は 1 に設定されており、プロデューサーがメッセージを送信した後、メッセージがリーダーに正常に伝達されていれば、他のフォロワーが同期されているかどうかは関係ないことを意味します。リーダーがメッセージを受信したばかりで、フォロワーがクラッシュする前にブローカーと同期する時間がなかったが、プロデューサーはメッセージが正常に送信されたとすでに認識しているため、この時点でメッセージが失われるという状況があります。

これを 1 に設定するのが Kafka のデフォルト設定です。 Kafka のデフォルト構成はそれほど可用性が高くなく、高可用性と高スループットのトレードオフになっていることがわかります。

3番目は、すべて(または-1)に設定することです。

つまり、プロデューサーがメッセージを送信した後、リーダーがメッセージを受信するだけでなく、ISR リスト内のフォロワーも同期して、プロデューサーがタスク メッセージを正常に送信できるようにする必要があります。

さらに考えてみると、 Asks=All の場合、メッセージが失われる状況が発生するのではないでしょうか。答えはイエスです。 ISR リストにリーダーのみが残っている場合、 Asks=All は Asks=1 と同等になります。この場合、ノードがクラッシュしてもデータが失われないことが保証されますか?したがって、データ損失が保証されるのは、Asks=All であり、ISR に 2 つのコピーがあるときだけです。

問題を解決する

長い道のりを経て、Kafka の高可用性メカニズムを理解した私たちは、ついに最初に尋ねた疑問に戻ってきました。ノードがダウンすると、なぜ Kafka が利用できなくなるのでしょうか?

開発およびテスト環境で構成したブローカー ノードの数は 3、トピック レプリカの数は 3、パーティションの数は 6、Asks パラメーターは 1 です。

3 つのノードのうち 1 つがダウンした場合、クラスターは最初に何を実行しますか?そうです、上で述べたように、クラスターはパーティションのリーダーに障害が発生したことを検出すると、ISR リストからリーダーを再選出する必要があります。 ISR リストが空の場合、使用できないのでしょうか?いいえ、代わりに、パーティションの残存コピーからリーダーが選択されますが、これによりデータ損失の潜在的なリスクが生じます。

そのため、Topic のコピー数を Broker の数と同じ数に設定しておけば、Kafka のマルチコピー冗長設計によって高可用性を確保でき、1 回のダウンタイムで利用できなくなるという状況は発生しません (ただし、Kafka には保護戦略があり、半数以上のノードが利用できなくなると Kafka は停止することに注意してください)。よく考えてみると、Kafka 上にレプリカが 1 つある Topic はあるでしょうか?

問題は__consumer_offsetにあります。 __consumer_offset は、コンシューマーが消費するオフセット情報を格納するために Kafka によって自動的に作成されるトピックです。デフォルトのパーティション数は 50 です。このトピックのデフォルトのレプリカ数は 1 です。すべてのパーティションが同じマシン上に存在する場合、それは明らかに単一障害点です。 __consumer_offset を保存しているパーティションのブローカーが強制終了されると、すべてのコンシューマーが消費を停止したことがわかります。

この問題を解決するにはどうすればいいでしょうか?

まず、__consumer_offset を削除する必要があります。このトピックは Kafka の組み込みトピックであり、コマンドを使用して削除することはできないことに注意してください。ログを削除して削除しました。

次に、offsets.topic.replication.factor を 3 に設定して、__consumer_offset のレプリカ数を 3 に変更する必要があります。__consumer_offset のコピーを冗長化することで、ノードがクラッシュした後のコンシューマー消費の問題を解決できます。

最後に、__consumer_offset のパーティションが各ブローカーに分散されるのではなく、1 つのブローカーにのみ保存されるように見える理由がわかりません。

<<:  モバイルエッジコンピューティングは爆発的な成長を遂げると予想されている

>>:  1,000万人のユーザーが同時にオンラインで接続できます。テンセントクラウドの技術が中国特許金賞を受賞した

推薦する

高品質の外部リンクを取得する 安心してウェブサイトのランキングを向上させる6つのポイント

1. 百科事典。この方法を使用するには、ある程度の専門知識と文学的才能が必要です。エントリを編集して...

「SEOアート」の簡単なレビュー

チームは端午節の期間中に3日間の休暇を取ることにしたので、王世凡は本を買って故郷に帰ることにした。数...

検索エンジンはウェブサイトに対して高い要件を設けていないのに、なぜウェブサイトの順位が上がらないのでしょうか?

実は、検索エンジンはウェブサイトに対してそれほど高い要件を設けていません。2012年の百度嵐以来、百...

ローカルキーワードを最適化して征服するのは非常に簡単です

私が始めたばかりの頃、SEOの宿題「中山ウェブサイトプロモーション」にしばらく苦労していたことを覚え...

モバイルフォーラムで勝つ:美容ゲームの分野にビジネスチャンスあり

「モバイルとクラウドで勝つ」円卓会議(写真はテンセントテクノロジー撮影)テンセントテクノロジーニュー...

Honor 携帯電話の復活の秘密

かつてファーウェイのブランドだったHonorは、かつての雇用主であるファーウェイからの「制裁命令」の...

タオバオストア運営における厳しい需要について(第2部)

前回の記事で取り上げた緊急を要するトピックは、Taobao での偽注文でした。その短い記事では、タオ...

desivps: ロサンゼルスの無制限トラフィック VPS、KVM 仮想化、月額 2 ドル、2G メモリ/1 コア/20g SSD

desivps は 年に設立され、検証可能な資格を有し、インドのムンバイに登録され、そこで事業を展開...

Docker セキュリティのためのトップ 10 のオープン ソース ツール

[51CTO.com クイック翻訳] コンテナのセキュリティに関しては、Tesla が経験したような...

MogujieのChen Qi氏:「Taobaoは必然的に垂直的な電子商取引セグメントに細分化されるだろう」

モグジエのCEOである陳奇氏にインタビューする前に、私はある疑問について考えていました。なぜ、同じく...

プロメテウス - 50% オフ/KVM VPS/SSD ディスク/G ポート/同じ更新価格

Prometeus の 17 周年を記念して、公式に KVM ベースの仮想 SSD ハード ディスク...

莫言がノーベル文学賞を受賞し、関連ドメイン名が登録された

莫言は、本名を関莫業といい、山東省高密県に生まれた。新浪科技は10月12日午後、中国の現代有名作家の...

クラウドネイティブのインメモリデータベースがストレージとコンピューティングの統合を実現

「インメモリデータベースは、クラウドネイティブ、永続性、コンバージドコンピューティングを3つの主要な...

ウェブサイトのキーワードを決定する方法

学校でエッセイの書き方を習っていたとき、先生はこう言っていました。「書き始める前に、まず記事の主な内...