Redis入門(七):Redis分佈式鎖(單機模式/集羣模式)

Redis 實現分佈式鎖

單機模式的Redis分佈式鎖

  • 優缺點
    • 實現比較輕,大多數時候能滿足需求;因爲是單機單實例部署,如果redis服務宕機,那麼所有需要獲取分佈式鎖的地方均無法獲取鎖,將全部阻塞,需要做好降級處理。
    • 當鎖過期後,執行任務的進程還沒有執行完,但是鎖因爲自動過期已經解鎖,可能被其它進程重新加鎖,這就造成多個進程同時獲取到了鎖,這需要額外的方案來解決這種問題。
  • 實現代碼
      import redis.clients.jedis.Jedis;
      import java.util.Collections;
    
      public class JedisDistributedLock {
    
          private static final String LOCK_SUCCESS = "OK";
          private static final Long RELEASE_SUCCESS = 1L;
    
          private static final String SET_IF_NOT_EXIST = "NX";
          private static final String SET_WITH_EXPIRE_TIME = "PX";
    
          // 獲取鎖,不設置超時時間
          public static boolean getLock(Jedis jedis, String lockKey, String requestId){
              String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST);
              if(LOCK_SUCCESS.equals(result)){
                  return true;
              }
              return false;
          }
    
          // 獲取鎖, 設置超時時間,單位爲毫秒
          public static boolean getLock(Jedis jedis, String lockKey, String requestId, Long expireTime){
    
              /**
              * jedis.set(key, value, nxxx, expx, time)
              *
              * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
              * GB).
              * @param key
              * @param value
              * @param NXXX NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key if it already exist.
              * @param EXPX EX|PX, expire time units: EX = seconds; PX = milliseconds
              *
              * @return Status code reply set成功,返回 OK
              */
              String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
              if(LOCK_SUCCESS.equals(result)){
                  return true;
              }
              return false;
          }
    
          //釋放鎖
          public static boolean releaseLock(Jedis jedis, String lockKey, String requestId){
    
              // Lua腳本
              String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
              Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
              if(RELEASE_SUCCESS.equals(result)){
                  return true;
              }
              return false;
          }
      }
    

