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>
閱讀更多 故事凌 的文章