1. 分佈式鎖特徵node
在不少分佈式或微服務架構產品應用中,有些場景須要加鎖處理,要求分佈式鎖具有以下特性:數據庫
一、要求每一個事物都有各自一把鎖。安全
二、鎖互斥,無論任什麼時候候,只有一個客戶端能持有同一個鎖。架構
三、鎖具備自動釋放特徵(超時後會自動釋放),確保不會死鎖,最終客戶端必定會獲得鎖,就算一個持有鎖的客戶端宕掉。併發
四、鎖的時效設置。避免單點故障形成死鎖,影響其餘客戶端獲取鎖。可是也要保證一旦一個客戶端持鎖,在客戶端可用時不會被其餘客戶端解鎖。框架
五、加鎖的事務或者操做盡可能粒度小,減小其餘客戶端申請鎖的等待時間,提升處理效率和併發性。分佈式
六、客戶端在再也不須要鎖或者任務執行完成以後須要主動釋放鎖,這樣其餘客戶端就不用等到超時時間再去獲取這個鎖。微服務
七、當一個客戶端嘗試獲取鎖時,若是這個鎖被其餘客戶端佔用,則當即返回,不作任何業務處理,此目的在於確保同一時刻只有一個客戶端在執行特定網元告警同步操做便可。工具
八、提供分佈式鎖的中間件,須要具備高可靠、容災等特性,確保分佈式鎖穩定性。測試
2. 分佈式鎖選型
分佈式鎖以往大部分的解決方案是基於數據庫來實現的,這種方式業務實現比較複雜,好比須要開發人員自行實現鎖超時釋放機制,避免死鎖問題。那麼如何找到一款可以知足各類應用場景的分佈式鎖組件呢?
2.1 ZooKeeper分佈式鎖
ZooKeeper是一個分佈式應用程序協調服務,爲分佈式應用提供一致性服務的組件。ZooKeeper節點結構是一個和文件系統相似的小型的樹狀的目錄結構,同時Zookeeper機制規定:同一個目錄下只能有一個惟一的文件名。例如:在ZooKeeper的根目錄下,由兩個客戶端同時建立一個名爲/locks/ne_node,則只有一個客戶端能夠建立成功。所以,能夠經過ZooKeeper節點爲每一個待告警同步的網元來建立一個鎖,例如/locks/10.63.204.101就能夠定義爲一個鎖。ZooKeeper分佈式鎖架構示意圖以下:
另外,ZooKeeper有一種臨時類型的節點,臨時節點由某個客戶端建立,當客戶端由於宕機,與ZooKeeper集羣斷開鏈接時,則該臨時節點會被自動刪除,從而避免了死鎖問題。
客戶端在獲取到鎖以後,開始執行互斥業務邏輯,執行完成後,顯示刪除臨時節點,便可釋放鎖。
2.2 Redis分佈式鎖
Redisson在基於NIO的Netty框架上,充分的利用了Redis鍵值數據庫提供的一系列優點,在Java實用工具包中經常使用接口的基礎上,爲使用者提供了一系列具備分佈式特性的經常使用工具類。Redisson提供了分佈式鎖特性,開發者可直接利用開發相關業務。
Redis分佈式鎖架構示意圖以下:
2.3 分佈式鎖比對
可重入鎖 |
持鎖斷開鏈接後釋放鎖 |
鎖持久化 |
優缺點 |
|
ZK |
支持 |
支持,臨時節點當鏈接中斷會刪除鎖 |
支持 |
安全性較高,支持鎖持久化存儲,但效率稍低 |
Redis |
支持 |
支持,過時時間 |
不支持 |
安全性較低,不支持鎖持久化存儲,但效率較高 |
3 分佈式鎖總結
除了上面提到的ZooKeeper和Redis外,還有不少技術能夠實現分佈式鎖。在思考是否採用分佈式鎖以及採用哪一種實現方案的時候,仍是要基於業務,技術方案必定是基於業務基礎,服務於業務,而且衡量過投入產出比的。因此若是有成熟的解決方案,在業務可承受規模確定是不要重複造輪子,固然還要通過嚴謹的選型和測試。開發者在實際開發中,可權衡利弊,選擇一種最合適業務場景的分佈式鎖來實現相關業務。