インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

ZooKeeperは、オープンソースの分散調整サービスおよび分散データ整合性ソリューションです。ZooKeeperに基づいて、ネーミングサービス、クラスター管理、マスター選択、分散ロックなどの機能を実現できます。

高可用性

ZooKeeperの可用性を確保するために、本番環境ではZooKeeperクラスターモードを使用して外部サービスを提供し、クラスターサイズは少なくとも3つのZooKeeperノードで構成されます。

クラスタは少なくとも3つのノードで構成されています

実際、ZooKeeper 2ノードはクラスターを形成して外部サービスを提供することもできますが、クラスターを使用する主な目的は高可用性です。2つのノードがクラスターを形成する場合、ノードの1つがダウンし、ZooKeeperノードは外部サービスを正常に提供できません。したがって、クラスターの意味は失われます。

3つのノードがクラスターを形成し、いずれかのノードがハングアップした場合、ZooKeeperのリーダー選出メカニズムに従って、他の2つのノードの1つをリーダーとして選択でき、クラスターは引き続き外部にサービスを提供できます。

ノードが多いほど良いとは限りません

  • ノードが多いほど、より多くのリソースが使用されます
  • ノードが多いほど、ZooKeeperノード間の通信コストが高くなり、ノード間で相互接続されるソケットが多くなります。ZooKeeperクラスターのトランザクション処理に影響します
  • ノードが多いほど、スプリットブレインの可能性が高くなります

クラスターサイズが奇数

独自のコストとリソースを検討することに加えて、クラスターサイズもZooKeeperの機能と併せて検討する必要があります。

  • リソースを節約する
  • 3ノードクラスターと4ノードクラスターの場合は、3ノードクラスターの使用を選択し、5ノードクラスターと6ノードクラスターの場合は、5ノードクラスターの使用を選択します。等々。実稼働環境で高可用性を確保するために、3ノードクラスターは最大1つまでハングすることができ、4ノードクラスターは最大1つまでハングすることができます(理由は半分以上の原則で説明されています)。同様に、5ノードのクラスターでは最大2ユニット、6ノードのクラスターでは最大2ユニットを使用できます。
  • リソースを節約するために、奇数ノードを使用して同じ高可用性を実現する必要があります。
  • クラスターの可用性
  • クラスター内のノード間のネットワーク通信に問題がある場合の奇数と偶数のクラスターへの影響

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

クラスター構成

ZooKeeperクラスター構成には、少なくとも2つの変更が必要です。

1.クラスター構成を増やす

クラスターの構成を{ZK_HOME} /conf/zoo.cfgに追加します。構造はserver.id = ip:port1:port2に基づいています。

たとえば、次の構成ファイルは3つのZooKeeperで構成されるクラスターを表しています。

server.1 = localhost:2881:3881 
server.2 = localhost:2882:3882server.3 = localhost:2883:3883

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

2.ノードIDを構成する

zoo.cfgでクラスターを構成するときは、server.idを指定する必要があります。このIDは、(zoo.cfgで構成された)dataDirで指定されたディレクトリにmyidファイルを作成する必要があります。ファイルのコンテンツは、現在のZooKeeperノードのIDです。

クラスターの役割

ZooKeeperはマスター/スレーブの概念を使用しませんが、クラスター内のノードを3つのタイプの役割に分割します。

  • 盟主
  • ZooKeeperクラスターでは、リーダーは1つしか存在できません。このリーダーは、クラスター内のトランザクション要求の唯一のスケジューラーおよびプロセッサーです。いわゆるトランザクション要求は、クラスターの状態を変更する要求を指します。リーダーは、トランザクションIDに基づいてトランザクション処理の順序を確認できます。 。
  • クラスタ内に複数のリーダーがいる場合、この現象は「スプリットブレイン」と呼ばれます。クラスター内の複数のリーダーの影響を想像してみてください。
  • これは元の大きなクラスターと同等であり、複数の小さなクラスターが分割され、それらの間のデータは互いに同期されません。クラスタ内のデータは、「スプリットブレイン」の後で非常に乱雑になります。
  • フォロワー
  • FollowerロールのZooKeeperサービスは、非トランザクションリクエストのみを処理できます。クライアントトランザクションリクエストを受信すると、リクエストをリーダーサーバーに転送し、リーダー選挙に参加し、リーダートランザクション処理投票に参加します。
  • フォロワーは、クラスター内のリーダーが使用できないことを検出すると、その状態を変更し、リーダー選挙投票を開始します。最終的に、クラスター内のフォロワーがリーダーとして選択されます。
  • 観察者
  • オブザーバーはフォロワーに非常によく似ており、非トランザクション要求を処理でき、トランザクション要求をリーダーサーバーに転送します。
  • フォロワーとは異なり、オブザーバーはリーダー選挙には参加せず、リーダートランザクション投票には参加しません。
  • オブザーバーは、クラスターのトランザクション処理機能に影響を与えることなく、クラスターの非トランザクション処理機能を改善するために使用されます。

