首頁 > 資料庫 > Redis > 主體

redis如何實現分散式鎖

(*-*)浩
發布: 2019-11-27 10:33:04
原創
4150 人瀏覽過

redis如何實現分散式鎖

分散式鎖定需要解決的問題

#互斥性:任意時刻只能有一個客戶端擁有鎖,不能同時多個客戶端取得

安全性:鎖定只能被持有該鎖定的使用者刪除,而無法被其他使用者刪除       (建議學習: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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!