日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redisson redlock(基于redisson框架和redis集群使用分布式锁)

發布時間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redisson redlock(基于redisson框架和redis集群使用分布式锁) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、關于分布式鎖的兩篇文章

文章1
文章2

二、redis分布式鎖存在的問題

redis實現分布式鎖有很多種方案,比較完善的方案應該是用setNx + lua進行實現。簡單實現如下:

  • java代碼-加鎖,相當于
set lock_key_name unique_value NX PX 5000;
  • lua腳本-解鎖,原子性操作
if redis.call("get", KEYS[1] == ARGV[1]) thenreturn redis.call("del", KEYS[1]) elsereturn 0 end
  • 解釋
  • NX:僅在不存在 key 的時候才能被執行成功;
  • PX:失效時間,傳入 30000,就是 30s 后自動釋放鎖;
  • unique_value:就是隨機值,可以是線程號之類的。主要是為了更安全的釋放鎖,釋放鎖的時候使用腳本告訴 Redis: 只有 key 存在并且存儲的值和我指定的值一樣才能刪除成功。
  • 為什么要設置隨機值:主要是為了防止鎖被其他客戶端刪除。
  • 客戶端 A 獲得了鎖,還沒有執行結束,但是鎖超時自動釋放了;
  • 客戶端 B 此時過來,是可以獲得鎖的,加鎖成功;
  • 此時,客戶端 A執行結束了,要去釋放鎖,如果不對比隨機值,就會把客戶端 B 的鎖給釋放了。
  • 當然前面看過 Redisson 的處理,這個unique_value存放的是 UUID:ThreadId 組合成的一個類似 931573de-903e-42fd-baa7-428ebb7eda80:1 的字符串。
  • 注意:

  • value需要具有唯一性,可以采用時間戳、uuid或者自增id實現;
  • 客戶端在解鎖時,需要比較本地內存中的value和redis中的value是否一致,防止誤解鎖;(case:clientA獲取鎖lock1,由于clientA執行的時間比較久,導致key=lock1已經過期,redis實例會移除該key;clientB獲取相同的鎖lock1,clientB正在占有鎖并執行業務,此時clientA業務已經執行完畢,準備釋放鎖;如果沒有比較value的邏輯,那么clientA會把clientB持有的鎖釋放掉,這個顯然不行的,由于value值不同,那么clientA釋放鎖的時候只會釋放自己加的鎖,不會誤釋放別的客戶端加的鎖)。
  • 注意,不能一味認為鎖過期的時間應該比key的expire要長,因為接下來要介紹的redisson框架中有續期機制(看門狗機制),該機制的核心就是:如果線程仍舊沒有執行完,那么redisson會自動給redis中的目標key延長超時時間

    在分布式系統中,為了避免單點故障,提高可靠性,redis都會采用主從架構,當主節點掛了后,從節點會作為主繼續提供服務。該種方案能夠滿足大多數的業務場景,但是對于要求強一致性的場景如交易,該種方案還是有漏洞的,原因如下:

  • redis主從架構采用的是異步復制,當master節點拿到了鎖,但是鎖還未同步到slave節點,此時master節點掛了,發生故障轉移,slave節點被選舉為master節點,丟失了鎖。這樣其他線程就能夠獲取到該鎖,顯然是有問題的。
  • 因此,上述基于redis實現的分布式鎖只是滿足了AP,并沒有滿足C。

    三、redlock

  • redlock出現的背景:當鎖遇到故障轉移
    單實例肯定不是很可靠吧?加鎖成功之后,結果 Redis 服務宕機了,就涼了。這時候會提出來將 Redis 主從部署。即使是主從,也是存在巧合的!
    • 主從結構中存在明顯的競態:
  • 客戶端 A 從 master 獲取到鎖
  • 在 master 將鎖同步到 slave 之前,master 宕掉了。
  • slave 節點被晉級為 master 節點
  • 客戶端 B 取得了同一個資源被客戶端 A 已經獲取到的另外一個鎖。安全失效!
  • 有時候程序就是這么巧,比如說正好一個節點掛掉的時候,多個客戶端同時取到了鎖。如果你可以接受這種小概率錯誤,那用這個基于復制的方案就完全沒有問題。

    • 如果使用集群呢

    我們知道對集群進行加鎖的時候,其實是通過 CRC16 的 hash 函數來對 key 進行取模,將結果路由到預先分配過 slot 的相應節點上。發現其實還是發到單個節點上的!

    • 正是因為上述redis分布式鎖存在的一致性問題,redis作者提出了一個更加高級的基于redis實現的分布式鎖——RedLock。原文可參考 Distributed locks with Redis,也可以參考這篇文章。
  • RedLock是什么
  • RedLock是基于redis實現的分布式鎖,它能夠保證以下特性:

    • 互斥性:在任何時候,只能有一個客戶端能夠持有鎖;
    • 避免死鎖:當客戶端拿到鎖后,即使發生了網絡分區或者客戶端宕機,也不會發生死鎖;(利用key的存活時間)
    • 容錯性:只要多數節點的redis實例正常運行,就能夠對外提供服務,加鎖或者釋放鎖;

    而非redLock是無法滿足互斥性的,上面已經闡述過了原因。

  • RedLock算法
  • 假設有N個redis的master節點,這些節點是相互獨立的(不需要主從或者其他協調的系統)。N推薦為奇數。具體算法如下:

    • 注意:為什么N推薦為奇數呢?
    • 原因1:本著最大容錯的情況下,占用服務資源最少的原則,2N+1和2N+2的容災能力是一樣的,所以采用2N+1;比如,5臺服務器允許2臺宕機,容錯性為2,6臺服務器也只能允許2臺宕機,容錯性也是2,因為要求超過半數節點存活才OK。

    • 原因2:假設有6個redis節點,client1和client2同時向redis實例獲取同一個鎖資源,那么可能發生的結果是——client1獲得了3把鎖,client2獲得了3把鎖,由于都沒有超過半數,那么client1和client2獲取鎖都失敗,對于奇數節點是不會存在這個問題。

    參考文章

  • 失敗時重試
    • 當客戶端無法獲取到鎖時,應該隨機延時后進行重試,防止多個客戶端在同一時間搶奪同一資源的鎖(會導致腦裂,最終都不能獲取到鎖)。客戶端獲得超過半數節點的鎖花費的時間越短,那么腦裂的概率就越低。所以,理想的情況下,客戶端最好能夠同時(并發)向所有redis發出set命令。

    • 當客戶端從多數節點獲取鎖失敗時,應該盡快釋放已經成功獲取的鎖,這樣其他客戶端不需要等待鎖過期后再獲取。(如果存在網絡分區,客戶端已經無法和redis進行通信,那么此時只能等待鎖過期后自動釋放)

    不明白為什么會發生腦裂???

  • 釋放鎖
  • 向所有redis實例發送釋放鎖命令即可,不需要關心redis實例有沒有成功上鎖。

    redisson在加鎖的時候,key=lockName, value=uuid + threadID,采用set結構存儲,并包含了上鎖的次數(支持可重入);解鎖的時候通過hexists判斷key和value是否存在,存在則解鎖;這里不會出現誤解鎖

  • 性能、 崩潰恢復和redis同步
    • 如何提升分布式鎖的性能?以每分鐘執行多少次acquire/release操作作為性能指標,一方面通過增加redis實例可用降低響應延遲,另一方面,使用非阻塞模型,一次發送所有的命令,然后異步讀取響應結果,這里假設客戶端和redis之間的RTT差不多。

    • 如果redis沒用使用備份,redis重啟后,那么會丟失鎖,導致多個客戶端都能獲取到鎖。通過AOF持久化可以緩解這個問題。redis key過期是unix時間戳,即便是redis重啟,那么時間依然是前進的。但是,如果是斷電呢?redis在啟動后,可能就會丟失這個key(在寫入或者還未寫入磁盤時斷電了,取決于fsync的配置),如果采用fsync=always,那么會極大影響性能。如何解決這個問題呢?可以讓redis節點重啟后,在一個TTL時間段內,對客戶端不可用即可。

    四、redlock已經在最新本的redisson中被棄用了

    看著 RedLock 好像是解決問題了:

  • 客戶端 A 鎖住了集群的大多數(一半以上);
  • 客戶端 B 也要鎖住大多數;
  • 這里肯定會沖突,所以 客戶端 B 加鎖失敗。
  • 那實際解決問題了么?推薦大家閱讀兩篇文章:

    • Martin Kleppmann:How to do distributed locking

    • Salvatore(Redis 作者):Is Redlock safe?

    最終,兩方各持己見,沒有得出結論。具體的源碼分析棄用原因,可以參考這篇文章

    五、結論

    Redisson RedLock 是基于聯鎖 MultiLock 實現的,但是使用過程中需要自己判斷 key 落在哪個節點上,對使用者不是很友好。Redisson RedLock 已經被棄用,直接使用普通的加鎖即可,會基于 wait 機制將鎖同步到從節點,但是也并不能保證一致性。僅僅是最大限度的保證一致性。

    基于MultiLock 實現的分布式鎖

    總結

    以上是生活随笔為你收集整理的redisson redlock(基于redisson框架和redis集群使用分布式锁)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美黄色a级片 | 欧美亚洲一级 | 高潮网| 91久久国语露脸精品国产高跟 | 国产精品久久久久久久9999 | 国产女人爽到高潮a毛片 | 中文字幕免费在线 | 久久久久久久久久国产精品 | 色乱码一区二区三区熟女 | 精品人妻aV中文字幕乱码色欲 | 久久国产影院 | 无遮挡裸光屁屁打屁股男男 | 国产欧美日韩视频 | 亚洲精品久久久久久 | 黄色在线网站 | 激情久久五月天 | 亚洲天堂网一区 | h在线网站| 中日韩av电影| 黑料视频在线 | 国产一区二区免费电影 | 日韩精品人妻一区二区中文字幕 | 亚洲乱码在线 | 无码人妻精品一区二区三区温州 | 姑娘第5集高清在线观看 | 中文字幕二区 | 亚欧成人精品 | 日操夜操天天操 | 香港三级日本三级 | 日韩欧美在线一区二区三区 | 成人免费毛片高清视频 | 国产一区二区三区视频免费在线观看 | 亚洲精品成a人在线观看 | 免费成年人视频在线观看 | 91亚洲天堂 | 亚洲女同av | 美日韩一级| 欧美精品一卡二卡 | 亚洲88| 国产精品入口久久 | 精品丰满人妻无套内射 | 国产精品第十页 | 亚洲国产成人在线视频 | 日本不卡视频一区二区三区 | 日韩视频在线免费 | 天天干,天天爽 | 两根大肉大捧一进一出好爽视频 | 人妻aⅴ无码一区二区三区 阿v免费视频 | 欧美日韩在线免费观看视频 | 国产大尺度视频 | 欧美女人交配视频 | 欧美一级性生活 | 91在线精品入口 | 亚洲欧美日韩电影 | 1024金沙人妻一区二区三区 | a级片在线免费看 | 豆花视频在线播放 | 日本xxxx色| 欧美日韩国产精品一区 | 日韩在线电影一区 | 三女警花合力承欢猎艳都市h | 亚洲色图偷拍视频 | 波多野结衣一区二区三区高清 | 这里只有精品22 | 亚洲一二三精品 | 欧美精品123区 | 久久久一本 | 国产成人在线电影 | 蝌蚪av| 91九色国产视频 | 黄色av片三级三级三级免费看 | 中文字幕1页 | 久久久久久久久久久久久久久久久久久 | 在线欧美 | 边吃奶边添下面好爽 | 中文字幕在线看片 | 亚洲卡一卡二卡三 | 蜜桃久久av一区 | 亚洲国产在 | 午夜国产片 | 又大又长粗又爽又黄少妇视频 | 亚洲国产av一区 | 久久久久久97 | 国产黄色视屏 | 午夜福利视频合集1000 | 欧洲精品在线播放 | 东北少妇不带套对白 | 免费成人福利视频 | 日本久久一区 | 黄色网入口 | 在线观看亚洲天堂 | a视频免费看 | 亚洲va欧美va国产综合久久 | 午夜蜜桃视频 | 天天干天天弄 | 淫羞阁av导航| 国产精品人人妻人人爽人人牛 | 精品人妻无码在线 | 一区二区成人在线观看 |