僅供自學回顧使用,請支持javaGuide原版書籍。
本篇文章涉及到的分布式鎖,在本人其他文章中也有涉及。
《JUC:三、兩階段終止模式、死鎖的jconsole檢測、樂觀鎖(版本號機制+CAS實現)+悲觀鎖》:https://blog.csdn.net/zhiaidaidai/article/details/142862002
《redis:四、雙寫一致性的原理和解決方案(延時雙刪、分布式鎖)》:https://blog.csdn.net/zhiaidaidai/article/details/135030539
必看???:《redis:六、setnx獲取鎖、Lua腳本釋放鎖、基于redisson的分布式鎖(看門狗機制、主從一致性、紅鎖)》:https://blog.csdn.net/zhiaidaidai/article/details/135064906
1.本地鎖和分布式鎖
對于單機多線程來說,在 Java 中,我們通常使用 synchronized 關鍵字這類 JDK 自帶的 本地鎖 來控制一個 JVM 進程內的多個線程對本地共享資源的訪問,如下:
分布式系統下,不同的服務/客戶端通常運行在獨立的 JVM 進程上。如果多個 JVM 進程共享同一份資源的話,使用本地鎖就沒辦法實現資源的互斥訪問了。于是,分布式鎖 就誕生了。
2.分布式鎖的特點
一個最基本的分布式鎖需要滿足:
互斥
:任意一個時刻,鎖只能被一個線程持有。高可用
:鎖服務是高可用的,當一個鎖服務出現問題,能夠自動切換到另外一個鎖服務。并且,即使客戶端的釋放鎖的代碼邏輯出現問題,鎖最終一定還是會被釋放,不會影響其他線程對共享資源的訪問。這一般是通過超時機制實現的。可重入
:一個節點獲取了鎖之后,還可以再次獲取鎖。
除了上面這三個基本條件之外,一個好的分布式鎖還需要滿足下面這些條件:
高性能
:獲取和釋放鎖的操作應該快速完成,并且不應該對整個系統的性能造成過大影響。非阻塞
:如果獲取不到鎖,不能無限期等待,避免對系統正常運行造成影響。
3.常見分布式鎖實現方案
常見分布式鎖實現方案如下:
- 基于關系型數據庫比如 MySQL 實現分布式鎖。
- 一般是通過唯一索引或者排他鎖實現。
- 一般不會使用這種方式,問題太多比如性能太差、不具備鎖失效機制。
- 基于分布式協調服務 ZooKeeper 實現分布式鎖。
- 基于分布式鍵值存儲系統比如 Redis 、Etcd 實現分布式鎖。
關系型數據庫的方式基于 ZooKeeper 或者 Redis 實現分布式鎖這兩種實現方式要用的更多一些。