使用Redis實現分布式鎖

2021-08-11 18:01:27 字數 1375 閱讀 1251

網上大部分建議都是使用setnx,這個本身沒有什麼問題,因為低版本的redis中,只有這個命令可以互斥的set乙個key。但是隨著redis版本的公升高,提供了更多的命令來更好的滿足我們的需求。

set

keyvalue

[ex seconds]

[px milliseconds]

[nx|xx]

這可和你所知道的不太一樣,set key value我們都知道,那後面的選項是啥呢。其實set這個命令在redis 1.0.0的時候就提供了,但是那個時候,只提供了set key value,後面的選項是redis 2.6.12的時候加上的:

為什麼比原來的使用setnx更好呢,因為setnx不能設定過期時間,那麼使用過程大致是這樣的:

//1.加鎖

setnx key value

//2.防止死鎖,設定過期時間

expire key seconds

//3.業務邏輯...

//4.釋放鎖

如果程式在2步之前,1步之後掛掉了,就會導致死鎖,根本原因和就是設定鎖和設定過期時間不是原子操作,當然你也可以使用事物來保證,只是沒有這麼簡潔而已。

del key [key ...]
直接使用del來刪除就可以了。

上面討論的鎖,其實只關注key,value並沒有關心,這樣的問題就是,不能確定這個鎖究竟是屬於哪個客戶端,也就存在了誤刪除的可能。

舉個例子,乙個客戶端建立了lock1,處理完邏輯後,這個客戶端準備釋放這個鎖lock1,但是這步操作發生在鎖的有效期之後,也就是這個lock1已經自動失效了,這時有另乙個客戶端建立了乙個新的鎖lock2,那麼客戶端刪除的就是lcok2了,這就是錯誤釋放鎖了。

把value設定成乙個token意義的值,比如uuid。

不能簡單的使用del來釋放鎖,而需要借助指令碼

if redis.call("get",keys[1]) == argv[1]

then

return redis.call("del",keys[1])

else

return

0end

,呼叫方法大致是eval ...script... resource-name token-value

更成熟的分布式鎖和同步器

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

使用redis 實現分布式鎖

在有些需要高可用的場景中,保證併發量的情況下需要使用分布式鎖來做控制,保證應用的可靠性。我們知道jdk提供了一些常用的鎖比如reentrantlock,reentrantreadwritelock,synchronized。對於這些鎖的實現這裡就不詳細介紹了,在使用過程中這些鎖鎖的是物件,在單伺服器...

使用redis實現分布式鎖

一.redis命令講解 setnx 命令 setnx的含義就是set if not exists,其主要有兩個引數 setnx key,value 該方法是原子的,如果key不存在,則設定當前key成功,返回1 如果當前key已經存在,則設定當前key失敗,返回0。get 命令 get key 獲取...