redis如何實(shí)現(xiàn)分布式鎖

redis如何實(shí)現(xiàn)分布式鎖

分布式鎖需要解決的問題

互斥性:任意時(shí)刻只能有一個(gè)客戶端擁有鎖,不能同時(shí)多個(gè)客戶端獲取

安全性:鎖只能被持有該鎖的用戶刪除,而不能被其他用戶刪除? ? ? ?(推薦學(xué)習(xí):Redis視頻教程

死鎖:獲取鎖的客戶端因?yàn)槟承┰蚨礄C(jī),而未能釋放鎖,其他客戶端無法獲取此鎖,需要有機(jī)制來避免該類問題的發(fā)生

容錯(cuò):當(dāng)部分節(jié)點(diǎn)宕機(jī),客戶端仍能獲取鎖或者釋放鎖

如何通過redis實(shí)現(xiàn)分布式鎖:(非完善方法)

SETNX key value :如果key不存在,則創(chuàng)建并賦值

時(shí)間復(fù)雜度: 0(1)

返回值:設(shè)置成功,返回1;設(shè)置失敗,返回0。

但是此時(shí)我們獲取的key是長期有效的,所以我們應(yīng)該如何解決長期有效的問題呢?

EXPIRE key seconds

設(shè)置key的生存時(shí)間,當(dāng)key過期時(shí)(生存時(shí)間為0) ,會(huì)被自動(dòng)刪除

缺點(diǎn):原子性得不到滿足

下面是偽代碼

//該程序存在危險(xiǎn),如果執(zhí)行到第二行就崩潰了,則此時(shí)key會(huì)被一直占用而無法被釋放 RedisService?redisService?=?SpringUtils.getBean(Redi?sService.class);? long?status?=?redisService.setnx(key,?"1"); if(status?==?1)?{ 	redisService.expire(key,?expire); 	//執(zhí)行獨(dú)占資源邏輯 	doOcuppiedWork(); }

如何通過Redis實(shí)現(xiàn)分布式鎖:(正確方式)

SET?key?value?[EX?seconds]?[PX?milliseconds]?[NX|XX]

EX second :設(shè)置鍵的過期時(shí)間為second秒

PX millisecond :設(shè)置鍵的過期時(shí)間為millisecond毫秒

NX :只在鍵不存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作

XX:只在鍵已經(jīng)存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作

SET操作成功完成時(shí),返回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))?{ 	//執(zhí)行獨(dú)占資源邏輯 	doOcuppiedWork(); }

大量的key同時(shí)過期的注意事項(xiàng)

集中過期,由于清除大量的key很耗時(shí),會(huì)出現(xiàn)短暫的卡頓現(xiàn)象

解放方案:在設(shè)置key的過期時(shí)間的時(shí)候,給每個(gè)key加上隨機(jī)值

更多Redis相關(guān)技術(shù)文章,請(qǐng)?jiān)L問Redis視頻教程欄目進(jìn)行學(xué)習(xí)!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊5 分享