群れの行動を避けるために、飼育係分散ロック(群れ効果)

本稿では、分散ロックのZooKeeper実装プロセスを使用することを記載し、効果的に「牧畜(群れ効果)」を回避する方法です。

分散ロックの一般的な実現

ここでは、通常の分散ロックの下で達成するためにどのように単に話します。特定のコードの実装はここで見ることができます:https://svn.apache.org/repos/asf/zookeeper/trunk/src/recipes/lock/

「前ZooKeepeデータモデルは、ノードのZooKeeperの種類を作成し、前に物品を指す」ここで我々は、ノードの一時的な順序に焦点を当てて、四つのカテゴリーがあります。このタイプのノードは、いくつかのいくつかの機能があります。

  1. ライフサイクルおよびクライアント・ノード・セッションバインディングは、そのノードがクリアされ、かつて過ごしたクライアント・ノード・セッションを作成することです。
  2. 、それぞれの親は作成され、その子ノードの順序を維持する責任を負う、とあなたはノードのシーケンス(シーケンシャル)を作成する場合は、親ノードが自動的に自動的にノード名に付加されるサフィックスの形で、このノードの整数値が割り当てられます最終ノードのノード名として。

上記の二つの特徴、我々は見て、分散ロック取得の基本的なロジックの実装を使用します:

  1. 名前のノードを作成する「_locknode_ /のGUID-ロックイン」のクライアント呼び出しはcreate()メソッドは、ノードの種類、ここでEPHEMERAL_SEQUENTIALを設定する必要を作成するには、ことに留意すべきです。
  2. クライアントは、GetChildrenメソッド(「_ locknode_」)メソッドは、すべての子ノードが作成されている取得するために呼び出して、このノードの子ノードウォッチャー登録変更通知中。
  3. クライアントの後、パスをノードステップ1で作成したノードは、すべてのノードの最小数である自分自身を見つける場合は、その後、ロックを取得するためにクライアントを考えるすべての子になります。
  4. 彼らがステップ3ではないことが判明した場合、彼はまだロックを取得していないことを示す、すべての子ノードの最小である、それはロックを取得するかどうかを判断するために、子ノードを取得し、次の時間までの子ノードの変更通知を待って、。

ロック解除プロセスは比較的簡単ですが、自分で作成することができ、子ノードを削除することです。

問題

この上記分散ロックの実装では、一般的には、ロック競合の分散一般的なクラスタのニーズを満たすことができます。ここでは、一般的なシーンを意味する10機よりも一般的に小さい、小さなクラスターサイズです。

しかし、反射に上記の論理を実現する、我々は容易に分散ロックを通して、このプロセス「ノード自体は最小のノード番号を作成したかどうかを決定するために、サブ点の全てを取得することである」、ステップ4の問題を見つけることができこれは明らかに非常に科学的に見えない - 競争力のあるプロセス、繰り返し実行の数が多いと、営業成績の大半は次回の通知を待つために継続するので、彼は、最小のノード番号ではなかったと判断されています。クライアントは、クライアントの切断一度、同時に複数のノードが存在する場合、大規模なクラスタ場合はサーバが大幅にパフォーマンスに影響を与える、とする時期ということではなく、気づくに関連過大と無償独自のイベントを受け取り、接続は、この時間は、サーバはクライアントの残りの部分のようなイベント通知の大規模な番号を送信します - これは牧畜と呼ばれています。問題の根本は、真のクライアントのフォーカスを識別できないということです。

分散ロック競合手続の上部を見てみましょう、そのコアロジックがある:彼らは最も小さい数値であるかどうかを判断するために、すべてのノード。だから、それだけでは、その数よりも小さく、そのノードに焦点を当てる必要がある各ノードの作成者が考えるのは簡単です。

分散ロックが向上達成します

ここでは改善された実現をロックし、実装前に唯一の違いは、それぞれがライバルとしてここで設計されたロックということで、ちょうど彼らの有無は可能よりも小さいノード番号の下に「_locknode_」ノードに焦点を当てる必要があります。配布されます 以下を達成するために:

  1. 名前のノードを作成する「_locknode_ /のGUID-ロックイン」のクライアント呼び出しはcreate()メソッドは、ノードの種類、ここでEPHEMERAL_SEQUENTIALを設定する必要を作成するには、ことに留意すべきです。
  2. クライアントは、ノードが作成されたすべての子を取得するためのGetChildrenメソッド(「_ locknode_」)メソッドを呼び出して、これは任意のウォッチャーを登録しないことに注意してください。
  3. クライアントは、すべての子になった後、私たちは、クライアントがロックを取得し、その、手順1で作成した最小のノード番号を見つけた場合、パスをノード。
  4. あなたは彼がまだロックを取得していないことを示す、ステップ3ですべての子ノードの少なくとも自分自身をない見つけた場合。クライアントは、ノードが、自身よりも小さい見つける必要がある。この時点では、それが存在する()メソッドを呼び出し、イベントリスナーを登録します。
  5. このノードに関心がある場合は除去した後、クライアントは、対応する通知を受信します。この時間は、クライアントがGetChildrenメソッド(「_ locknode_」)あなたが実際に最小のノードであることを確認した後、ステップ3に進むために作成されたすべての子ノードを取得するためのメソッドを再度呼び出す必要があります。

結論

配布のための最後の2つのロックは、実現可能です。特定の選択は、クラスタのサイズによって異なります。

ます。http://rdc.taobao.com/team/jm/archives/tag/zookeeperからフォワーディング

おすすめ

転載: blog.csdn.net/demon7552003/article/details/92056046