Redis實現分布式鎖

2021-10-08 11:57:06 字數 3090 閱讀 5904

初始:實現redis中庫存資料-1的基本邏輯 

@restcontroller

public class dislockcontroller else

return "end";}}

問題:單程序多執行緒下出現併發問題

演進一:加synchronized同步鎖,避免了單程序多執行緒下併發錯誤

關鍵**:synchronized (this){}

@restcontroller

public class dislockcontroller else

}return "end";}}

問題:集群下,多程序下的多執行緒併發問題

演進二:

1、採用redis的setnx方法,只有key不存在,才能設定值

2、當處理完後,del掉該key,其他執行緒可獲得分布式鎖執行

關鍵**:

// redis分布式鎖

boolean result = stringredistemplate.opsforvalue().setifabsent("lockkey", "zhuge");

if(!result)

@restcontroller

public class dislockcontroller

int stock = integer.parseint(stringredistemplate.opsforvalue().get("stock"));

if(stock > 0)else

stringredistemplate.delete("lockkey");

return "end";}}

問題:如果某執行緒加鎖後,還沒釋放鎖,**出現問題,則鎖永遠不會被釋放,其他執行緒無法進行

演進三:加try-finally**塊,保證**出現問題,鎖也會釋放

關鍵**:try{}finally {}

@restcontroller

public class dislockcontroller

int stock = integer.parseint(stringredistemplate.opsforvalue().get("stock"));

if(stock > 0)else

}finally

return "end";}}

問題:如果機器宕機了,則不會執行finally**內容,鎖不會釋放,其他集群執行緒也無法進行

演進四:給鎖設定超時時間,集群宕機了,redis設定key-value超時了,則自動刪除了,不會導致其他集群執行緒

關鍵**:

boolean result = stringredistemplate.opsforvalue().setifabsent("lockkey", clientid, 10, timeunit.seconds);

@restcontroller

public class dislockcontroller

int stock = integer.parseint(stringredistemplate.opsforvalue().get("stock"));

if(stock > 0)else

}finally

return "end";}}

問題:如果a執行緒給鎖設定10秒,可是a執行緒邏輯10秒內都沒執行完,b執行緒設定鎖,a執行完邏輯後,把b的鎖給刪掉了

演進五:在del釋放鎖之前做乙個判斷,驗證當前的鎖是不是自己加的鎖,是才刪除

關鍵**:value設定為uuid,執行緒a設定的鎖,只有a能刪除......

string clientid = uuid.randomuuid().tostring();

boolean result = stringredistemplate.opsforvalue().setifabsent("lockkey", clientid, 10, timeunit.seconds);

if(clientid.equals(stringredistemplate.opsforvalue().get("lockkey")))

@restcontroller

public class dislockcontroller

int stock = integer.parseint(stringredistemplate.opsforvalue().get("stock"));

if(stock > 0)else

}finally

}return "end";}}

問題:上面只是保證了a只能刪a,b只能刪b...,但是當a邏輯沒執行完,b拿到鎖,就可以執行和a同樣的邏輯,就會造成資料不一致

演進六(最終版):採用redission watch dog 自動延期機制,客戶端 1一旦加鎖成功,就會啟動乙個 watch dog 看門狗,是乙個後台執行緒,會每隔 10 秒檢查一下,如果客戶端還持有鎖 key,那麼就會不斷的延長鎖 key 的生存時間

關鍵**:

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

redis實現分布式鎖

隨便 系統越來越大,各功能模組除了垂直切割以外,同時也得做集群處理,那麼問題來了,在多執行緒情況下對於資源的競爭就需要乙個統一的訪問限制。以選課系統為例子,集群中各節點對課程可選數量同時操作,這裡就需要同步了,否則會導致最後選到的數量比可選的數量大,這裡我們的分布式鎖就派上用場了。利用redis來實...

redis實現分布式鎖

分布式鎖可以基於很多種方式實現,比如zookeeper redis.不管哪種方式,他的 基本原理是不變的 用乙個狀態值表示鎖,對鎖的占用和釋放通過狀態值來標識。1 使用redis的setnx命令實現分布式鎖 1 實現的原理 redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多客戶...