Redisson(4)分布式锁之RedLock
?Redis實現分布式鎖的官方文檔介紹
Redis的官方文檔對用Redis分布式鎖的難點以及解決方案的考慮做了一些說明,具體內容參見:/docs/reference/patterns/distributed-locks/,譯文參考:《Redis官方文檔》用Redis構建分布式鎖 | 并發編程網 – ifeve.com
場景一:
保存鎖的Redis的master節點掛了。這里不是說有slave就沒問題了,因為Redis的數據復制功能(replication)是異步的,存在這樣的可能,線程1獲取到鎖了,該鎖在從master復制到slave之前,master掛掉了,然后slave提升為了master,這個時候線程2從新的master節點上是可以獲取到鎖的,之前的鎖丟失了,這樣會導致安全問題。
場景二:
對于鎖“lock123”(名字隨便取的),線程一獲取到鎖,設置過期時間為30s,但是真正業務執行時間超過了30s,比如說40s。在32s的時候線程二嘗試獲取鎖,并且成功了,因為這個鎖的超時時間是30s,在32s的時候,該鎖已經失效了。當40s的時候,線程一業務執行完畢,這個時候嘗試去釋放鎖,即刪除鎖,很不幸,這個時候線程二鎖持有的鎖會被線程一誤刪掉,因為它們的key相同。
解決方案:
set操作的時候,設置一個random value作為該key的value,在解鎖的時候,判斷當前鎖的value和該value是相同的,這樣才可以執行刪除操作,就可以解決上面場景中的誤刪問題了。但是其實并不完美,因為在第一個線程執行完任務之前,線程二不應該獲取鎖,但是該鎖的過期時間比業務執行時間短,從而導致了線程二仍然獲取到了鎖。
Redisson的解決方案
在redis的文檔中提到了一個算法,如果按照這個算法來實現分布式鎖的話,可以解決之前提到的那些問題。
Redisson的實現在RedissonMultiLock中,核心算法在tryLock方法中:
這里管理了多個鎖,為的就是解決某一個Redis節點上保存的鎖因為該Redis節點出現問題而導致鎖不可用的情況。for循環對每個鎖進行嘗試加鎖操作,這里有兩種情況:
①如果獲取鎖成功,那么就將當前鎖添加到已獲取鎖的隊列中去
②如果加鎖失敗,那么判斷當前成功的鎖的個數是否達標,如果達標,那么跳出循環。如果不達標,那么失敗限制計數減一(因為上面再次循環成功的次數有可能加一,所以這里失敗限制要減一)。然后檢查是否已經超時,如果超時,說明在超時限定時間內沒有獲取到鎖,即獲取鎖失敗,這時釋放所有已經成功加鎖的所有鎖。如果加鎖成功的話,那么給所有已經加鎖成功的鎖設置超時時間。
總結
以上是生活随笔為你收集整理的Redisson(4)分布式锁之RedLock的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器人碰撞检测——生成无碰撞轨迹
- 下一篇: [组图]国外专家谈游戏制作