淺入淺出分佈式鎖(Redis)的所有細節
八股之分佈式鎖(Redis)
面試中,求職者常高估自己精通度卻忽略細節,我們從頭到尾,將問題捋一捋!
分佈式鎖基本概念
-
• 鎖的核心定義:當一個線程獲取鎖後,其他線程無法獲取,必須等待解鎖才能繼續執行,確保資源互斥訪問。
-
• 面試場景:面試者簡歷中常寫 “精通高併發、高可用” 項目,但被問及分佈式鎖實現時,只能模糊回答 “Redis”,"setnx",“Lua 腳本” 等關鍵詞,缺乏細節。
-
• 關鍵屬性:鎖需具備互斥性(exclusivity)和原子性(atomicity),避免多個線程同時訪問共享資源。
2. 鎖的互斥性與原子性實現
-
• 互斥性原理:一個線程獲取鎖後,其他線程被阻塞,無法執行關鍵代碼段。
-
• 原子性保證:
解鎖時需先判斷鎖是否屬於當前線程,再釋放,避免誤釋放他人鎖。 -
• Redis 實現:使用
SET命令(如SET key value NX EX timeout)保證原子性,因爲 Redis 命令是單線程執行,天然具備原子性。 -
• 問題場景:線程獲取鎖後崩潰,鎖未釋放怎麼辦?需爲鎖設置過期時間(timeout),確保自動釋放。
-
• 超時風險:業務未執行完鎖已超時釋放,其他線程可能獲取鎖,導致數據不一致。
3. 看門狗機制
-
• 機制作用:防止鎖在業務執行中超時釋放,通過後臺線程定期續期鎖的過期時間。
-
• 實現細節:
-
• 看門狗線程(watchdog thread)定時執行續期操作(如每 10 秒續期一次)。
-
• 業務線程掛掉時,看門狗線程需自動終止:將看門狗設爲
守護線程(daemon thread),其生命週期依賴業務線程;業務線程終止,守護線程隨之結束。 -
• 問題與解決:
-
• 業務線程掛掉後,守護線程終止,避免鎖永久佔用。
-
• 遞歸或方法調用中,線程多次獲取同一鎖需支持可重入性。
可重入鎖實現
-
• 可重入需求:同一線程在遞歸或嵌套方法中多次獲取同一鎖時,不應阻塞(如 Java 的
synchronized鎖)。 -
• 不可重入風險:線程重複獲取鎖失敗,導致死鎖(deadlock)。
-
• 實現方案:
-
• 計數器機制:類似 Java 的
synchronized,使用鎖計數器(lock counter),重入一次計數器加 1,釋放一次減 1,減到 0 時完全釋放鎖。 -
• Redis 實現:
-
• 方案 1:用 Redis 哈希結構(hash),key 爲鎖名,field 爲線程 ID(thread ID)和 UUID(保證唯一性),value 爲重入次數(counter)。
-
• 方案 2:服務內部維護併發哈希映射(concurrent hash map),value 作爲計數器。
-
• 關鍵細節:線程 ID 需結合 UUID 確保分佈式環境唯一性,避免 ID 衝突。
鎖的阻塞設計
-
• 阻塞鎖(blocking lock):線程未搶到鎖時不直接失敗,而是等待重試。
-
• 實現方式:
-
• 自旋(spin):
線程不斷重試搶鎖,適用於低競爭場景;部分公司分佈式鎖採用此方案。 -
• Redis 優化:用發佈訂閱(pub/sub)機制:未搶到鎖的線程訂閱頻道(channel);持有鎖的線程釋放後發佈消息,訂閱線程被喚醒並重試搶鎖。
-
• 超時控制:設置等待超時時間(timeout),避免無限等待。
主從架構問題與解決方案
-
• 主從問題(master-slave issue):Redis 主節點加鎖後未同步到從節點就崩潰,新主節點無鎖數據,其他線程仍能加鎖成功,導致鎖失效。
-
• 解決方案—RedLock 基礎:
-
• 連鎖機制(multi-lock):部署多組 Redis 主節點,加鎖需所有主節點成功纔算成功;即使某節點崩潰,其他節點數據可保證鎖安全。
-
• 侷限性:節點加鎖失敗率高(如網絡延遲或節點宕機),性能差且需回滾數據。
RedLock 機制
-
• 原理:由 Redis 官方提出,要求部署多個獨立 Redis 主節點(無主從關係),加鎖需半數以上(majority)節點成功。
-
• 數學基礎:基於分佈式一致性算法(如 Paxos),半數以上成功可保證互斥性(一個線程成功時,其他線程無法再獲半數支持)。
-
• 實現細節:
-
• 節點加鎖超時後放棄,不等待慢節點。
-
• 嚴格時間控制:加鎖操作需在限定時間內完成。
-
• 優勢:相比連鎖機制,降低失敗率並提升性能。
RedLock 鎖的侷限性
-
• RedLock 問題:
-
• 節點間系統時間或狀態可能不一致,仍存鎖失效風險。
-
• GC 停頓(garbage collection pause)可能導致看門狗線程暫停,鎖過期未被續期。
-
• 部署複雜:需多個主節點,數據同步開銷大。
-
• 實際應用:多數公司採用簡單 Redis 鎖或自定義實現,RedLock 因複雜性和風險較少使用。
Redis 作者提出的 Redlock 方案後,馬上受到英國劍橋大學、業界著名的分佈式系統專家 Martin 的質疑!認爲這個 Redlock 的算法模型是有問題的,並寫了篇文件對分佈式鎖的設計,提出了自己的看法。之後,Redis 作者 Antirez 面對質疑,不甘示弱,也寫了一篇文章,反駁了對方的觀點,並詳細剖析了 Redlock 算法模型的更多設計細節。關於這個問題的爭論,在當時互聯網上也引起了非常激烈的討論
一般答到這裏就已經可以停下,那是領域大佬們爭論的事,普通人插不上嘴!
總結
分佈式鎖的實現與挑戰,核心包括:鎖的互斥性和原子性通過 Redis 命令保證;看門狗機制防止業務未完成時鎖超時;可重入鎖需計數器機制(如 Redis 哈希結構);主從架構易致鎖失效,RedLock 方案需半數以上節點成功加鎖但存在一致性問題。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/fluxu3rsu4cy4mbzk41QfA