集羣模式的Redis分佈式鎖 Redlock

  • 優缺點

    • Redlock是Redis的作者antirez給出的集羣模式的Redis分佈式鎖,它基於N個完全獨立的Redis節點
    • 部分節點宕機,依然可以保證鎖的可用性
    • 當某個節點宕機後,又立即重啓了,可能會出現兩個客戶端同時持有同一把鎖,如果節點設置了持久化,出現這種情況的機率會降低
    • 和單機模式Redis鎖相比,實現難度要大一些
  • 實現代碼

    • 搭建redis集羣
    # 安裝指定版本的redis
    cd /opt
    wget http://download.redis.io/releases/redis-3.2.8.tar.gz
    tar xzf redis-3.2.8.tar.gz && rm redis-3.2.8.tar.gz
    cd redis-3.2.8
    make
    
    # 構建redis集羣
    cd
    mkdir cluster-test
    cd cluster-test
    mkdir conf logs bin
    # 拷貝客戶端服務器文件
    rsync -avp /opt/redis-3.2.8/src/redis-server bin/
    rsync -avp /opt/redis-3.2.8/src/redis-cli bin/
    # 配置文件
    for i in 7000 7001 7002 7003 7004 7005; do
    cat << EOF > conf/${i}.conf
    port ${i}
    cluster-enabled yes
    cluster-config-file nodes-${i}.conf
    cluster-node-timeout 5000
    appendonly yes
    logfile "logs/${i}.log"
    appendfilename "appendonly-${i}.aof"
    EOF
    done
    # 啓動
    cd ${HOME}/cluster-test
    for i in 7000 7001 7002 7003 7004 7005; do
    ./bin/redis-server ./conf/${i}.conf &
    done
    # 創建集羣
    sudo apt-get install -y ruby rubygems
    gem install redis
    cd /opt/redis-3.2.8/src/
    ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
    # 測試
    cd ${HOME}/cluster-test/
    ./bin/redis-cli -c -p 7000 cluser nodes
    # 停止
    #cd ${HOME}/cluster-test
    #for i in 7000 7001 7002 7003 7004 7005; do
    #./bin/redis-cli -p ${i} shutdown && echo "redis ${i} 已停止"
    #done
    

    腳本執行後,出現如下日誌,說明集羣搭建成功

    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    127.0.0.1:7000
    127.0.0.1:7001
    127.0.0.1:7002
    Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
    M: d0e3588845a839052d9e611853740edd3b348966 127.0.0.1:7000
    slots:0-5460 (5461 slots) master
    M: 4f5518e78c1ea1c25bab0d0147f12c0281fd5f96 127.0.0.1:7001
    slots:5461-10922 (5462 slots) master
    M: 5724fb03c4527389be0d556c5dc5419a12d367c5 127.0.0.1:7002
    slots:10923-16383 (5461 slots) master
    S: 1206f7a76b8050b10e2e602fad422faee95efdb5 127.0.0.1:7003
    replicates d0e3588845a839052d9e611853740edd3b348966
    S: 8f421f529c86cefbf033e1e3a1687a9767802bd2 127.0.0.1:7004
    replicates 4f5518e78c1ea1c25bab0d0147f12c0281fd5f96
    S: d94710251235efde7da4073cc4ff104d9298bd0f 127.0.0.1:7005
    replicates 5724fb03c4527389be0d556c5dc5419a12d367c5
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join...
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: d0e3588845a839052d9e611853740edd3b348966 127.0.0.1:7000
    slots:0-5460 (5461 slots) master
    1 additional replica(s)
    S: 8f421f529c86cefbf033e1e3a1687a9767802bd2 127.0.0.1:7004
    slots: (0 slots) slave
    replicates 4f5518e78c1ea1c25bab0d0147f12c0281fd5f96
    S: 1206f7a76b8050b10e2e602fad422faee95efdb5 127.0.0.1:7003
    slots: (0 slots) slave
    replicates d0e3588845a839052d9e611853740edd3b348966
    M: 4f5518e78c1ea1c25bab0d0147f12c0281fd5f96 127.0.0.1:7001
    slots:5461-10922 (5462 slots) master
    1 additional replica(s)
    S: d94710251235efde7da4073cc4ff104d9298bd0f 127.0.0.1:7005
    slots: (0 slots) slave
    replicates 5724fb03c4527389be0d556c5dc5419a12d367c5
    M: 5724fb03c4527389be0d556c5dc5419a12d367c5 127.0.0.1:7002
    slots:10923-16383 (5461 slots) master
    1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
    • redis-cluster簡單集羣示例圖
      Redis rdbs
    • 使用Redission構建redLock

           Redis集羣使用分片的方式保存鍵值對,redis-cluster採用slot(槽)的概念,一共16384個槽位,分佈在集羣中的所有master實例上。保存數據時,直接對key值做CRC16校驗後得到的校驗值對16384取模,將鍵值對存儲到對應的槽位所在的實例上。

    import org.redisson.Redisson;
    import org.redisson.api.RAtomicLong;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    
    /**
    * Created by Haiyoung on 2018/8/11.
    */
    public class RedissonManager {
    
        private static final String RAtomicName = "genId_";
    
        private static Config config = new Config();
    
        private static RedissonClient redisson = null;
    
        public static void init(){
            try{
                config.useClusterServers()
                        .setScanInterval(200000)//設置集羣狀態掃描間隔
                        .setMasterConnectionPoolSize(10000)//設置對於master節點的連接池中連接數最大爲10000
                        .setSlaveConnectionPoolSize(10000)//設置對於slave節點的連接池中連接數最大爲500
                        .setIdleConnectionTimeout(10000)//如果當前連接池裏的連接數量超過了最小空閒連接數,而同時有連接空閒時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單位是毫秒。
                        .setConnectTimeout(30000)//同任何節點建立連接時的等待超時。時間單位是毫秒。
                        .setTimeout(3000)//等待節點回覆命令的時間。該時間從命令發送成功時開始計時。
                        .setRetryInterval(3000)//當與某個節點的連接斷開時,等待與其重新建立連接的時間間隔。時間單位是毫秒。
                        .addNodeAddress("redis://127.0.0.1:7000","redis://127.0.0.1:7001","redis://127.0.0.1:7002","redis://127.0.0.1:7003","redis://127.0.0.1:7004","redis://127.0.0.1:7005");
                redisson = Redisson.create(config);
    
                RAtomicLong atomicLong = redisson.getAtomicLong(RAtomicName);
                atomicLong.set(1);//自增設置爲從1開始
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        public static RedissonClient getRedisson(){
            if(redisson == null){
                RedissonManager.init(); //初始化
            }
            return redisson;
        }
    
        /** 獲取redis中的原子ID */
        public static Long nextID(){
            RAtomicLong atomicLong = getRedisson().getAtomicLong(RAtomicName);
            atomicLong.incrementAndGet();
            return atomicLong.get();
        }
    }
    
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    
    import java.util.concurrent.TimeUnit;
    
    /**
    * Created by Haiyoung on 2018/8/11.
    */
    public class DistributedRedisLock {
    
        private static RedissonClient redisson = RedissonManager.getRedisson();
        private static final String LOCK_TITLE = "redisLock_";
    
        public static void acquire(String lockName){
            String key = LOCK_TITLE + lockName;
            RLock mylock = redisson.getLock(key);
            mylock.lock(2, TimeUnit.MINUTES); //lock提供帶timeout參數,timeout結束強制解鎖,防止死鎖
            System.err.println("======lock======"+Thread.currentThread().getName());
        }
    
        public static void release(String lockName){
            String key = LOCK_TITLE + lockName;
            RLock mylock = redisson.getLock(key);
            mylock.unlock();
            System.err.println("======unlock======"+Thread.currentThread().getName());
        }
    
        public static void main(String[] args){
            for (int i = 0; i < 3; i++) {
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            String key = "test123";
                            DistributedRedisLock.acquire(key);
                            Thread.sleep(1000); //獲得鎖之後可以進行相應的處理
                            System.err.println("======獲得鎖後進行相應的操作======");
                            DistributedRedisLock.release(key);
                            System.err.println("=============================");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
                t.start();
            }
        }
    }
    

    執行main函數,進行測試:

    //建立的集羣關係如下所示:
    //可以看到集羣關係以及槽位分配信息
    12:41:14.749 [redisson-netty-1-7] DEBUG org.redisson.cluster.ClusterConnectionManager - cluster nodes state from 127.0.0.1/127.0.0.1:7001:
    d0e3588845a839052d9e611853740edd3b348966 127.0.0.1:7000 master - 0 1539319273461 1 connected 0-5460
    d94710251235efde7da4073cc4ff104d9298bd0f 127.0.0.1:7005 slave 5724fb03c4527389be0d556c5dc5419a12d367c5 0 1539319273963 6 connected
    5724fb03c4527389be0d556c5dc5419a12d367c5 127.0.0.1:7002 master - 0 1539319274465 3 connected 10923-16383
    8f421f529c86cefbf033e1e3a1687a9767802bd2 127.0.0.1:7004 slave 4f5518e78c1ea1c25bab0d0147f12c0281fd5f96 0 1539319272458 5 connected
    1206f7a76b8050b10e2e602fad422faee95efdb5 127.0.0.1:7003 slave d0e3588845a839052d9e611853740edd3b348966 0 1539319272961 4 connected
    4f5518e78c1ea1c25bab0d0147f12c0281fd5f96 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
    
    //加鎖解鎖過程
    ======lock======Thread-2
    10:27:50.086 [redisson-netty-1-6] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=1, freeSubscribeConnectionsCounter=50, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@788625756 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x9109c84f, L:/127.0.0.1:49276 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:50.096 [Thread-1] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:50.102 [redisson-netty-1-6] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@615544583 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x088086f4, L:/127.0.0.1:49194 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:50.120 [Thread-1] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:50.120 [Thread-3] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:50.121 [Thread-1] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@1475932758 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x37cce38a, L:/127.0.0.1:49230 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:50.121 [Thread-3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=30, freeConnectionsCounter=9998, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@1231431314 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xea1b90d2, L:/127.0.0.1:49286 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:50.126 [redisson-netty-1-1] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1475932758 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x37cce38a, L:/127.0.0.1:49230 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:50.127 [redisson-netty-1-1] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1231431314 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xea1b90d2, L:/127.0.0.1:49286 - R:127.0.0.1/127.0.0.1:7002]]
    ======獲得鎖後進行相應的操作======
    10:27:51.081 [Thread-2] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:51.082 [Thread-2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, redisLock_test123, redisson_lock__channel:{redisLock_test123}, 0, 30000, 20e96666-d967-4d3c-ac94-abeb14493160:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@697105324 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x3b2eb2ff, L:/127.0.0.1:49244 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:51.086 [redisson-netty-1-5] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, redisLock_test123, redisson_lock__channel:{redisLock_test123}, 0, 30000, 20e96666-d967-4d3c-ac94-abeb14493160:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@697105324 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x3b2eb2ff, L:/127.0.0.1:49244 - R:127.0.0.1/127.0.0.1:7002]]
    ======unlock======Thread-2
    =============================
    10:27:51.090 [Thread-1] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:51.090 [Thread-3] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:51.091 [Thread-1] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=30, freeConnectionsCounter=9998, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@489743733 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xc2cb57a1, L:/127.0.0.1:49204 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:51.091 [Thread-3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=30, freeConnectionsCounter=9998, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@562253068 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x69c6d83a, L:/127.0.0.1:49260 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:51.095 [redisson-netty-1-1] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@562253068 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x69c6d83a, L:/127.0.0.1:49260 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:51.096 [redisson-netty-1-6] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@489743733 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xc2cb57a1, L:/127.0.0.1:49204 - R:127.0.0.1/127.0.0.1:7002]]
    ======lock======Thread-1
    ======獲得鎖後進行相應的操作======
    10:27:52.102 [Thread-1] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:52.103 [Thread-1] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, redisLock_test123, redisson_lock__channel:{redisLock_test123}, 0, 30000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@2085319794 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x7b0b77c0, L:/127.0.0.1:49250 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:52.107 [redisson-netty-1-5] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, redisLock_test123, redisson_lock__channel:{redisLock_test123}, 0, 30000, 20e96666-d967-4d3c-ac94-abeb14493160:20] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@2085319794 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x7b0b77c0, L:/127.0.0.1:49250 - R:127.0.0.1/127.0.0.1:7002]]
    ======unlock======Thread-1
    =============================
    10:27:52.111 [Thread-3] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    10:27:52.112 [Thread-3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@1360268292 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xe28d264d, L:/127.0.0.1:49406 - R:127.0.0.1/127.0.0.1:7002]]
    10:27:52.115 [redisson-netty-1-7] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);, 1, redisLock_test123, 120000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=10000, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1360268292 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0xe28d264d, L:/127.0.0.1:49406 - R:127.0.0.1/127.0.0.1:7002]]
    ======lock======Thread-3
    10:27:53.120 [Thread-3] DEBUG org.redisson.cluster.ClusterConnectionManager - slot 12809 for redisLock_test123
    ======獲得鎖後進行相應的操作======
    10:27:53.121 [Thread-3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, redisLock_test123, redisson_lock__channel:{redisLock_test123}, 0, 30000, 20e96666-d967-4d3c-ac94-abeb14493160:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=9999, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:7002], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:7002... RedisConnection@1735465853 [redisClient=[addr=redis://127.0.0.1:7002], channel=[id: 0x669d66fa, L:/127.0.0.1:49254 - R:127.0.0.1/127.0.0.1:7002]]
    ======unlock======Thread-3
    =============================
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章