使用Redis實現分布式可重入鎖

2021-10-04 11:19:52 字數 1973 閱讀 3818

在分布式應用中經常需要用到分布式鎖。

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

參考資料<

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

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

使用Redis實現分布式鎖

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

使用redis 實現分布式鎖

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