Redis分散ロックの実装

5080 ワード

前言


分散ロックには一般的に3つの実現方式がある:1.データベース楽観ロック;2.Redisベースの分散ロック;3.ZooKeeperベースの分散ロック.このブログでは、Redisに基づいて分散ロックを実現する第2の方法について説明します.このブログでは、Redis分散ロックの実装について様々なブログが紹介されていますが、彼らの実装には様々な問題があり、子弟の誤解を避けるために、Redis分散ロックを正しく実装する方法について詳しく説明します.

しんらいせい


まず、分散ロックが使用可能であることを確認するために、少なくともロックの実装が以下の4つの条件を満たしていることを確認します.
反発性任意の時点で、ロックを保持できるクライアントは1つしかありません.
デッドロックは発生しません.ロックを保持している間にクラッシュし、アクティブにロックを解除しなくても、後続の他のクライアントがロックを追加できることを保証します.
許容誤差がある.ほとんどのRedisノードが正常に動作している限り、クライアントはロックとロック解除を行うことができます.
ベルを解くにはベルを結ぶ人が必要だ.ロックとロック解除は同じクライアントでなければなりません.クライアントは自分で他の人のロックを解除することはできません.

コード実装


コンポーネント依存


まず、Mavenを通じてJedisオープンソースコンポーネントをpomに導入します.xmlファイルには、次のコードが追加されます.
1
2
3
4
5      redis.clients      jedis      2.9 . 0

ロックコード


しい
Talk is cheap, show me the code.まずコードを し、なぜこのように されたのかをゆっくり します.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class RedisTool {
       private static final String LOCK_SUCCESS = "OK" ;      private static final String SET_IF_NOT_EXIST = "NX" ;      private static final String SET_WITH_EXPIRE_TIME = "PX" ;
       /**       *       * @param jedis Redis       * @param lockKey       * @param requestId       * @param expireTime       * @return       */      public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
           String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
           if (LOCK_SUCCESS.equals(result)) {              return true ;          }          return false ;
       }
  }
ロックをかけるとコードが1 されますset(String key,String value,String nxxx,String expx,int time)、このset()メソッドには5つのパラメータがあります.
1つ はkeyです. たちはkeyをロックとして します.keyは だからです.
2つ はvalueです. たちが えているのはrequestIdです. くの が からないかもしれませんが、keyが としてあれば ではないでしょうか.どうしてvalueを うのですか.なぜなら, について した , ロックが4 の を たすにはベルを す があり,valueにrequestIdを することで,このロックがどのリクエストに えられたのか,ロックを する に があるからである.requestIdはUUIDを することができる.randomUUID().toString()メソッドが されます.
3つ はnxxxです.このパラメータはNXです.SET IF NOT EXISTを します.つまり、keyが しない 、set を います.keyがすでに する 、 もしません.
4 はexpxで、このパラメータはPXを えています.これは たちがこのkeyに れの を することを しています. な は5 のパラメータによって まります.
5 はtimeで、4 のパラメータに してkeyの れを します.
じて、 のset()メソッドを すると、2つの しか られません:1. ロックが しない(keyが しない) は、ロック を い、ロックに を し、valueはロックされたクライアントを します.2.ロックは に し、 もしない.