單機redis分布式鎖實現原理解析

2022-09-27 07:27:13 字數 1156 閱讀 5429

使用者通過http請求可以通知任務中心結束掉自己傳送的任務,這時候任務中心會通過mq通知結束服務去結束任務儲存資料,由於任務結束資料計算儲存有一定延時,所以存在使用者短時間內多次結束同乙個任務,這時候就會導致我們結束服務對同乙個任務儲存多次資料。恰好我們也是用了redis,所以對於這個問題我當時想到使用分布式鎖來解決,那麼如何用redis實現分布式鎖呢?

首先要明確乙個分布式鎖應具備的原則:

互斥性。在任意時刻,只有乙個客戶端能持有鎖;不會發生死鎖。即使乙個客戶端持有鎖的期間崩潰而沒有主動釋放鎖,也需要保證後續其他客戶端能夠加鎖成功;加鎖和解鎖必須是同乙個客戶端;有高可用的獲取鎖和釋放鎖功能。

由於我們只使用了單機的redis,所以本文的實現不具備第四點原則。

我們這個鎖的實現就包括兩點:加鎖、解鎖。首先看加鎖。先上**:

public boolean trygetdistributedlock(string lockkey, string requestid, int expiretime) throws exception

return false;

} finally

}我們的加鎖就是設定乙個鍵值對,並且程式設計客棧滿足以下條件:

確保只有當鍵不存在時才設定有效;設定的值必須是當前客戶端生成的uuid;鍵必須要有過期時間。

這三點條件就可以滿足上述的原則1、原則2。

接下來xoudsf看下解鎖,**如下:

public boolean releasedistributedlock(string lockkey, string requestid) throws exception

return false;

}finally

}解鎖是通過一段lua指令碼實現,邏輯如下:

1、獲取鎖鍵值看是否與當初設定的值一致;

2、如果一致則刪除鍵。

由於解鎖過程分為兩步,為了確保原子性所以通過讓redis執行lua指令碼來實現,校驗鍵值可以確保加鎖解鎖都是同乙個客戶端。

這樣乙個簡易的分布式鎖就實現完畢了,當然在本文開頭就說了,這個實現只能滿足單機redis的情況,對於redis集群其實是不嚴謹的,對於redis集群有乙個redlock方案,我也在研究中,後面也會總結一下。

本文標題: 單機redis分布式鎖實現原理解析

本文位址: /ruanjian/j**a/310219.html

單機Redis實現分布式鎖

最近有個專案用到了鎖,直接想到了redis,在網上檢視了一下案列,總感覺不是特別符合需求,索性自己寫了乙個。不多說,直接上 class redis lock 單機redis 分布式鎖 class redis lock 單台redis設定鎖 param string key param int exp...

redis單機實現分布式鎖

原理 使用setnx,設定成功返回1,失敗返回0,由於redis也是單執行緒的,所以一次只能有乙個執行緒獲取成功。程式異常情況 設定超時時間,避免程式掛掉鎖無法釋放。執行超時情況 為避免 執行時間超過key設定的超時時間,從而釋放了其他程序的鎖問題。需要儲存當前執行緒的value。在釋放之前先檢查k...

redis 單機鎖 和 分布式鎖

偷自 require vendor autoload.php client new predis client scheme tcp host 127.0.0.1 port 6379,class redislock desc 獲取鎖鍵名 public function getlockcachekey...