Redis分布式锁奥义
生活随笔
收集整理的這篇文章主要介紹了
Redis分布式锁奥义
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分布式鎖
- 分布式系統進行邏輯處理的時候,經常會遇到并發問題,例如直播場景中,用戶需要連麥主播,當多個用戶在同一個時刻一起連麥時候,應該保證只有一個用戶能連麥成功,我們改怎么保證這種業務場景下保證數據的正確性。
- 當我們連麥的時候,其實設計到兩個步驟操作,首先讀取房間座位信息,當發現座位沒有被占用,修改作為狀態,之后存儲。但是這幾個步驟并非原子操作,也就是可能存在兩個線程同時讀取,一起修改,這樣肯定會造成數據錯亂。怎樣來保證讀取,修改,存儲,這三個步驟的原子操作就是分布式鎖需要解決的問題。
分布式鎖的奧義
- 分布式鎖本質上實現就是在Redis中占用一個key值,當別的進程也要來占用這個key時候,發現已經存在這個key,就只能放棄,或者等待key消失。我們一般使用setnx(set if not exists) 命令,只允許被一個客戶占用,先到先得,在用del刪除key,釋放key占用給別的線程
- 存在的問題,比如邏輯執行期間,出現異常,導致del指令無法執行,占用會陷入死鎖,永遠不能得到釋放,這個問題可以通過過期時間解決,我們在設置key時候添加一個過期時間,這樣中介出現異常,5s后也會自動釋放如下:
- 新的問題, setnx 與expire兩個指令并非原子操作,在兩個指令執行間隔期間掛機,那么還是會死鎖。如果可以一起執行就不會出現這種問題,可能Redis事務來解決問題,但是這種業務場景下不下,因為expire必須在前面setnx成功的前提條件才能夠執行,當setnx沒有獲取鎖,expire是不能執行的,此時同一個事務中這兩個命令會出現一個成功一個失敗,與預期不符合。
- 為解決此問題,Redis2.8 版本后引入了一個新的指令,是的setnx和expire指令能一起執行,徹底解決分布式鎖的問題,從此后,所有第三方鎖都可以舍棄了,如下:
- 以上指令setnx和expire的組合一起的原子指令,他就是分布式鎖解決的奧義。
還有超時問題
- Redis分布式鎖還是解決不了某種超時,比如,我設置5s,但是業務太垃圾了執行了6秒,以至于超過了鎖的限制,那么問題出現了。鎖以釋放,剩余邏輯無法得到保護,第二個線程重新持有鎖,然后第一個還沒執行完的線程現在執行完了,給你吧key刪了,這樣是不是很刺激。
- 為避免這個問題,Redis分布式鎖不要用著長時間的任務,如果偶爾出現問題,造成的數據小錯誤就人肉解決吧。
- 另外還有一個小的技巧來規避這種刪除問題,我們利用value造一個樂觀鎖,我們在set value的時候設置本輪次邏輯的一個特殊的value值,當我們執行完邏輯后,在刪除之前先確認一下value是否本輪次的value,如果不是表示非本輪次,不執行刪除,如果是當前value,則刪除。
- 問題又來了,匹配value,刪除key,又不是原子操作,Redis也沒有類似的delifequals的指令,但是Redis4.0 后提供了lua腳本的支持,因為lua腳本可以保證連續多個指令的原子性執行
- 這并非完美解決方案,還是有部分邏輯在裸奔,那么我們盡量規避吧,還有就是這么長邏輯,應該想到的是優化。
Redis分布式鎖失效情況
- 在Redis集群中,我們分布式鎖是有一定缺陷的,例如在哨兵模式集群中,主節點掛掉,從節點會取而代之,這對客戶端是無感知的,比如,客戶端A主節點上申請lock,但是這把鎖還沒同步到Slave節點,主節點掛掉,之后從節點變主節點,B客戶端在申請lock,同樣成功,這樣就存在兩把鎖,違背了分布式鎖的初衷。不安全性由此產生。
- 以上情況在理論上是完全有可能發生的,但是也僅僅只是在主從發生failover的情況下才產生,而且持續時間比較短,業務系統多試情況下是可以容忍的。所以我嗎業務中一般會忽略這種極端的情況。
Redlock算法
- 遇到問題,解決問題,以上出現的極端情況也是有解決方案的,她流產比較復雜,但是有很多開源的libray已經做了良好的封裝,用戶之間用即可,例如Python中redlock-py
- 為了使用Redlock,需要提供多個Redis實例,這些實例之間相互獨立,沒有主從關系。通很多分布式算法一樣,Redlock用大多數機制。
- 加鎖時候向過半節點發送set(key, value, nx=True, ex=xxx)指令,只要過半節點set成功,就認為加鎖成功
- 釋放鎖需要想所有節點發送del指令
- Redlock需要想多個節點進行讀寫,意味著相比單實例Redis的性能會下降。
Redlock使用場景
- 業務室對高可用性有苛刻的要求,希望一臺Redis掛了也完全不受影響,就應該考慮用Redlock
- 代價是需要更多的Redis實例,性能也下降,代碼刪還需引入額外的library,運維上也需要特殊對待,這些都是成本。
上一篇:Redis流量控制策略
下一篇:LBS解決方案
總結
以上是生活随笔為你收集整理的Redis分布式锁奥义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 艾灸肚子能减肥吗
- 下一篇: 后背长痘痘拔罐有用吗