通常情況在解決分布式場景鎖機制都會首先想到redis。因為redis單執行緒天然就解決了這個問題。使用redis實現分布式鎖可以通過getset和setnx。
redis> getset db mongodb # 沒有舊值,返回 nil
(nil)
redis> get db
"mongodb"
redis> getset db redis # 返回舊值 mongodb
"mongodb"
redis> get db
"redis"
redis> exists job # job 不存在
(integer) 0
redis> setnx job "programmer"
# job 設定成功
(integer) 1
redis> setnx job "code-farmer"
# 嘗試覆蓋 job ,失敗
(integer) 0
redis> get job # 沒有被覆蓋
"programmer"
然而這個方式在鎖等待的情況下,都無法主動獲取鎖釋放通知,必須輪詢的方式去不斷的查redis。這個就會產生大量查詢請求並且會增加等待時間(譬如你10ms輪詢一次,但是可能下一毫秒已經可以獲得鎖了,你卻需要繼續等10ms)。接下來我分享一段我基於redis subpub機制實現的分布式鎖的思路:
使用了redis list佇列和subpub機制。
每個等待鎖都會生成全域性唯一的eventid,redis佇列放置的就是等待獲取鎖的eventid集合。
獲取鎖的過程一:放入佇列後長度剛好為:1,則已獲得鎖。
鎖等待:執行緒阻塞等待redis發布訊息,如果nexteventid與當前一致則獲得鎖。
其他需要考慮:鎖超時,死鎖等問題。
附: 1. eventid結構:固定位數節點id+13位時間戳+唯一序列
public string buildevenid()
釋放鎖,發布訊息內容:lockname+分隔符+nexteventid
完整**:
獲取完整**
Redis發布訂閱機制
redis是乙個開源的記憶體資料庫,它以鍵值對的形式儲存資料。由於資料儲存在記憶體中,因此redis的速度很快,但是每次重啟redis服務時,其中的資料也會丟失,因此,redis也提供了持久化儲存機制,將資料以某種形式儲存在檔案中,每次重啟時,可以自動從檔案載入資料到記憶體當中。redis的架構包括...
Redis 發布訂閱機制詳解
程序間的一種訊息通訊模式 傳送者 pub 傳送訊息,訂閱者 sub 接收訊息。聯想諸多訊息中介軟體的發布訂閱模式,但是redis大多用來作為基於記憶體的分布式快取,企業中訊息中介軟體多用activemq ribbitmq等。下圖展示了頻道channel1,以及訂閱這個頻道的三個客戶端 client2...
Redis之發布 訂閱機制
相關命令 publish 發布 subscribe 訂閱 psubscribe 一種訂閱符合給定模式的所有頻道的方法 unsubscribe 退訂 punsubscribe 退訂乙個訂閱的模式這些命令被廣泛用於構建即時通訊應用,比如網路聊天室 chatroom 和實時廣播 實時提醒等。redis相關...