リーダー選挙

リーダーはクラスター内で非常に重要な役割であり、トランザクション全体の処理とスケジューリングを担当し、分散データの一貫性を確保するための鍵となります。リーダーはZooKeeperクラスターで非常に重要であるため、クラスターに常に1つのリーダーのみが存在することを確認する必要があります。

クラスター内のリーダーが利用できない場合は、クラスターから最適なサービスを見つけてリーダーに昇格させ、トランザクションの処理と責任のスケジュールを継続できるようにするメカニズムが必要です。このプロセスはリーダー選挙と呼ばれます。

選挙メカニズム

ZooKeeper選挙指導者は、次の原則に依存し、優先順位に従います。

1.選挙投票は同じラウンドで行われなければならない

フォロワーサービスの選挙ラウンドが異なる場合、投票は採用されません。

2.最新のデータを持つノードが最初にリーダーになります

新旧のデータはトランザクションIDによって決まります。トランザクションIDが大きいほど、ノードデータはリーダーのデータに近いと見なされ、自然にリーダーになるはずです。

3. server.idを比較します。より高いid値を持つものが最初にリーダーになります

各参加ノードのトランザクションIDが同じ場合は、server.idを使用して比較します。server.idは、クラスター内のノードの一意のIDであり、myidファイルで構成されます。

クラスターの起動時にリーダーが選出されるか、クラスターの実行中にリーダーが再選されるかは関係ありません。クラスタ内の各フォロワーロールサービスは、上記の条件に基づいて適切なリーダーを選択します。ノードの半分以上が選択されると、ノードはリーダーに昇格します。

半分以上の原則

ZooKeeperクラスターには多くのタイプの投票があります。リーダー選挙投票、事業提案投票、これらの投票は多数決の原則に依存しています。言い換えると、ZooKeeperは、投票結果がクラスターの総数の半分を超えており、後続のトランザクションを安全に処理できると考えています。

  • 事業提案票
  • ZooKeeperクラスターを形成する3つのノードがあり、クライアントがノードの追加を要求するとします。トランザクション要求を受け取った後、リーダーはすべてのフォロワーが投票するための「ノード作成」提案を開始します。リーダーがクラスターからフィードバックの半分以上を受け取った場合、リーダーは引き続きすべてのフォロワーへのコミットを開始します。現時点では、リーダーはクラスターが半分以上であると考えています。クラスターがハングアップしても、安全で信頼できます。
  • リーダー選挙投票
  • ZooKeeperクラスターを形成するノードが3つあるとします。現時点では、リーダーが電話を切り、リーダーに投票する必要があります。同じ投票結果が半分以上の場合、リーダーが選出されます。
  • 利用可能なノードをクラスター化する
  • ZooKeeperクラスターの各ノードには独自の役割があり、クラスターの可用性を実現するには、半分以上の原則を満たす必要があります。この半分を超えると、利用可能なリーダーロール+フォロワーロールの数が、クラスター内のリーダーロール+フォロワーロールの総数よりも多くなります。
  • ZooKeeperクラスターを形成する5つのノード、1つのリーダー、2つのフォロワー、2つのオブザーバーがあるとします。2人のフォロワー、または1人のリーダーと1人のフォロワーが停止している場合、クラスターは使用できなくなります。オブザーバーの役割は、いかなる形の投票にも参加しないからです。

いわゆる半分以上の原理アルゴリズムは、投票数>クラスタ内のノードの総数/ 2です。クラスタノードの総数/ 2の計算結果は切り捨てられます。

このアルゴリズムは、ZooKeeperのソースコードQuorumMaj.javaに実装されています。以下のコードスニペットが削減されました。

public boolean containsQuorum(HashSet <Long> set){ 
 / ** nはクラスターの総数を参照します* / int half = n / 2; return(set.size()> half);}

振り返って、奇数クラスタと偶数クラスタのリーダー選挙の結果を見てみましょう。

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

