超實(shí)用!一篇文章講透分布式鎖,建議收藏!
分布式鎖是在分布式系統(tǒng)環(huán)境下,確保多個(gè)節(jié)點(diǎn)(可能位于不同機(jī)器或不同地理位置)對(duì)共享資源的互斥訪問,從而避免數(shù)據(jù)不一致和競爭條件。
它是現(xiàn)代微服務(wù)應(yīng)用(分布式應(yīng)用)架構(gòu)解決并發(fā)控制問題的關(guān)鍵技術(shù),也是面試中的??土耍裉煸蹅儊肀P點(diǎn)一下分布式鎖的 3 種常見實(shí)現(xiàn)方案。
1.基于Redis的分布式鎖
這是分布式鎖最常見的實(shí)現(xiàn)方案,因?yàn)?Redis 本身為分布式組件,所以 Redis 實(shí)現(xiàn)的鎖就天然的分布式鎖:
圖片
基于 Redis 的分布式的實(shí)現(xiàn)方案也有以下幾種:
- setnx(set if Not eXists):嘗試設(shè)置鍵 key 的值為 value,但如果 key 已經(jīng)存在,則不會(huì)執(zhí)行任何操作并返回 0,如果 key 不存在則加鎖成功。
- 缺陷:存在死鎖問題、鎖誤刪問題、不可重入問題、鎖無法自動(dòng)續(xù)期問題。
- set nx ex/px:setnx 升級(jí)版本,Redis 2.6 版本后才能支持此語法。嘗試加鎖和設(shè)置鎖超時(shí)時(shí)間,使用案例 set key value nx px 3000。
- 缺陷:存在鎖誤刪問題、不可重入問題、鎖無法自動(dòng)續(xù)期問題。
- Lua 腳本:解決鎖重入的問題
- 缺陷:實(shí)現(xiàn)復(fù)雜、且存在鎖無法自動(dòng)續(xù)期問題。
- Redisson 框架:基于 Redis 實(shí)現(xiàn)分布式鎖的開源框架。其實(shí)現(xiàn)簡單、不存在鎖重入和鎖續(xù)期等問題。
可用于生成環(huán)境的實(shí)現(xiàn)方式為 Redisson 框架實(shí)現(xiàn)的分布式鎖,它底層是基于 Redis 主線程執(zhí)行任務(wù)為單線程 + Set 命令的原子性來加鎖的,核心命令:SET key value NX EX 命令:
- NX:僅當(dāng) KEY 不存在時(shí)設(shè)置,保證互斥;
- EX:設(shè)置過期時(shí)間,防止死鎖;
- value:擁有者 ID,防止誤刪鎖。
但它實(shí)現(xiàn)簡單,不存在鎖重入、鎖誤刪、解決了鎖續(xù)期的問題,所以常被用于生產(chǎn)環(huán)境。
2.基于Zookeeper的分布式鎖
ZooKeeper 提供強(qiáng)一致性和順序性,適合實(shí)現(xiàn)高可靠分布式鎖。
它的實(shí)現(xiàn)原理:
- 創(chuàng)建一個(gè)持久父節(jié)點(diǎn),如 /locks;
- 每個(gè)客戶端嘗試獲取鎖時(shí),在該父節(jié)點(diǎn)下創(chuàng)建一個(gè)臨時(shí)順序節(jié)點(diǎn),如 /locks/lock_000000001;
- 客戶端獲取所有子節(jié)點(diǎn)并排序,檢查自己創(chuàng)建的節(jié)點(diǎn)是否為最小節(jié)點(diǎn);
- 若是最小節(jié)點(diǎn),則獲得鎖;否則監(jiān)聽前一個(gè)節(jié)點(diǎn)的刪除事件;
- 釋放鎖時(shí)刪除自己的臨時(shí)節(jié)點(diǎn),ZooKeeper 自動(dòng)通知下一個(gè)節(jié)點(diǎn)。
優(yōu)點(diǎn):
- 臨時(shí)節(jié)點(diǎn)在客戶端斷開連接后自動(dòng)刪除,避免死鎖;
- 順序節(jié)點(diǎn)保證公平性;
- Watch 機(jī)制實(shí)現(xiàn)高效通知。
缺點(diǎn):
- 依賴 ZooKeeper 集群,運(yùn)維復(fù)雜;
- 網(wǎng)絡(luò)抖動(dòng)可能導(dǎo)致臨時(shí)節(jié)點(diǎn)被誤刪。
3.基于數(shù)據(jù)庫的分布式鎖
最簡單的實(shí)現(xiàn)方式是創(chuàng)建一張鎖表,包含資源名稱(唯一索引)和持有者信息。加鎖時(shí)插入記錄,利用數(shù)據(jù)庫的唯一約束保證互斥;釋放鎖時(shí)刪除記錄。
它的缺點(diǎn)是性能差、存在單點(diǎn)故障、無法自動(dòng)釋放(若客戶端宕機(jī))。改進(jìn)方式包括引入過期時(shí)間字段,配合定時(shí)任務(wù)清理,但存在精度問題和性能問題。
小結(jié)
分布式鎖的常見實(shí)現(xiàn)方案有:基于 Redis 的分布式鎖實(shí)現(xiàn)、基于 Zookeeper 的分布式鎖實(shí)現(xiàn),以及基于數(shù)據(jù)庫的分布式鎖實(shí)現(xiàn),但其中使用 Redisson 框架(基于 Redis 實(shí)現(xiàn))實(shí)現(xiàn)分布式鎖的方案使用的最多,因?yàn)樗鼰o需單獨(dú)部署中間件服務(wù),并且使用簡單,不存在鎖重入和解決了鎖續(xù)期等問題。































