Redis實作分散式鎖定
1.根據lockKey區進行setnx(set not exist,如果key值為空,則正常設定,傳回1,否則不會進行設定並返回0)操作,如果設定成功,表示已經獲得鎖,否則並沒有取得鎖。
2.如果沒有取得鎖,去Redis拿到該key對應的值,在該key上我們儲存一個時間戳記(用毫秒錶示,t1),為了避免死鎖以及其他客戶端佔用該鎖超過一定時間(5秒),使用該客戶端當前時間戳,與儲存的時間戳記作比較。 (建議學習:Redis影片教學)
3.如果沒有超過該key的使用時限,返回false,表示其他人正在佔用該key,不能強制使用;如果已經超過時限,那我們就可以進行解鎖,使用我們的時間戳記來取代該欄位的值。
4.但是如果在setnx失敗後,get該值卻無法拿到該字段時,說明操作之前該鎖已經被釋放,這個時候,最好的辦法就是重新執行一遍setnx方法來獲取其值以獲得該鎖。
釋放鎖定:刪除redis中key
Zookeeper實作分散式鎖定
基於臨時順序節點:
1.客戶端呼叫create()方法建立一個名為「locknode/guid-lock-」的節點,要注意的是,這裡節點的建立類型需要設定為EPHEMERAL_SEQUENTIAL。
2.客戶端呼叫getChildren(“locknode”)方法來取得所有已經建立的子節點。
3.客戶端取得到所有子節點path之後,如果發現自己在步驟1中建立的節點是所有節點中序號最小的,那麼就認為這個客戶端獲得了鎖。
4.如果創建的節點不是所有節點中序號最小的,那麼則監視比自己創建節點的序號小的最大的節點,進入等待。直到下次監視的子節點變更的時候,再進行子節點的獲取,判斷是否取得鎖。
釋放鎖定的過程相對比較簡單,就是刪除自己建立的那個子節點即可。
區別:
redis分散式鎖,其實需要自己不斷去嘗試取得鎖,比較消耗效能
zk分散式鎖,取得不到鎖,註冊個監聽器即可,不需要不斷主動嘗試取得鎖,效能開銷較小
另外一點就是,如果是redis取得鎖的那個客戶端bug了或掛了,那麼只能等待超時時間之後才能釋放鎖;而zk的話,因為創建的是臨時znode,只要客戶端掛了,znode就沒了,此時就自動釋放鎖定
更多Redis相關技術文章,請造訪Redis資料庫使用入門教學欄位學習!
以上是zk和redis分散式鎖區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!