大家好,我是小米,今年 31 歲,一個在 Java 世界裏摸爬滾打多年的程序員大哥哥。

前幾天,我在幫朋友模擬社招面試的時候,面試官突然拋出一個問題:

“你瞭解 Redis 的 RedLock 嗎?它解決了什麼問題?”

朋友愣了三秒鐘,憋出一句:

“呃……分佈式鎖的一種實現?”

面試官點點頭,又補了一刀:

“那為什麼要有 RedLock?SETNX 不行嗎?”

好,熟悉的氣息來了。這是一個典型的:面試官想看看你“到底理解到哪一層”的問題。

今天這篇文章,我不打算一上來就甩論文、甩算法、甩名詞。我們還是老規矩講個故事。

故事的開始:全村只有一把鎖

想象一個場景。你住在一個村子裏,村裏有一間公共倉庫,裏面放着村裏唯一的“寶貝資源”:比如水泵、電動車充電口、發電機。

為了避免大家同時搶,村長規定:誰用,誰先拿鎖。這把鎖就掛在倉庫門口。

單機時代:一把鎖,世界和平

一開始,村子很小,只有一個倉庫。

  • 鎖是真的鎖
  • 鑰匙只有一把
  • 誰先拿到,誰用

這就像:單體應用 + 本地鎖(synchronized / ReentrantLock)

簡單、直接、世界和平。

問題來了:村子擴張了(分佈式時代)

後來,村子發展了。

  • 東村
  • 西村
  • 南村
  • 北村

每個村口都建了一個倉庫副本,數據是同步的。於是問題來了:“鎖放哪?”

如果還只有一把鎖,大家跑來跑去,效率極低。於是村長拍板:“每個倉庫門口,都放一把鎖!”

聽起來很合理,對吧?

Redis 分佈式鎖的第一形態:SETNX

這時候,我們就進入了Redis 分佈式鎖的基礎階段

Redis 單節點鎖的思路

在 Redis 裏,我們通常這麼做:

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_加鎖

含義是:

  • NX:只有不存在才設置(加鎖)
  • PX:設置過期時間(防止死鎖)

Java 示例代碼:

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_加鎖_02

這套方案,在單 Redis 實例下,基本可用。

單點問題:鎖的“唯一倉庫”塌了

故事開始變得刺激。有一天,西村倉庫塌了(Redis 宕機)。發生了什麼?

  • 鎖沒了
  • 其他人以為“鎖不存在”
  • 大家一起衝進倉庫

問題本質:單個 Redis 節點 = 單點故障

只要 Redis 掛了:

  • 鎖狀態丟失
  • 分佈式一致性直接破產

進階方案:主從 + 哨兵,夠了嗎?

你可能會説:“那我用 Redis 主從 + 哨兵不就好了?”

這是一個非常典型的面試陷阱點主從複製的時間差問題。

Redis 的主從複製是:異步複製。想象這個場景:

  1. 客户 A 在 Master 上加鎖成功
  2. Master 還沒來得及同步給 Slave
  3. Master 宕機
  4. Slave 被提升為 Master
  5. 客户 B 再次加鎖成功

結果是:兩個客户端,同時持有“同一把鎖”

故事轉折:村長髮明瞭“五把鎖機制”

這時候,村長終於意識到:“不能只信一把鎖了。”

於是他提出一個瘋狂的方案:在 5 個獨立的倉庫裏,各放一把鎖,誰能同時拿到其中 3 把,誰才算真的拿到鎖。”

這,就是 RedLock 的核心思想

什麼是 RedLock?一句話説清楚

RedLock 是 Redis 作者提出的一種基於多個獨立 Redis 節點的分佈式鎖算法,通過“多數派原則”來提升鎖的可靠性。

關鍵詞拆解一下:

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_加鎖_03

RedLock 的加鎖流程(面試必考)

RedLock 的加鎖流程,面試官最愛問。

加鎖步驟

假設有 5 個 Redis 節點:

1、記錄當前時間 T1

2、依次向 5 個 Redis 節點嘗試加鎖

3、每個節點使用相同的:

  • key
  • value
  • 過期時間

4、如果:

  • 成功節點 ≥ 3
  • 且總耗時 < 鎖過期時間

5、則加鎖成功

6、否則:

  • 向已成功的節點釋放鎖
  • 加鎖失敗

RedLock 的核心判斷條件(表格版)

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_加鎖_04

RedLock Java 代碼示例(基於 Redisson)

現實中,我們不建議手寫 RedLock。最常用的是 Redisson

1、Maven 依賴

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_Redis_05

2、配置多個 Redis 節點

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_分佈式鎖_06

3、使用 RedLock

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_Redis_07

RedLock 的優點和爭議(高階加分點)

優點

面試官一問 RedLock,我才發現自己以前真的只會用 Redis_加鎖_08

爭議(面試官最喜歡的)

Redis 官方作者提出,但學術界和工程界一直有爭論

  • 網絡分區問題
  • 時間漂移問題
  • 鎖有效性依賴系統時間

Martin Kleppmann 曾公開質疑:“RedLock 並不能在所有情況下保證安全性。”

面試官真正想聽的答案是什麼?

當面試官問:“你怎麼看 RedLock?”

一個成熟的回答是:

  • RedLock 適合高可用場景
  • 成本較高,複雜度高
  • 並非強一致性方案
  • 是否使用,取決於業務容錯能力

總結

最後,用一句話總結:

RedLock 不是銀彈,它只是在“可用性”和“複雜度”之間,給出的一種工程折中方案。

如果你的業務:

  • 能容忍極小概率的鎖失效
  • 對可用性要求極高

RedLock 值得考慮。

如果你的業務:

  • 對一致性要求極端嚴格
  • 不能接受任何併發錯誤

請考慮 數據庫鎖 / Zookeeper

END

我是小米,一個喜歡分享技術的31歲程序員。如果你喜歡我的文章,歡迎關注我的微信公眾號“軟件求生”,獲取更多技術乾貨!