Redis用setnx+expire實現分布式鎖存在什么隱患,如何改進?


用Redis實現分布式鎖,2.6.12之前版本方案:setnx加鎖,del釋放鎖,如果鎖沒釋放,設置過期時間,到了時間,del釋放鎖。但是,這會存在一些問題。

  1. setnx和expire不是原子操作一旦redis宕機,expire沒有設置成功,鎖就無法釋放。只有一個請求的setnx可以成功,任何一個請求的expire都可以成功。請求比較密集,過期時間一直刷新,導致鎖一直有效。
  2. 超時后,刪除其他線程的鎖。在線程A執行過程中,鎖已釋放,A還未在執行業務,但是還未刪除鎖。線程B獲取鎖執行業務,線程A執行完,A誤刪B的鎖。
  3. 多個線程並發獲取鎖、釋放鎖。同一時間有線程A、B在訪問同一代碼塊。

對於上面的隱患,Redis已改善。下面,我們針對隱患逐一改善。

  1. Redis2.6.12以上版本,可以用set獲取鎖。set可以實現setnx和expire,這個是原子操作。
  2. Lua刪除鎖。Lua是原子操作。
  3. 讓獲取鎖的線程開啟一個守護線程,給線程還沒執行完,又快要過期的鎖續航。大概是這樣的,線程A還沒執行完,守護線程每當快過期時,延時expire時間。當線程A執行完,顯示關閉守護線程。如果中間宕機,鎖超過超時,守護線程也不在了,自動釋放鎖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM