1. 程式人生 > 其它 >『Redis』什麼是分散式鎖?如何實現?

『Redis』什麼是分散式鎖?如何實現?

分散式鎖問題

相關視訊教程(來自動力節點):https://www.bilibili.com/video/BV1Uz4y1X72A

相關資料下載:http://www.bjpowernode.com/?cnblogs

一、什麼是分散式鎖?

要介紹分散式鎖,首先要提到與分散式鎖相對應的是執行緒鎖、程序鎖。

  • 執行緒鎖:主要用來給方法、程式碼塊加鎖。當某個方法或程式碼使用鎖,在同一時刻僅有一個執行緒執行該方法或該程式碼段。執行緒鎖只在同一JVM中有效果,因為執行緒鎖的實現在根本上是依靠執行緒之間共享記憶體實現的,比如synchronized是共享物件頭,顯示鎖Lock是共享某個變數(state)。
  • 程序鎖:為了控制同一作業系統中多個程序訪問某個共享資源,因為程序具有獨立性,各個程序無法訪問其他程序的資源,因此無法通過synchronized等執行緒鎖實現程序鎖。
  • 分散式鎖:當多個程序不在同一個系統中,用分散式鎖控制多個程序對資源的訪問。

二、分散式鎖的使用場景

執行緒間併發問題和程序間併發問題都是可以通過分散式鎖解決的,但是強烈不建議這樣做!因為採用分散式鎖解決這些小問題是非常消耗資源的!分散式鎖應該用來解決分散式情況下的多程序併發問題才是最合適的。有這樣一個情境,執行緒A和執行緒B都共享某個變數X。

如果是單機情況下(單JVM),執行緒之間共享記憶體,只要使用執行緒鎖就可以解決併發問題。

如果是分散式情況下(多JVM),執行緒A和執行緒B很可能不是在同一JVM中,這樣執行緒鎖就無法起到作用了,這時候就要用到分散式鎖來解決。

三、分散式鎖的實現

分散式鎖實現的關鍵是在分散式的應用伺服器外,搭建一個儲存伺服器,儲存鎖資訊,這時候我們很容易就想到了Redis。首先我們要搭建一個Redis伺服器,用Redis伺服器來儲存鎖資訊。

在實現的時候要注意的幾個關鍵點:

1、鎖資訊必須是會過期超時的,不能讓一個執行緒長期佔有一個鎖而導致死鎖;

2、同一時刻只能有一個執行緒獲取到鎖。

幾個要用到的redis命令:

  • setnx(key, value):“set if not exits”,若該key-value不存在,則成功加入快取並且返回1,否則返回0。
  • get(key):獲得key對應的value值,若不存在則返回nil。
  • getset(key, value):先獲取key對應的value值,若不存在則返回nil,然後將舊的value更新為新的value。
  • expire(key, seconds):設定key-value的有效期為seconds秒。

分散式鎖的三種實現方式

  1. 資料庫樂觀鎖;

  2. 基於Redis的分散式鎖;

  3. 基於ZooKeeper的分散式鎖。