分散インタビューの質問(1):分散ロック

Q:
分散ロック
1.分散システム環境では、メソッドは1台のマシンの1つのスレッドで同時に実行
できます2.高可用性ロックの取得と解放のロック
3.高性能のロックの取得と解放のロック
4.リエントリーあり機能(再入力、データエラーを気にせずに複数のタスクで同時に使用することとして理解できます)
5。デッドロックを防ぐためのロック障害メカニズム付き
6.ノンブロッキングロック機能付き、つまりロックは取得されませんロックの取得の失敗に直接戻ります

Q:
zookeeper1に基づく分散ロック。zookeeperの
いくつかの機能

順序付きノード:現在の親ノードが/ lockの場合、この親ノードの下に子ノードを作成できます。zookeeperはオプションの順序付き機能を提供します。たとえば、子ノード「/ lock / node-」を作成して順序を指定します。次に、zookeeperは、子ノードを生成するときに、子ノードの現在の数に応じて整数のシリアル番号を自動的に追加します。つまり、それが最初に作成された子ノードである場合、生成される子ノードは/ lock / node-0000000000です。ノードは/ lock / node-0000000001などです。

一時ノード:クライアントは一時ノードを確立できます。セッションが終了するか、セッションがタイムアウトすると、Zookeeperはノードを自動的に削除します。

イベントモニタリング:データを読み取るときに、ノードのイベントモニタリングを同時に設定できます。ノードのデータまたは構造が変更されると、zookeeperはクライアントに通知します。現在、zookeeperには次の4つのイベントがあります:
1。ノードの作成;
2。ノードの削除;
3。ノードデータの変更;
4。子ノードの変更。

2.実現
①クライアントはzookeeperに接続し、/ lockの下に一時的で整然とした子ノードを作成します。最初のクライアントは子ノード/ lock / lock-1に対応し、2番目は/ lock / lock-2というように続きます。
②クライアントは/ lockの下の子ノードリストを取得し、作成した子ノードが現在の子ノードリストの中でシーケンス番号が最も小さい子ノードであるかどうかを判断します。ロックされている場合はロックされていると見なし、そうでない場合は監視します。 / lockの子ノード変更メッセージで子ノードを取得します。ノード変更通知後、ロックが取得されるまでこの手順を繰り返します
。③ビジネスコードを実行します
。④ビジネスプロセス終了後、対応する子ノードを削除してロックを解除します。

Q:
キュレーターに基づくzookeeper分散ロックの実装

public static void main(String[] args) throws Exception {
    
    
        //创建zookeeper的客户端
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);

        CuratorFramework client = CuratorFrameworkFactory.newClient("10.21.41.181:2181,10.21.42.47:2181,10.21.49.252:2181", retryPolicy);

        client.start();

        //创建分布式锁, 锁空间的根节点路径为/curator/lock
        InterProcessMutex mutex = new InterProcessMutex(client, "/curator/lock");

        mutex.acquire();

        //获得了锁, 进行业务流程
        System.out.println("Enter mutex");

        //完成业务流程, 释放锁
        mutex.release();

        //关闭客户端
        client.close();

    }

Q:Redis
ベースの分散ロック
1.プロセス
1.ロックを取得するために、サービスAはRedisに対して次のコマンドを開始します。SETproductId:lock 0xx9p03001 NX PX 30000この中で、「productId」はそれ自体で定義され、関連付けることができます。このビジネスIDに対して、「0xx9p03001」はランダムな値の文字列であり、グローバルに一意である必要があります(理由は後で説明します)。「NX」は、キー(つまり、「productId:lock」ケース)はRedisにあります。存在しない場合、実行は成功します。存在しない場合、実行は失敗します。「PX30000」は、30秒後にキーが自動的に削除されることを意味します。コマンドの実行後に成功が返され、サービスがロックを正常に取得したことを示します。
2.ロックを取得するために、サービスBはRedisに対して同じコマンドを開始します。SETproductId:lock 0000111 NX PX 30000同じ名前のキーがRedisにすでに存在し、有効期限が切れていないため、コマンドの実行は失敗し、サービスBは失敗します。ロックを取得します。サービスBは、実行が成功してロックが取得されるまで、1秒ごとにRedisにリクエストを送信するなどの循環リクエスト状態に入ります(それ自体で設定されます)。
3.サービスAのビジネスコードの実行時間が30秒を超えると、キーがタイムアウトするため、Redisは自動的にキーを削除します。このとき、サービスBは、この要求で設定された値が0000222であると想定して、コマンドを再送信し、正常に実行されます。
4.サービスAの実行が完了した後、ロックを解除するために、サービスAはRedisへのキー削除要求をアクティブに開始します。

2.実現
①ロック
クライアントはRedissonを統合します。ロックする前に、まずハッシュアルゴリズムを使用してクラスター内のRedisマスターを選択する必要があります。後続のロックおよびロック解除プロセスはすべてこのRedisマスターに関連付けられています。スレーブノード間。②lua
スクリプトを実行してロックを実現します
。③
ウォッチドッグは自動的にウォッチドッグを拡張します。ウォッチドッグはバックグラウンドスレッドであり、現在のクライアントがロックを保持しているかどうかを10秒ごとに監視します。保持している場合、クライアントはロックを使用している可能性があります。ロックの残りの生存時間を延長します。
④ロックメカニズムを解除します。lock.unlock()を実行すると、Redisは上記のテストデータ構造を見つけ、ロックの数を1つ減らします。削減後にロックの数が0であることが判明した場合は、現在のクライアントがロックを保持していないことを意味するため、deltestコマンドを実行してこのキーをRedisから削除します。

// 准备为名为"test"的key加锁
RLock lock = redisson.getLock("test");
// 加锁
lock.lock();
// 解锁
lock.unlock();

このブログの公式アカウント:Muziネットワークサイドビジネス、交換に注意を払うことを歓迎します!

おすすめ

転載: blog.csdn.net/ncw8080/article/details/113879257