web-dev-qa-db-ja.com

kafkaはネットワークパーティションをどのように処理しますか?

Kafkaには、同期レプリカセットの概念があります。これは、リーダーからそれほど離れていないノードのセットです。

ネットワークがクリーンにパーティション化され、リーダーを含む少数派が一方の側にあり、多数派がもう一方の側に他の同期ノードを含む場合はどうなりますか?

少数派/リーダー側は、おそらくノードの束を失ったと考えており、それに応じてISRサイズを縮小し、喜んで続行します。

反対側はおそらくリーダーを失ったと思っているので、新しいリーダーを選び、楽しく続けます。

これで、同じクラスターに2つのリーダーがあり、書き込みを個別に受け入れます。大多数のノードがパーティションの後で続行する必要があるシステムでは、古いリーダーはステップダウンして書き込みの受け入れを停止します。

カフカのこの状況ではどうなりますか? ISRセットを変更するには、多数決が必要ですか?もしそうなら、リーダー側が停止を検出するまで、短いデータ損失がありますか?

9
Filip Haglund

私はこれをテストしていませんが、受け入れられた答えは間違っており、ラース・フランケは脳分裂の可能性について正しいと思います。

Zookeeperクォーラムには過半数が必要なため、ZKアンサンブルパーティションの場合、最大で片側にクォーラムがあります。

コントローラーになるには、ZK(エフェメラルznode登録)とのアクティブなセッションが必要です。現在のコントローラーがZKクォーラムから離れて分割されている場合、それ自体をコントローラーと見なすことを自発的に停止する必要があります。これには最大でzookeeper.session.timeout.ms = 6000かかります。まだZKクォーラムに接続しているブローカーは、その中から新しいコントローラーを選択する必要があります。 (これに基づく: https://stackoverflow.com/a/52426734

トピックパーティションリーダーになるには、ZKとのアクティブなセッションも必要です。 ZKクォーラムへの接続を失ったリーダーは自発的に1つになるのをやめるべきです。選出されたコントローラーは、一部の元リーダーが欠落していることを検出し、ISRのリーダーから新しいリーダーを割り当て、引き続きZKクォーラムに接続します。

では、ZKタイムアウトウィンドウ中にパーティション化された元リーダーが受信したプロデューサーリクエストはどうなりますか?いくつかの可能性があります。

プロデューサーのacks = allとトピックのmin.insync.replicas = replication.factorの場合、すべてのISRはまったく同じデータを持つ必要があります。元リーダーは最終的に進行中の書き込みを拒否し、プロデューサーはそれらを再試行します。新しく選出されたリーダーはデータを失うことはありません。一方、パーティションが修復されるまで、書き込み要求を処理することはできません。クライアントリクエストを拒否するか、しばらくバックグラウンドで再試行し続けるかは、プロデューサー次第です。

そうしないと、新しいリーダーが最大zookeeper.session.timeout.ms + replica.lag.time.max.ms = 16000相当のレコードを失い、パーティションが修復された後に元のリーダーから切り捨てられる可能性が非常に高くなります。

読み取り専用であることに満足しているよりも長いネットワークパーティションを期待しているとしましょう。

このようなものが機能します:

  • 3つのアベイラビリティーゾーンがあり、最大で1つのゾーンが他の2つのゾーンから分割されると予想されます。
  • 各ゾーンにはZookeeperノード(またはいくつか)があるため、2つのゾーンを組み合わせると常に過半数を形成できます
  • 各ゾーンにはたくさんのKafkaブローカーがいます
  • 各トピックにはreplication.factor = 3があり、各アベイラビリティーゾーンに1つのレプリカ、min.insync.replicas = 2があります。
  • プロデューサーのacks = all

このように、ネットワークパーティションのZKクォーラム側に2つのKafka ISRがあり、そのうちの少なくとも1つは元リーダーと完全に最新である必要があります。したがって、ブローカーでのデータ損失はなく、利用可能です。勝者側に接続できるプロデューサーからの書き込み用。

1

Kafkaクラスターでは、ブローカーの1つがコントローラーとして機能するように選択されます。

とりわけ、コントローラーは新しいリーダーを選出する責任があります。レプリカ管理セクションでは、これについて簡単に説明します。 http://kafka.Apache.org/documentation/#design_replicamanagment

Kafkaは、Zookeeperを使用して、一度に1つのコントローラーのみが存在することを確認しようとします。ただし、説明した状況は依然として発生する可能性があり、Zookeeperアンサンブル(両側にクォーラムがあると仮定)とKafkaクラスターを2に分割し、2つのコントローラーになります。

その場合、Kafkaには、影響を制限するためのいくつかの構成があります。

  • _unclean.leader.election.enable_:デフォルトではFalseです。これは、同期していないレプリカがリーダーになるのを防ぐために使用されます。使用可能なレプリカが同期していない場合、Kafkaはパーティションをオフラインとしてマークし、データの損失を防ぎます
  • _replication.factor_と_min.insync.replicas_:たとえば、それぞれ3と2に設定すると、「スプリットブレイン」の場合、プロデューサーが_acks=all_

クラスターが元に戻った後に分岐したログの処理の詳細については、 KIP-101 も参照してください。

6
Mickael Maison