zookeeper實現分佈式鎖,以及和redis區別

原文鏈接:https://www.cnblogs.com/mengchunchen/p/9647756.html

https://www.cnblogs.com/mengchunchen/p/9647756.html

Redis實現分佈式鎖

  1.根據lockKey區進行setnx(set not exist,如果key值爲空,則正常設置,返回1,否則不會進行設置並返回0)操作,如果設置成功,表示已經獲得鎖,否則並沒有獲取鎖。

  2.如果沒有獲得鎖,去Redis上拿到該key對應的值,在該key上我們存儲一個時間戳(用毫秒錶示,t1),爲了避免死鎖以及其他客戶端佔用該鎖超過一定時間(5秒),使用該客戶端當前時間戳,與存儲的時間戳作比較。

  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.如果創建的節點不是所有節點中序號最小的,那麼則監視比自己創建節點的序列號小的最大的節點,進入等待。直到下次監視的子節點變更的時候,再進行子節點的獲取,判斷是否獲取鎖。

  釋放鎖的過程相對比較簡單,就是刪除自己創建的那個子節點即可。

Zookeeper另一個版本:

  zk分佈式鎖,就是某個節點嘗試創建臨時znode,此時創建成功了就獲取了這個鎖;這個時候別的客戶端來創建鎖會失敗,只能註冊個監聽器監聽這個鎖。

  釋放鎖就是刪除這個znode,一旦釋放掉就會通知客戶端,然後有一個等待着的客戶端就可以再次重新加鎖。

區別

zk分佈式鎖,獲取不到鎖,註冊個監聽器即可,不需要不斷主動嘗試獲取鎖,性能開銷較小。

redis分佈式鎖,其實需要自己不斷去嘗試獲取鎖,比較消耗性能。

如果是redis獲取鎖的那個客戶端bug了或者掛了,那麼只能等待超時時間之後才能釋放鎖;而zk的話,因爲創建的是臨時 znode,只要客戶端掛了,znode就沒了,此時就自動釋放鎖

Spring Cloud 實現全局鎖(內置的)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章