動物園のrecipe for lockを読んでいるうちに、混乱しました。この分散ロックのレシピは、"2人のクライアントが同じロックを保持していると思うスナップショットはありません"という保証はできません。しかし、ZooKeeperは非常に広く採用されているので、リファレンスドキュメントにこのような間違いがあった場合、誰かがそれを先に指摘していたはずなので、私は何を誤解しましたか? the recipe for distributed locksを引用飼い葉桶のロックレシピに関する懸念
:グローバル同期している
ロック
完全分散ロック、時間内の任意のスナップショットで意味なし2つのクライアントは、彼らが同じロックを保持すると思うん。これらはZooKeeeperを使用して実装できます。優先度キューと同様に、最初にロック・ノードを定義します。
- コールは "locknode/GUID-ロックイン" と設定されたシーケンスと短命フラグのパス名に()を作成します。
- ウォッチフラグを設定せずにロックノードでgetChildren()を呼び出します(これは群れの影響を避けるために重要です)。
- 手順1で作成したパス名のシーケンス番号の接尾辞が最も小さい場合、クライアントはロックを持ち、クライアントはプロトコルを終了します。
- クライアントコールは、ロックディレクトリ内のパスにwatchフラグが設定されており、次のシーケンス番号が最も低くなります。 :)(存在する場合はfalseを返します
- 、考えてみましょう以下のケースを2
ステップに行く前に、前のステップからのパス名の通知を待って、それ以外の場合は手順2に進みます。
- Client1がZooKeeperノード「locknode/guid-lock-0」を使用してロックを取得しました(手順3)。
- クライアント2のノード「locknode/guid-lock-1」がロックの取得に失敗し、現在「locknode/guid-lock-0」を監視しています。
- その後、何らかの理由で(ネットワーク輻輳など)、Client1はZooKeeperクラスタにハートビートメッセージを送信できませんが、Client1はまだロックを保持していると誤って処理しています。
しかし、ZooKeeperのはクライアント1のセッションがタイムアウトしていると思うし、その後
- 削除 "locknode/guidをロック-0" も、
- は、クライアント2に通知を送信(または多分最初の通知を送信しますか? )、
- (ただし、ネットワークの輻輳のために)「セッションタイムアウト」通知をClient1に送信できません。
- クライアント2は、「locknode /のGUIDロック-1" 、それ自体を作成した」だけのノードを取得し、ステップ2に進み、通知を取得し;従って、クライアント2は、それがロックを保持前提
- しかしで同じ時刻に、Client1はロックを保持しているとみなします。
これは有効なシナリオですか?
_zookeeper-users_メーリングリストに関するパラレルディスカッション:http://thread.gmane.org/gmane.comp.java.hadoop.zookeeper.user/5065 – seh