分散式鎖定需要解決的問題
#互斥性:任意時刻只能有一個客戶端擁有鎖,不能同時多個客戶端取得
安全性:鎖定只能被持有該鎖定的使用者刪除,而無法被其他使用者刪除 (建議學習:Redis影片教學)
)
死鎖:取得鎖的客戶端因為某些原因而宕機,而未能釋放鎖,其他客戶端無法取得此鎖,需要有機制來避免該類別問題的發生
容錯:當部分節點宕機,客戶端仍能取得鎖定或釋放鎖定
如何透過Redis實作分散式鎖定:(非完善方法)##SETNX key value :
如果key不存在,則建立並賦值時間複雜度: 0(1)傳回值:設定成功,回傳1;設定失敗,回傳0。但是此時我們取得的key是長期有效的,所以我們該如何解決長期有效的問題呢?
EXPIRE key seconds
設定key的生存時間,當key過期時(生存時間為0) ,會被自動刪除 #缺點:原子性無法滿足下面是偽代碼
//该程序存在危险,如果执行到第二行就崩溃了,则此时key会被一直占用而无法被释放 RedisService redisService = SpringUtils.getBean(Redi sService.class); long status = redisService.setnx(key, "1"); if(status == 1) { redisService.expire(key, expire); //执行独占资源逻辑 doOcuppiedWork(); }如何透過Redis實作分散式鎖定:(正確方式)
SET key value [EX seconds] [PX milliseconds] [NX|XX]EX second :設定鍵的過期時間為second秒PX millisecond :設定鍵的過期時間為millisecond毫秒#NX :只有在鍵不存在時,才對鍵進行設定操作XX:只在鍵已經存在時才對鍵進行設定操作#SET操作成功完成時,返回OK ,否則回傳nil
下面是偽代碼
RedisService redisService = SpringUtils.getBean(RedisService.class); . String result = redisService.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if ("OK".equals(result)) { //执行独占资源逻辑 doOcuppiedWork(); }大量的key同時過期的注意事項 集中過期,由於清除大量的key很耗時,會出現短暫的卡頓現象解放方案:在設定key的過期時間的時候,給每個key加上隨機值
更多Redis相關技術文章,請訪問Redis入門教學
欄位進行學習! ###以上是redis如何實現分散式鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!