redis分佈式鎖踩坑實踐

Redis

版本一: redis判斷是否有值,沒有加值
導致問題:1、加鎖不是個原子操作2、若加鎖後宕機,系統死鎖

版本二: redis加鎖原子性操作(setnx),鎖加過期時間
導致問題:1、若設置過期時間2s,程序執行3s,釋放了別人的鎖

版本三: redis加鎖上放一個隨機值,然後判斷隨機值刪除鎖
導致問題:1、刪除是不是一個原子操作,也會出現刪除別人的鎖的情況

版本四: redis刪除鎖通過lua腳本實現(判斷相等在刪除)
遺留問題:以上問題都是針對單節點而言,實際生產都是redis集羣,redis主從複製是異步的.

數據庫

數據庫主庫和從庫不一致,常見有這麼幾種優化方案:

(1)業務可以接受,系統不優化

(2)強制讀主,高可用主庫,用緩存提高讀性能

(3)在cache裏記錄哪些記錄發生過寫請求,來路由讀主還是讀從

說到這裏,來說一下最佳解決方案,也是redis官方推薦Redisson

Config config = new Config();
config.useClusterServers()
    .addNodeAddress("redis://192.168.31.101:7001")
    .addNodeAddress("redis://192.168.31.101:7002")

    .addNodeAddress("redis://192.168.31.101:7003")

    .addNodeAddress("redis://192.168.31.102:7001")

    .addNodeAddress("redis://192.168.31.102:7002")

    .addNodeAddress("redis://192.168.31.102:7003");

RedissonClient redisson = Redisson.create(config);

RLock lock = redisson.getLock("anyLock");

lock.lock();

lock.unlock();

就是這麼簡單,我們只需要通過它的api中的lock和unlock即可完成分佈式鎖,他幫我們考慮了很多細節:

  • redisson所有指令都通過lua腳本執行,redis支持lua腳本原子性執行
  • redisson設置一個key的默認過期時間爲30s,如果某個客戶端持有一個鎖超過了30s怎麼辦?
  • redisson中有一個watchdog的概念,翻譯過來就是看門狗,它會在你獲取鎖之後,每隔10秒幫你把key的超時時間設爲30s
  • 這樣的話,就算一直持有鎖也不會出現key過期了,其他線程獲取到鎖的問題了。
  • redisson的“看門狗”邏輯保證了沒有死鎖發生。

(如果機器宕機了,看門狗也就沒了。此時就不會延長key的過期時間,到了30s之後就會自動過期了,其他線程可以獲取到鎖)

下面文章寫的不錯,在此記錄一下
https://baijiahao.baidu.com/s?id=1623086259657780069&wfr=spider&for=pc&isFailFlag=1
https://blog.csdn.net/john1337/article/details/98850192
http://blog.itpub.net/29715045/viewspace-2650976/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章