したがって、3つのノードと4つのノードで構成されるクラスターは、ZooKeeperの原則の下で最大で1つのノードしか持つことができませんが、4〜3つは1つのノードリソースを浪費します。

シーン戦闘

2つのシナリオを使用して、クラスターが使用できない場合のリーダー再選プロセスを理解します。

3ノードクラスター再選リーダー

server.1(フォロワー)、server.2(リーダー)、server.3(フォロワー)の3つのノードで構成されるクラスターを想定します。現在、server.2は使用できません。クラスターには次の変更があります。

1.クラスターが利用できない

リーダーがダウンしているため、クラスターはトランザクション要求に使用できません。

2.ステータス変更

すべてのフォロワーノードは、ステータスをLOOKINGに変更し、独自の投票を変更します。投票内容は、自分のノードのトランザクションIDとserver.idです。(トランザクションID、server.id)で表します。

server.1のトランザクションIDが10であるとすると、変更の独自の投票は(10、1)であり、server.3のトランザクションIDは8であり、変更の独自の投票は(8、3)です。

3.最初の投票

変更の投票をクラスター内のすべてのフォロワーノードに送信します。server.1は、それ自体を含め、クラスター内のすべてのフォロワーに(10、1)を送信します。Server.3は同じで、すべてのフォロワーに(8、3)を送信します。

したがって、server.1は2つの票(10、1)と(8、3)を受け取り、server.3は2つの票(8、3)と(10、1)を受け取ります。

4. PKの投票

投票の開始に加えて、各フォロワーノードは他のフォロワーから送信された投票も受け取り、2つの提案されたトランザクションIDとserver.idを独自の投票PKと比較します。PKの結果は、状態を変更して再度投票するかどうかを決定します。

server.1の場合、2つの投票(10、1)と(8、3)が受信されます。それ自体が変更した投票と比較すると、どちらも自分の投票(10、1)より大きくないため、server.1はそれ自体を維持します投票は変更されません。

server.3の場合、2つの票(10、1)と(8、3)を受け取ります。自身の変更の票と比較した後、server.1によって送信された票は自分の票より大きいため、server.3は自分の投票を変更し、変更した投票をクラスター内のすべてのフォロワーに送信します。

5. 2回目の投票

server.3は投票を(10、1)に変更し、クラスター内のすべてのフォロワーに再度投票を送信します。

server.1の場合、2番目のラウンドで(10、1)の投票が受信され、server.1はPK後も変更されないままです。

server.3では、server.3自体が(10、3)投票に変更されたため、今回は(10、1)投票が受信されました。

この時点で、server.1とserver.3は投票について合意に達しました。

6.投票受付バケット

ノードが受信した投票は受信バケットに格納され、各フォロワーの投票結果はバケットに1回だけ記録されます。ZooKeeperソースコードの受信バケットは、Mapによって実装されます。

次のコードスニペットは、ZooKeeperによって定義され、バケットにデータを書き込む受信バケットです。Map.KeyはLong型で、投票元ノードのserver.idを格納するために使用され、Voteは対応するノードの投票情報です。ノードは投票を受信した後、受信バケットを更新します。つまり、バケットはすべてのフォロワーノードの投票を保存し、最後の投票結果のみが保存されます。

HashMap <ロング、投票> recvset = new HashMap <ロング、投票>(); 
recvset.put(n.sid、new Vote(n.leader、n.zxid、n.electionEpoch、n.peerEpoch));

7.統計投票

投票を受け取った後、毎回投票を数えようと試み、投票数の半分が過ぎると選挙は成功します。

投票統計のデータは、投票受信バケット内の投票データから取得されます。このシナリオを最初から説明し、受信バケット内のデータの変化を見てみましょう。

server.2が電話を切った後、server.1とserver.3が最初の投票を開始します。

server.1は、server.1から(10、1)投票を受け取り、server.3から(8、3)投票を受け取ります。

server.3は、server.1から(10、1)票を、server.3から(8、3)票も受け取ります。このとき、server.1とserver.3の受信バケット内のデータは次のようになります。

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

server.3がPKに合格した後、server.1の投票が自身の投票よりも大きいと信じたため、server.3は投票を変更し、投票を再開しました。

server.1はserver.3から(10、1)の投票を受け取り、server.3はserver.3から(10、1)の投票を受け取りました。このとき、server.1とserver.3の受信バケット内のデータは次のようになります。

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

