天天看點

redission分布式鎖實作_Redisson實作分布式鎖原理

redission分布式鎖實作_Redisson實作分布式鎖原理

目錄

1、高效分布式鎖 2、Redisson原理分析

來源: cnblogs.com/qdhxhz/p/11046905.html

1、高效分布式鎖

當我們在設計分布式鎖的時候,我們應該考慮分布式鎖至少要滿足的一些條件,同時考慮如何高效的設計分布式鎖,這裡我認為以下幾點是必須要考慮的。

1、互斥

在分布式高并發的條件下,我們最需要保證,同一時刻隻能有一個線程獲得鎖,這是最基本的一點。

2、防止死鎖

在分布式高并發的條件下,比如有個線程獲得鎖的同時,還沒有來得及去釋放鎖,就因為系統故障或者其它原因使它無法執行釋放鎖的指令,導緻其它線程都無法獲得鎖,造成死鎖。

是以分布式非常有必要設定鎖的有效時間 ,確定系統出現故障後,在一定時間内能夠主動去釋放鎖,避免造成死鎖的情況。

3、性能

對于通路量大的共享資源,需要考慮減少鎖等待的時間,避免導緻大量線程阻塞。

是以在鎖的設計時,需要考慮兩點。

  • 鎖的顆粒度要盡量小。比如你要通過鎖來減庫存,那這個鎖的名稱你可以設定成是商品的ID,而不是任取名稱。這樣這個鎖隻對目前商品有效,鎖的顆粒度小。
  • 鎖的範圍盡量要小 。比如隻要鎖2行代碼就可以解決問題的,那就不要去鎖10行代碼了。

4、重入

我們知道ReentrantLock是可重入鎖,那它的特點就是:同一個線程可以重複拿到同一個資源的鎖。重入鎖非常有利于資源的高效利用。關于這點之後會做示範。

針對以上Redisson都能很好的滿足,下面就來分析下它。

2、Redisson原理分析

為了更好的了解分布式鎖的原理,我這邊自己畫張圖通過這張圖來分析。

redission分布式鎖實作_Redisson實作分布式鎖原理

1、加鎖機制

線程去擷取鎖,擷取成功: 執行lua腳本,儲存資料到redis資料庫。

線程去擷取鎖,擷取失敗: 一直通過while循環嘗試擷取鎖,擷取成功後,執行lua腳本,儲存資料到redis資料庫。

2、watch dog自動延期機制

這個比較難了解,找了些許資料感覺也并沒有解釋的很清楚。這裡我自己的了解就是:

在一個分布式環境下,假如一個線程獲得鎖後,突然伺服器當機了,那麼這個時候在一定時間後這個鎖會自動釋放,你也可以設定鎖的有效時間(不設定預設30秒),這樣的目的主要是防止死鎖的發生。

但在實際開發中會有下面一種情況:

//設定鎖1秒過去redissonLock.lock("redisson", 1);/** * 業務邏輯需要咨詢2秒*/redissonLock.release("redisson");/*** 線程1 進來獲得鎖後,線程一切正常并沒有當機,但它的業務邏輯需要執行2秒,這就會有個問題,在 線程1 執行1秒後,這個鎖就自動過期了,* 那麼這個時候 線程2 進來了。那麼就存在 線程1和線程2 同時在這段業務邏輯裡執行代碼,這當然是不合理的。* 而且如果是這種情況,那麼在解鎖時系統會抛異常,因為解鎖和加鎖已經不是同一線程了,具體後面代碼示範。*/
           

是以這個時候 看門狗 就出現了,它的作用就是 線程1 業務還沒有執行完,時間就過了,線程1 還想持有鎖的話,就會啟動一個watch

dog背景線程,不斷的延長鎖key的生存時間。

注意 正常這個看門狗線程是不啟動的,還有就是這個看門狗啟動後對整體性能也會有一定影響,是以不建議開啟看門狗。

3、為啥要用lua腳本呢?

這個不用多說,主要是如果你的業務邏輯複雜的話,通過封裝在lua腳本中發送給redis,而且redis是單線程的,這樣就保證這段複雜業務邏輯執行的原子性 。

4、可重入加鎖機制

Redisson可以實作可重入加鎖機制的原因,我覺得跟兩點有關:

1、Redis存儲鎖的資料類型是 Hash類型2、Hash資料類型的key值包含了目前線程資訊。
           

下面是redis存儲的資料

redission分布式鎖實作_Redisson實作分布式鎖原理
  • 這裡表面資料類型是Hash類型,Hash類型相當于我們java的 > 類型,這裡key是指 'redisson'
  • 它的有效期還有9秒,我們再來看裡們的key1值為 078e44a3-5f95-4e24-b6aa-80684655a15a:45 它的組成是:
  • guid + 目前線程的ID。後面的value是就和可重入加鎖有關。

舉圖說明

redission分布式鎖實作_Redisson實作分布式鎖原理

上面這圖的意思就是可重入鎖的機制,它最大的優點就是相同線程不需要在等待鎖,而是可以直接進行相應操作。

5、Redis分布式鎖的缺點

Redis分布式鎖會有個缺陷,就是在Redis哨兵模式下:

用戶端1 對某個 master節點 寫入了redisson鎖,此時會異步複制給對應的 slave節點。但是這個過程中一旦發生

master節點當機,主備切換,slave節點從變為了 master節點。

這時 用戶端2 來嘗試加鎖的時候,在新的master節點上也能加鎖,此時就會導緻多個用戶端對同一個分布式鎖完成了加鎖。

這時系統在業務語義上一定會出現問題, 導緻各種髒資料的産生 。

缺陷 在哨兵模式或者主從模式下,如果 master執行個體當機的時候,可能導緻多個用戶端同時完成加鎖。

redission分布式鎖實作_Redisson實作分布式鎖原理

繼續閱讀