一個作業了7年的Java程式員,私信我關于分布式鎖的問題,
一上來就兩個靈魂拷問:
- Redis鎖超時怎么辦?
- Redis主從切換導致鎖失效怎么辦?
我說,別著急,這些都是小問題,
那么,關于“分布式鎖的理解和實作”這個問題,我們看看普通人高手的回答,
普通人:
嗯,分布式鎖,就是可以用來實作鎖的分布性,嗯…
就是可以解決跨行程的應用對于共享資源訪問的沖突問題,
可以用Redis來實作分布式鎖,
高手:
分布式鎖,是一種跨行程的跨機器節點的互斥鎖,它可以用來保證多機器節點對于共享資源訪問的排他性,

我覺得分布式鎖和執行緒鎖本質上是一樣的,執行緒鎖的生命周期是單行程多執行緒,分布式鎖的宣告周期是多行程多機器節點,
在本質上,他們都需要滿足鎖的幾個重要特性:
- 排他性,也就是說,同一時刻只能有一個節點去訪問共享資源,
- 可重入性,允許一個已經獲得鎖的行程,在沒有釋放鎖之前再次重新獲得鎖,
- 鎖的獲取、釋放的方法
- 鎖的失效機制,避免死鎖的問題
所以,我認為,只要能夠滿足這些特性的技術組件都能夠實作分布式鎖,
-
關系型資料庫,可以使用唯一約束來實作鎖的排他性,
如果要針對某個方法加鎖,就可以創建一個表包含方法名稱欄位,
并且把方法名設定成唯一的約束,
那搶占鎖的邏輯就是:往表里面插入一條資料,如果已經有其他的執行緒獲得了某個方法的鎖,那這個時候插入資料會失敗,從而保證了互斥性,
這種方式雖然簡單啊,但是要實作比較完整的分布式鎖,還需要考慮重入性、鎖失效機制、沒搶占到鎖的執行緒要實作阻塞等,就會比較麻煩,
-
Redis,它里面提供了SETNX命令可以實作鎖的排他性,當key不存在就回傳1,存在就回傳0,然后還可以用expire命令設定鎖的失效時間,從而避免死鎖問題,
當然有可能存在鎖過期了,但是業務邏輯還沒執行完的情況, 所以這種情況,可以寫一個定時任務對指定的key進行續期,
Redisson這個開源組件,就提供了分布式鎖的封裝實作,并且也內置了一個Watch Dog機制來對key做續期,
我認為Redis里面這種分布式鎖設計已經能夠解決99%的問題了,當然如果在Redis搭建了高可用集群的情況下出現主從切換導致key失效,這個問題也有可能造成
多個執行緒搶占到同一個鎖資源的情況,所以Redis官方也提供了一個RedLock的解決辦法,但是實作會相對復雜一些,
-
在我看來,分布式鎖應該是一個CP模型,而Redis是一個AP模型,所以在集群架構下由于資料的一致性問題導致極端情況下出現多個執行緒搶占到鎖的情況很難避免,
那么基于CP模型又能實作分布式鎖特性的組件,我認為可以選擇Zookeeper或者etcd,
- 在資料一致性方面,zookeeper用到了zab協議來保證資料的一致性,etcd用到了raft演算法來保證資料一致性,
- 在鎖的互斥方面,zookeeper可以基于有序節點再結合Watch機制實作互斥和喚醒,etcd可以基于Prefix機制和Watch實作互斥和喚醒,
以上就是我對于分布式鎖的理解!
總結
我認為,回答這個問題的核心本質,還是在技術底層深度理解的基礎上的思考,
可以從高手的回答中明顯感受到,對于排它鎖底層邏輯的理解是很深刻的,同時再技術的廣度上也是有足夠的積累,
所以在回答的時候,面試官可以去抓到求職者在回答這個問題的時候的技術關鍵點和技術思維,
我認為,當具備體系化的技術能力的時候,是很容易應對各種面試官的各種刁難的,
好的,本期的普通人VS高手面試系列就到這里結束了,喜歡的朋友記得點贊和收藏,
另外,有任何技術上的問題,職業發展有關的問題,都可以私信我,我會在第一時間回復,
著作權宣告:本博客所有文章除特別宣告外,均采用 CC BY-NC-SA 4.0 許可協議,轉載請注明來自
Mic帶你學架構!
如果本篇文章對您有幫助,還請幫忙點個關注和贊,您的堅持是我不斷創作的動力,歡迎關注「跟著Mic學架構」公眾號公眾號獲取更多技術干貨!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/465949.html
標籤:Java
