回覆列表
  • 1 # 淺析架構

    首先明確分散式鎖應該具備什麼特性:獲取鎖的業務無論正常與否,都必須能釋放鎖,這樣才能避免死鎖;鎖應該具有高可用性。

    我們來看看redis是怎麼來實現鎖的的。

    redis主要是透過setnx、get、getset、del命令來完成加鎖,搶鎖和釋放鎖的操作的,這裡我用兩個客戶端來模擬下加鎖的過程。下面有實際操作的截圖。

    1、客戶端1使用setnx獲取到鎖,並設定鎖的當前時間。設定超時時間就是為了業務掛了,鎖不能釋放成為死鎖。

    執行命令

    setnx lock 0

    為了方便舉例,我們假定鎖的當前時間是從0秒開始的,超時時間為3秒。如果結果返回為1,表明加鎖成功,可以執行業務邏輯了。

    2、當第一秒鐘客戶端2使用setnx獲取鎖,執行命令

    setnx lock 1

    返回值為0,則加鎖失敗。

    3、客戶端2接收到加鎖時間的迴應後,會去檢視鎖是否超時。執行命令

    get lock

    返回值為加鎖的時間,假設現在時間已經到第4秒了,客戶端會使用返回的時間0加上超時時間3小於當前時間4,鎖已經超時了。

    4、客戶端2使用getset命令去獲取鎖。

    getset lock 4

    這時候返回的是前一次加鎖的時間,如果這個時間是0,證明加鎖成功,因為和前一次get的值相同。如果不同,說明鎖已經被別人搶佔了,加鎖失敗,繼續重複步驟3和4。

    5、業務執行完成後,判斷下鎖是否超時,沒有超時,不用管了。如果沒有超時,呼叫del命令釋放鎖即可。

    redis存在的問題

    1、redis如果是單機的話是有單點問題的,不滿足高可用性。redis叢集因為是ap模型,是不能保證一致性的,官方提供了redlock演算法來解決這個問題,但是至少需要3個master-slave節點才能完成,成本也較大。redlock相當於是來實現一致性協議的。

    2、鎖的超時時間設定問題,太長太短都不合適,太長了如果服務掛掉了會一直阻塞業務,太短了有可能業務還沒執行完成就釋放了。當然可以用官方提供redisson解決。

  • 中秋節和大豐收的關聯?
  • 面寬16米,進深11米,如何建兄弟又拼兩層圖形?