分布式锁是啥?zk还是redis?
?關于分布式系統中應該考慮的幾個問題包括諸如最基本的分布式鎖和分布式事務等。該篇中我們將簡單來聊聊分布式鎖相關知識,比如常見的分布式鎖的實現方式有哪些?redis如何設計分布式鎖?zk如何設計分布式鎖?以及這兩種方式哪種效率更高?
?
1.redis分布式鎖
最常見的一種方式也被稱為“原生方式”,即不采用任何redis相關的第三方框架的方式。
采用setnx指令的設置一個key,比如setnx mylock,這個setnx的意思就是只有key不存在時才會設置成功,相當于誰先創建成功誰就獲得這把鎖,然后當前線程執行完畢后就執行del mylock指令刪除該key即釋放鎖,此時其它線程就可以獲取鎖了。這是redis中最常見的一種做法。
不過顯然僅僅這樣還是不行的,比如如果在釋放鎖之前發生了異?;蛘弋斍胺斟礄C,將會導致鎖無法釋放,這樣其它線程就永遠不可能獲取這把鎖了,這就是我們常說的死鎖。
所以一般的做法就是我們在設置key的時候加上一個過期時間setnx mylock 30?比如設置該key的過期時間為expire 30?為30s,這樣在30s后就會自動刪除該key釋放鎖。
但是這樣其實還不夠,試想如果當前線程在30s過期時間內業務還沒執行完,但是鎖已經釋放,而此時其它線程已經搶占到了鎖,如果當前線程剛好執行完然后去刪除key的話就會有大問題,因為此時的key也就是“鎖”已經不屬于你了,你會把原本屬于其它線程的鎖給釋放掉,很明顯接下來就全亂套了,你為什么要刪別人鎖啊啊。。。
因此,我們在設置key加鎖的時候一般要帶上一個標識,這個標識可以放到value中,用來標識當前鎖所屬的線程,釋放鎖刪除key的時候根據value判斷下當前鎖是否屬于你。
綜上所述,有沒有發現redis實現分布式鎖真的是又“簡單”又“復雜”,簡單到一條指令就可以搞定,復雜的是你需要考慮各種可能出現的異常情況。
因此一般情況下都是采用框架來做,比如redisson。
redis鎖的原生方式大致如下圖:
?
2.zk實現分布式鎖
zk實現分布式鎖的原理很簡單實現也很方便,zk采用的是創建臨時節點node的方式實現的,即誰創建某個指定的臨時節點node成功,誰就獲取到了這把鎖;其它線程來創建節點就會失敗也就無法獲取鎖,然后通過注冊watch監聽事件來監聽這個節點。釋放鎖就是刪除該節點node,一旦該節點刪除就會通知其它注冊過監聽事件的線程(服務宕機也會自動刪除該臨時節點,所以不用擔心死鎖問題),其它線程就會來重新創建節點搶占鎖,這就是原生zk實現分布式鎖的基本原理。
當然,一般實際情況中都會采用成熟框架的方式創建分布式鎖,比如curator,其原理是與原生框架略有區別,是通過創建臨時順序節點的方式實現的,即所有線程都可以創建一個節點,根據創建順序依次排序,其中第一號最小節點client1獲取鎖,其它線程創建的節點依次對上一個節點注冊監聽事件,比如client2對client1注冊監聽事件,client3對client2注冊監聽事件,當上一個節點刪除時,下一個節點會成為最小的“一號”節點,獲取鎖成功。比如client1刪除了節點,那么client2接收到通知,此時client2稱為了最小節點因此client2就獲取到了鎖,依次類推。
zk分布式鎖大致原理如下圖:
?
?
其實要做選擇的話,看公司的場景,如果公司是以redis為主的可以選用redis做分布式鎖,如果公司使用了zookeeper框架,個人覺得可以考慮zookeeper做分布式鎖!
?
關注微信公眾號“蝦米聊吧”,獲取更多技術知識干貨喲~
? ? ? ? ? ?掃碼關注微信公眾號
總結
以上是生活随笔為你收集整理的分布式锁是啥?zk还是redis?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手心输入法设置怎么双拼
- 下一篇: 怎么设置Win10任务栏通知区域 设置W