網上大部分建議都是使用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 獲取...