ZooKeeperの原則の半分以上に基づいて:バケットに投票してserver.1をリーダーとして2回選出し、半分以上を2> 3/2、つまり2> 1に選出してください。

最後に、sever.1ノードがLeaderに昇格し、server.3がFollowerに変更されました。

クラスター拡張リーダーをいつ開始するか

ZooKeeperクラスターを拡張するには、zoo.cfg構成ファイルに新しいノードを追加する必要があります。拡張プロセスはZooKeeper拡張で導入されました。ここでは、3ノードの容量が5ノードに拡張された場合のリーダー起動のタイミングについて説明します。

現在、クラスターを形成している3つのノード、つまりserver.1(フォロワー)、server.2(リーダー)、およびserver.3(フォロワー)があると想定します。クラスター内のノードトランザクションIDは同じであると想定します。設定ファイルは以下の通りです。

server.1 = localhost:2881:3881 
server.2 = localhost:2882:3882server.3 = localhost:2883:3883

1.新しいノードがクラスターに参加します

2つの新しいノード、server.4とserver.5がクラスターに追加されます。最初に、server.4とserver.5のzoo.cfg構成を変更して開始します。ノード4および5は、起動後に投票ステータスを変更し、リーダー選挙投票のラウンドを開始します。server.1、server.2、およびserver.3が投票を受け取った後、リーダーがクラスターで選択されているため、server.4およびserver.5の投票結果を直接フィードバックします。server.2がリーダーです。投票を受けたserver.4とserver.5は、半分以上の原則に基づいてserver.2がリーダーであると判断し、フォロワーに切り替えます。

#节点server.1、server.2、server.3配置
サーバー.1 = localhost:2881:3881server.2 = localhost:2882:3882server.3 = localhost:2883:3883#节点サーバー.4、server.5配置サーバー.1 = localhost:2881:3881server.2 = localhost:2882:3882server.3 = localhost:2883:3883server.4 = localhost:2884:3884server.5 = localhost:2885:3885

2.リーダーを停止

server.4とserver.5を追加すると、クラスターserver.1、server.2、およびserver.3のzoo.cfg構成を変更して再起動する必要があります。ただし、リーダーノードを再起動すると、リーダーの再起動によってクラスターのフォロワーがリーダーの再選を開始するため、注意することが重要です。server.4とserver.5の2つの新しいノードが正常に追加された後、新しいノードが追加されるため、クラスターはリーダーを変更しません。したがって、現在server.2は引き続きリーダーです。

クラスターがどうなるかを確認するために、間違った順序で開始しました。server.2zoo.cfg構成ファイルを変更し、server.4およびserver.5の構成を増やして、server.2サービスを停止します。server.2が停止すると、リーダーは存在しなくなり、クラスター内のすべてのフォロワーが投票を開始します。server.1とserver.3が投票を開始するとき、server.4とserver.5ノードはserver.1とserver.3のクラスター構成に含まれていないため、投票はserver.4とserver.5に送信されません。対照的に、server.4およびserver.5は、クラスター内のすべてのノードに投票を送信します。つまり、server.1とserver.3の場合、クラスターにはノードが3つしかないと考えています。server.4とserver.5については、クラスター内に5つのノードがあると考えています。

半分以上の原則に従って、server.1とserver.3はすぐに新しいリーダーを選択します。ここでは、server.3が新しいリーダーになるように昇格されたと仮定します。しかし、server.2を起動しなかった場合、投票は半分以上の原則を満たしていないため、server.4とserver.5は常にLeaderに投票します。これまでは、クラスター内のノードのステータスは次のようになっています。

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

3.リーダーを開始

次に、server.2を起動します。server.2zoo.cfgはすでにserver.1からserverv.5への完全な構成であるため、選挙投票はserver.2の起動後に開始され、serverv.4およびserverv.5も常に選挙投票を開始します。server.2の選挙ラウンドがserverv.4とserverv.5の選挙ラウンドと調整されると、最後にserver.2はその状態を変更し、server.5がLeadaderであると判断します。

予期しないことが起こり、2人のリーダーが現れました。

インタビュアーからの質問:ZooKeeperクラスターとリーダー選挙についてのあなたの理解について教えてください。

 

ZooKeeperクラスターが拡張されている場合、リーダーノードが最後に起動されると、リーダーノードが再起動する前にすべてのフォロワーノードのzoo.cfg構成が同じであり、相互接続する同じクラスター構成に基づいているため、この問題は回避でき、投票します選挙。

おすすめ

転載: blog.csdn.net/python8989/article/details/108524443