在分布式應用中經常需要用到分布式鎖。
redis使用set命令來實現分布式鎖
set key value [ex seconds] [px milliseconds] [nx|xx]
直接使用該命令構建的redis分布式鎖是不像jdk的reentrantlock具有可重入性的,使用執行緒的threadlocal變數儲存當前持有鎖的計數,可以實現redis分布式鎖的可重入性。
另外redis分布式鎖有超時的問題,不要用於耗時較長的任務.如果真的有耗時較長的任務需要鎖,建議使用資料庫的樂觀鎖來解決。
import redis
import threading
host =
'127.0.0.1'
port =
'6379'
password =
''pool = redis.connectionpool(host=host, port=port, password=password, max_connections=
1024
)conn = redis.redis(connection_pool=pool)
locks = threading.local(
)locks.redis =
defkey_for
(user_id)
:return
"account_{}"
.format
(user_id)
def_lock
(client, key)
:print
("redis lock "
)return
bool
(client.
set(name=key, value=
"1", nx=
true
, ex=5)
)def
_unlock
(client, key)
:print
("redis un lock"
) client.delete(key)
deflock
(client, user_id)
: key = key_for(user_id)
if key in locks.redis:
locks.redis[key]+=1
return
true
ok = _lock(client, key)
ifnot ok:
return
false
locks.redis[key]=1
return
true
defunlock
(client, user_id)
: key = key_for(user_id)
if key in locks.redis:
locks.redis[key]-=1
if locks.redis[key]
<=0:
del locks.redis[key]
_unlock(client, key)
return
true
return
false
print
(lock(conn,
"codehole"))
print
(lock(conn,
"codehole"))
print
(unlock(conn,
"codehole"))
print
(unlock(conn,
"codehole"
))
輸出
輸出redis lock
true
true
unlock
true
redis un lock
true
參考資料< 關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs... 網上大部分建議都是使用setnx,這個本身沒有什麼問題,因為低版本的redis中,只有這個命令可以互斥的set乙個key。但是隨著redis版本的公升高,提供了更多的命令來更好的滿足我們的需求。set keyvalue ex seconds px milliseconds nx xx 這可和你所知道... 在有些需要高可用的場景中,保證併發量的情況下需要使用分布式鎖來做控制,保證應用的可靠性。我們知道jdk提供了一些常用的鎖比如reentrantlock,reentrantreadwritelock,synchronized。對於這些鎖的實現這裡就不詳細介紹了,在使用過程中這些鎖鎖的是物件,在單伺服器...分布式鎖 使用Redis實現分布式鎖
使用Redis實現分布式鎖
使用redis 實現分布式鎖