redis分佈式鎖

7. redis的分佈式鎖

7.1 鎖的處理:

  • 單應用中使用鎖: (單進程多線程)
<code>synchronize, ReentrantLo/<code>
  • 分佈式應用中使用鎖: (多進程多線程)

分佈式鎖是控制分佈式系統之間同步訪問共享資源的一種方式

7.2 分佈式鎖的實現方式

  • 基於數據庫的樂觀鎖實現分佈式鎖
  • 基於zookeeper的臨時節點實現分佈式鎖
  • 基於redis的分佈式鎖

7.3 實現分佈式鎖

  • 獲取鎖:

在set命令中, 有很多選項可以用來修改命令的行為, 以下是set命令可用選項的基本語法

<code>redis 127.0.0.1:6379>SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]

- EX seconds 設置指定的到期時間(單位為秒)
- PX milliseconds 設置指定的到期時間(單位毫秒)

- NX: 僅在鍵不存在時設置鍵
- XX: 只有在鍵已存在時設置/<code>

方式1: 推介

<code>   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";

public static boolean getLock(JedisCluster jedisCluster, String lockKey, String requestId, int expireTime) {
       // NX: 保證互斥性
       String result = jedisCluster.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
       if (LOCK_SUCCESS.equals(result)) {
           return true;
      }
       return false;
  }/<code>

方式2:

<code>public static boolean getLock(String lockKey,String requestId,int expireTime) {
    Long result = jedis.setnx(lockKey, requestId);
    if(result == 1) {
        jedis.expire(lockKey, expireTime);
        return true;
    }
    return false;
}/<code>

注意: 推介方式1, 因為方式2中setnx和expire是兩個操作, 並不是一個原子操作, 如果setnx出現問題, 就是出現死鎖的情況, 所以推薦方式1

  • 釋放鎖:

del命令實現

<code>public static void releaseLock(String lockKey,String requestId) {
   if (requestId.equals(jedis.get(lockKey))) {
       jedis.del(lockKey);
  }
}

/<code>


分享到:


相關文章: