特斯拉:貴州超級充電線路全省通達,佈局線路近三千公里
首先我們意識裡要知道分佈鎖有哪些?
分散式鎖一般分三種:
基於資料庫的樂觀鎖,
基於redis的分散式鎖,
基於zookeper的分散式鎖
本文只講基於reids的分散式鎖。
為什麼要用分散式鎖?
在傳統單體應用單機部署的情況下,併發問題可以通過使用Java併發相關的鎖如synchronized,但是當規模上升到分散式叢集的情況下,要控制共享資源訪問,就需要通過分散式鎖來實現。
當應用進行了分散式部署,應用有多個服務,這個時候應用服務端就沒有一個可提供原子性操作的地方了,Redis效能高,且是單執行緒,因此可提供一個原子性操作的地方
redis分散式鎖的底層原理
Redis分散式鎖可以有多種方式實現但是其核心就是通過以下三個Redis命令組合實現。
-
SETNX SETNX key val 當且僅當key不存在時,set一個key為val的字串,返回1;若key存在,則什麼都不做,返回0。
-
Expire expire key timeout 為key設定一個超時時間,單位為second,超過這個時間鎖會自動釋放,避免死鎖。
-
Delete delete key 刪除key
核心思想
-
使用setnx獲取鎖。如果成功取到鎖,則使用expire命令為鎖新增一個超時時間,超過該時間則自動釋放鎖。
-
獲取鎖的時候還設定一個獲取的超時時間,若超過這個時間則放棄獲取鎖。
客戶端1和客戶端2同時持有了同一個資源的鎖,鎖不再具有安全性。根本原因是Redis叢集不是強⼀致性的。
那麼怎麼保證強⼀致性呢—Redlock演算法;
假設客戶端1從Master獲取了鎖。 這時候Master宕機了,儲存鎖的key還沒有來得及同步到Slave上。 Slave升級為Master。
客戶端2從新的Master獲取到了對應同一個資源的鎖;
直白點說,就是採用N(通常是5)個獨立的redis節點,同時setnx,如果多數節點成功,就拿到了鎖,這樣就可以允許少數(2)個節點掛掉了。整個取鎖、釋放鎖的操作和單節點類似。