面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

Redisson的看門狗和Netty的時間輪,瞭解一下?寫的過程中順便打了一下自己的臉。技術嘛,不就是在不斷打臉的過程中成長起來的嘛。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

荒腔走板聊生活

大家好,一週的時間過的飛快,轉眼間又到週末了。

老規矩,還是本號特色,先是荒腔走板的聊聊生活。

上面的圖片是我在一次跑步的過程中拍的,一隻狗子。可以看到圖片中還有一個軌跡圖,也是一隻狗子。

這個軌跡圖全長21km,剛好是一個半馬的距離,而且一路上會穿過北海、什剎海、南鑼鼓巷、雍和宮、地壇、鼓樓大街、德勝門這些比較知名的景點。我個人非常喜歡這個路線,在北京的時候跑過好幾次。

如果你在北京,也有去跑一跑這個軌跡然後發朋友圈裝逼的想法,可以在關注公眾號後,在後臺回覆“狗子跑”。我會把具體的路線圖回覆給你。

最近由於疫情,距離上次跑步已經過了很久很久了,雖然公司有跑步機,但是我一向不太習慣在跑步機上跑。

這周成都基本上解禁了,小區裡面跑步的人也慢慢出來了,所以我決定這篇文章寫完後,一定要出去跑個至少10km,準備開啟這個夏天,畢竟一到夏天,我不經意間漏出的腹肌也該出來活動活動了。

好了,說迴文章。

面試後的覆盤非常重要

之前寫了《求錘得錘之神仙打架》這篇文章,在長髮哥出錘這一小節中,裡面有寫到這樣一段話:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

於是就有讀者來問了:老哥,看門狗介紹一下唄。面試的時候被問到了,沒有回答上來。

聽到這個問題我腦海裡首先浮現出了幾個問題:

1.你面試被問到,沒有答上來,然後呢?

2.面試結束之後你沒有進行面試的覆盤嗎?

3.對於自己沒有回答上來的問題,沒有去進行探索嗎?

甚至你都忘記了當時你的面試題,只是看到我文章的時候,突然想起:哦,這題我之前遇到過,沒有解決。

這個方式是不對的,朋友。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

一次面試是一場技術的交鋒,所以面試之後的覆盤非常非常的重要,面試結束後的第一件事情就應該是回顧整個面試過程,看看在整個面試的過程中,哪些地方是自己知道但是沒有說清楚的,哪些地方是自己應該知道但是確實不知道,需要去提升的。

然後立刻、馬上、當即在手機標籤或者隨身筆記上記錄下覆盤後自己的總結出來的關鍵點。

這些關鍵點可以是表現的好的地方,但是更多的應該是需要提升的地方。

也許你也在網上看到過這個套路:面試的過程中有幾個問題沒有回答上來,最後面試官說你先回去等通知吧。於是面試結束後,你對於沒有回答上來的問題進行了學習,然後把自己的學習總結髮給面試官。面試官一看,喲,這小夥可以啊,學習能力還不錯。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

然後就真的通知你準備進行下一輪面試吧。

這招我沒用過,但是這個套路,傳遞的思想就是:在自己領域範圍內,不懂的問題,遇到了,你得主動去解決。

面試後的覆盤,非常的重要。

覆盤過程中的想法形成文字,保留下來,非常非常的重要。

形成文字了,還可以分享出去,幫助後來人。

好了,既然讀者問了這個問題,我就稍微擴展一下,把我自己知道的都分享一下。

先看示例代碼

Redisson 分佈式鎖可能大多數朋友都用過。先上個代碼給大家看看是怎麼用的。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

看到這幾行代碼,你先別往下看,你先想一想,和你自己造的輪子比起來有什麼非常明顯不一樣的地方?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

我給大家分享一下我第一次用 Redission 做分佈式鎖的時候遇到的兩個非常直觀的疑問吧。

1.value去哪裡了?

2.過期時間去哪裡了?

之前說過,如果是我們自己造輪子,基於 Redis 做分佈式鎖的話,需要向 Redis 發一條下面的命令:

SET key random_value NX PX 3000

而在我們上面的示例代碼中,為什麼只有 key 沒有 value 呢?

我們知道 value 是必須要有的。還記得《求錘得錘之神仙打架》這篇文章裡面說的,當面試官問:

你給我講一講基於Redis的加鎖和釋放鎖的細節吧。

我們從三個關鍵點中去回答:

1.原子命令加鎖。

2.設置值的時候,放的是random_value。

3.value 的值設置為隨機數主要是為了更安全的釋放鎖,釋放鎖的時候需要檢查 key 是否存在,且 key 對應的值是否和我指定的值一樣,是一樣的才能釋放鎖。所以可以看到這裡有獲取、判斷、刪除三個操作,為了保障原子性,我們需要用 lua 腳本。

所以,這個 value 是非常重要的。

另外,第 3 步,釋放鎖的時候為什麼需要 lua 腳本,也有讀者問過,其實這事幾句話就能說清楚,所以我在這裡插播一下:

你看這三個操作:獲取、判斷、刪除。

獲取操作,只讀不寫,沒有任何問題。問題就出在判斷和刪除之間。如果不是原子操作,出現了下面的情況:

1.線程 A 在判斷了 value 是自己放進去的,在執行 key 刪除操作之前,程序 GC 導致了 STW。

2.STW 期間線程 A 的鎖雖然沒有執行刪除操作,但是由於時間到期被 redis 釋放了。

3.STW 之後,在線程 A 執行刪除操作之前,線程 B 加了同樣 key 的鎖。

4.結果你猜怎麼著?線程 A 把線程 B 加的鎖刪除了。這就出問題了。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

為什麼 lua 腳本可以解決這個問題呢?

因為 lua 腳本的執行是原子性的,再加上 Redis 執行命令是單線程的,所以在 lua 腳本執行完之前,其他的命令都得等著。就不會出現上面說的情況了。

第二個問題是過期時間去哪裡了呢?

看上面的加鎖代碼,像是沒有設置過期時間似的。

我們先說說沒有過期時間的問題是什麼。很明顯嘛,容易造成死鎖。

加鎖操作的服務器,在沒有執行釋放鎖操作之前,服務器崩了。

哦豁,喜提死鎖一把。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

value去哪了?

對於這個問題,首先我們需要確定的是,value一定是有的。

當我們自己放 value 的時候,一般就是搞個隨機值,往裡面一塞就完事了。

另外,我見過網上有些分析 Redis 分佈式鎖的文章裡面 value 直接扔個 OK 進去。前面我們說過,這是不對啊,朋友們。要注意辨別。

用 Redssion 時,我們知道這個 key 肯定是框架幫我們生成了。所以我們只需要去源碼中驗證我們的想法即可。

但是,先別慌,我們還有一個更加簡單的驗證方法:程序跑起來,然後去 Redis 裡面看一眼不就完事了?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

看了一眼後發現,不錯哦,不僅驗證了我們的想法,還有意外收穫呢。

意外收穫一:我們看到了 TTL:25 說明雖然我們沒用設置過期時間,但是框架幫我們把過期時間設置好了。這部分在這一小節中先按下不表,等下一小節詳細描述。

意外收穫二:可以看到我們放進去的 why 是一個 Hash 類型。並不是我們常用的 String 類型。

很明顯,key 是 UUID:1,這個 1 是什麼含義呢?

為什麼要用 Hash 類型,而不用 String 類型呢?

我們帶著這兩個疑問去看一眼源碼。

注意本文中的 Redssion 的 Maven 版本為 3.12.3。

Redssion 的源碼非常好 Debug,我建議你自己實際操作一遍。

首先 lock 操作會調用到這個方法:

<code>

org

.redisson

.RedissonLock

#lock

(

long

,

java

.util

.concurrent

.TimeUnit

,

boolean

)/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

可以看到,在這裡的時候,獲取到的 thredId 就是 1。那 key 裡面 UUID 後面拼接的 1。是不是就是這裡來的呢?我們接著往下看。

再往前 Debug 三步就能到下面的這個位置:

<code>

org

.redisson

.RedissonLock

#tryLockInnerAsync

/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

到這裡的 getLockName(threadId) 其實就是我們要找的東西:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

你看,這一串東西,不就是我們剛剛看到的 UUID:1 嗎?這個 1 就是線程ID。

什麼?你問我為什麼說這個 id 是 UUID?

直覺,程序猿的直覺告訴我,這就是個 UUID。但是我可以給你驗證一下。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

這個 id 的來源是下面這個接口:

<code>

org

.redisson

.connection

.ConnectionManager

/<code>

而該接口有 5 個實現類:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

在創建 ConnectionManager 時,每個實現類的構造方法傳的都是 UUID。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

所以,我們可以下結論了:

使用 Redssion 做分佈式鎖,不需要明確指定 value ,框架會幫我們生成一個由 UUID 和 加鎖操作的線程的 threadId 用冒號拼接起來的字符串。

毫無挑戰甚至有點無聊的探索過程啊。(其實我想表達的是源碼真的不難,不要抱有恐懼的心理,帶著問題去看源碼。)

但是彆著急,這只是開胃菜。

對於第二個問題:為什麼要用 Hash 類型,而不用 String 類型呢?

我們在下一節,尋找過期時間去哪裡了的同時,尋找該問題的答案。

過期時間去哪了?

這個問題,我們從這段代碼裡面可以找到答案:

<code>

org

.redisson

.RedissonLock

#tryLockInnerAsync

/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

我們首先看一下這個方法對應的幾個入參:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

主要關注我框起來的部分:

script:是要執行的 lua 腳本。

keys:是 redis 中的 key。這裡的 why 就是 KEYS[1]。

params:是 lua 腳本的參數。這裡的 30000 就是 ARVG[1]。UUID:thredId 就是 ARVG[2]。

所以這個過期時間我們也知道了,默認是 30000ms,即30s。

知道了上面三個參數的含義後,我們再來拆解這個 lua 腳本就很簡單了,首先我們把他拆解為三部分:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

第一部分:加鎖

先看第一部分的加鎖操作:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

第 4行,首先用 exists 判斷了 KEYS[1] (即 why)是否存在。

如果不存在,則進入第 5 行,使用 hincrby 命令。hincrby 命令是幹什麼的知道吧?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

之後進入第 6 行,對 KEY[1] 設置過期時間,30000ms。

然後,第7行,進行返回為 nil,結束。

這樣,一個原子性的加鎖操作就完成了。

到這裡,我們就已經從源碼的角度驗證了:因為用的是 hincrby 命令,Redssion 做鎖的時候 key 確實是一個 Hash 結構。

第二部分:重入

當第一部分的 if 分支判斷 KEYS[1] 是存在的,則會進入到這個分支中:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

由於 KEYS[1] 是一個 Hash 結構,所以第 13 行的意思是獲取這個 KEYS[1] 中字段為 ARGV[2] 的數據,判斷是否存在。

如果存在,則進入第 14 行代碼,用 hincrby 命令對 ARGV[2] 字段進行加一操作。

然後第 15 行,沒啥說的,就是重新設置過期時間為 30s。之後第 16 行,返回為 nil,結束。

所以,你在感受一下第 14 行代碼的作用是什麼?進入,然後加一,你聯想到了什麼?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

看到這裡的時候,

解鎖的 lua 腳本都不必看的,想也能想到,肯定是有一個減一的操作,然後減到 0,就釋放這把鎖。一會我們就去驗證這個點。

所以,這裡也就解釋了為什麼 Redssion 需要用 Hash 類型做鎖。因為它支持可重入呀。

你用 String 類型,你怎麼實現重入功能,來鍵盤給你,實現一個,讓我學習一下?(其實也是可以的,就是有點背道而馳了。沒意義。)

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

第三部分:返回

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

一行代碼,問題不大。作用就是返回 KEY[1] 的剩餘存活時間。

通過分析 lua 的這三部分,我們知道了:過期時間默認是 30s。當一個 key 加鎖成功或者當一個鎖重入成功後都會返回空,只有加鎖失敗的情況下會返回當前鎖剩餘的時間。

記住這個結論,我們在接下來的看門狗咋工作的這一小節中會用到這個返回值。

另外,寫文章的時候我發現 Redssion 的最新版本 3.12.3 和之前的版本相比,加鎖時的 lua 腳本有一個細微的差別,如下:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

3.12.3 版本之前用的是 hset ,現在用的是 hincrby。所以導致第一部分和第二部分相似度有點高。看起來會有點容易迷糊。

你去網上找應該看到的都是說 hset 操作的。因為 3.12.3 版本剛剛發佈一個月。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

恭喜你,朋友,又學到了一個用不上的知識點。

看門狗咋工作的?

看到這一節的朋友們,辛苦了。在這一節,我們終於要看到看門狗長啥樣了。

<code>

org

.redisson

.RedissonLock

#tryAcquireAsync

/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

這裡的 ttlRemaining 就是經過 lua 腳本後返回的值。經過前面我們知道了,當加鎖成功或者重入成功後會返回 null。進入這個方法:

<code>

org

.redisson

.RedissonLock

#scheduleExpirationRenewal

/<code>

這個方法,就是看門狗工作的片區了。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

Debug之後,你會遇到這個方法:

<code>

org

.redisson

.RedissonLock

#renewExpiration

/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

很明顯,從上面標註的數字可以看出來:

①:這是一個任務。

②:這任務需要執行的核心代碼。

③:該任務每 internalLockLeaseTime/3ms 後執行一次。而 internalLockLeaseTime 默認為 30000。所以該任務每 10s 執行一次。

接著我們看一下 ② 裡面執行的核心代碼是什麼:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

這個 lua 腳本,先判斷 UUID:threadId 是否存在,如果存在則把 key 的過期時間重新設置為 30s,這就是一次續命操作。

來,在做個小學二年的算法題:

應用題:key 默認的過期時間是 30s,每過 30s/3 的時候會去進行續命操作,那麼每當 key 的 ttl(剩餘時間)返回多少的時候,會進行續命操作?

答:由題幹可知,30s/3 = 10s。於是得公式到:30s - 10s =20s。

所以,每當 key 的 ttl(剩餘時間)為 20 的時候,則進行續命操作,重新將 key 的過期時間設置為默認時間 30s。

注意我上面一直強調的是默認時間 30s

因為這個時間是可以修改的,比如我們想要修改為 60s,就這樣:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

於是 internalLockLeaseTime 就變成了 60000 了:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

那麼附加題就來了。

附加題:閱讀上面材料後,當默認時間被修改為 60s 後,那麼每當 key 的 ttl(剩餘時間) 返回多少的時候,會進行續命操作?

答:由題可得,時間每過 60s/3 = 20s 時,任務會被觸發,看門狗進行工作。

所以,60s -20s =40s。每當 key 的 ttl 返回 40 時,會進行續命操作。

得學會變形,朋友們,明白嗎?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

接下來,我們看看這個 task 任務是怎麼實現的。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

可以看到,這個 Timeout 是 netty 包裡面的類。

這個 task 任務是基於 netty 的時間輪做的。

面試官追問你:啥是時間輪?

你又不知道。那你接著往下看。

時間輪又是啥?

你聽到了時間輪,你首先想到了啥?

聽到這個詞,就算你完全不知道時間輪,你也該想到,輪子嘛,不就是一個環嘛。

網上隨便一搜,你就知道它確實長成了一個環狀:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

它的工作原理如下:

圖片中的時間輪大小為 8 格,每格又指向一個保存著待執行任務的鏈表。

我們假設它每 1s 轉一格,當前位於第 0 格,現在要添加一個 5s 後執行的任務,則0+5=5,在第5格的鏈表中添加一個任務節點即可,同時標識該節點round=0。

我們假設它每 1s 轉一格,當前位於第 0 格,現在要添加一個 17s 後執行的任務,則(0+17)% 8 = 1,則在第 1 格添加一個節點指向任務,並標記round=2,時間輪每經過第 1 格後,對應的鏈表中的任務的 round 都會減 1 。則當時間輪第 3 次經過第 1 格時,會執行該任務。

需要注意的是時間輪每次只會執行round=0的任務。

知道了工作原理,我們再看看前面說的 Timeout 類,其實就是 HashedWheelTimer 裡面 newTimeout 方法的返回:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

前面我們分析了,在 Redssion 實現看門狗功能的時候,使用的是 newTimeout 方法。該方法三個入參:

1.task,任務,對於 Redssion 看門狗功能來說,這個 task 就是把對應的 key 的過期時間重置,默認是 30s。

2.delay,每隔多久執行一次,對於 Redssion 看門狗功能來說,這個 delay 就是 internalLockLeaseTime/3 算出來的值,默認是 10s。

3.unit,時間單位。

其實,你發現了嗎,這個時候我們已經脫離了 Redssion 進入 Netty 了。

我們只需要告訴 newTimeout 方法,我們要每隔多少時間執行一次什麼任務就行。

那我們為什麼不自己寫個更加簡單的,易於理解的 Demo 來分析這個時間輪呢?

比如下面這樣的:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

上面的 Demo 應該是很好理解了。

到這裡,我們知道了看門狗是基於定時任務實現的,而這個定時任務是基於 Netty 的時間輪實現的。

對於 HashedWheelTimer 的源碼,開始我還想進行一個導讀,寫著寫著去查閱資料的時候發現,這個鏈接裡面的對於源碼的解讀已經很到位了,我索性把自己的寫那部分刪除了,大家有興趣的可以去閱讀一下:

<code>

https

:/<code>

另外,關於時間輪,還可以看一下 IBM 論壇裡面的這篇文章《淺析 Linux 中的時間編程和實現原理》:`

<code>

https:

/

/www.ibm.com/developerworks

/cn/linux

/1308_liuming_linuxtime3/index

.html/<code>
面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

解鎖操作

還記得我們加鎖操作的時候說的嗎?

<code>

進入,然後加一,你聯想到了什麼?

這不就是可重入鎖嗎!

看到這裡的時候,解鎖的

lua

腳本都不必看的,想也能想到,肯定是有一個減一的操作,然後減到

0

,就釋放這把鎖。

一會我們就去驗證這個點。

/<code>

這一小節,我們就去驗證這個點,請看下面的釋放鎖執行的 lua 腳本:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

是不是裡面有個 counter 的判斷,如果減一後小於等於 0。就執行 del key 的操作。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

解鎖操作確實挺簡單,主要是 del 之後執行了一個 publish 命令。你猜這裡 publish 的是啥?

先猜再驗證嘛,大膽假設,小心求證!

這裡是基於 redis 的發佈/訂閱功能。解鎖的時候發佈了一個事件,你覺得通知的是什麼玩意?

肯定是告訴別的線程,我這邊鎖用完了,你來獲取吧。

別的線程是什麼線程呢?

就是想要申請同一把鎖的線程。

tryAcquire 的代碼我們之前分析過,當 ttl 不為 null 時,只有一種情況,那就是加鎖失敗:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

所以加鎖失敗的線程就執行了 subscribe 方法,完成了訂閱。

這樣,就和釋放鎖時的 publish 操作呼應上了。

接下來就只剩下一個問題沒有解決了:怎麼讓看門狗知道不用續命了?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

其實就是在執行完解鎖的 lua 腳本之後,通過響應式編程,完成了 cancel 操作。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

自此,我們的加鎖、看門狗續命、解鎖的一套操作就完成了。

補充說明,順便打臉

在打臉之前,我先問個問題吧:看門狗什麼情況下會失效?

別給我說宕機,宕機之後,由於線程沒了,看門狗只是不續命了, redis 裡面的 key 到期之後就刪除了。

我問的失效是指什麼時候完全就不啟動?

答案是,調用 lock 方法的時候傳進一個指定時間,這樣如果指定時間之內沒有調用 unLock 方法,該鎖還是會被釋放的。就像下面這樣:

rLock.lock(5,TimeUnit.SECONDS);

該鎖在 5s 之後就會自動釋放了。不會進行續命操作!!!

對應的源碼如下,注意看我寫的註釋:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

所以,我想起很久之前我在群裡說的這個,紅框框起來的部分是錯的:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

明確指定了超時時間的時候,是不會啟動看門狗機制。

自己打自己臉的事......

好爽啊,這事我經常幹。

而且,

讀書人的事,這能叫打臉嗎?這叫成長。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

另外,這圖畫的挺好的,分享給大家:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

圖片來源:
https://juejin.im/post/5bf3f15851882526a643e207

還有一個讀者提出的問題,續租的時候,是否需要進行次數的限制?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

我覺得是不需要限制的,如果你的代碼一直在進行續期操作,說明兩種情況:

1.由於某種異常原因,導致你本次需要處理的數據比之前的多,所以,需要的時間更長,導致一直在進行續期操作。

2.你的代碼有問題,導致了死循環,也就是死鎖的出現,這個鍋,Redssion 不背。

最後,還有一個問題,這鎖安全嗎,或者說你覺得會有什麼問題?

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

什麼?你不知道?

之前分享過的文章中說過了:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

節點之間異步通信,會出現上面描述的情況。所以 Redis 推出的解決方案是啥?

RedLock,之前寫的《求錘得錘之神仙打架》這篇文章,就是講 RedLock 的。如果你不知道,你就去瞅一眼。

其實後來有一天我突然想到, 如果從 CAP 的角度上去看 Redis 分佈式鎖問題,我覺得可能更好理解一點。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

分佈式鎖的一致性要求 CP,但是Redis 集群架構之間的異步通信滿足的是 AP ,因此對不上呀,就是有問題的啊。

但是為什麼 Redis 做分佈式鎖還是那麼流行呢?

可能是因為大多場景中可以容忍它的這個問題,也可能是使用者存在僥倖心理吧,或者說使用者就當個黑盒使用,根本不知道可能會出問題。

最後說一句(求關注)

寫完之後一看時間又是凌晨 2 點過了:

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

點個“在看”吧,周更很累的,不要白嫖我,需要一點正反饋。

面試時遇到『看門狗』脖子上掛著『時間輪』,我就問你怕不怕?

才疏學淺,難免會有紕漏,如果你發現了錯誤的地方,還請你留言給我指出來,我對其加以修改。(我每篇技術文章都有這句話,我是認真的說的。)

感謝您的閱讀,我堅持原創

,十分歡迎並感謝您的關注。

我是why技術,一個不是大佬,但是喜歡分享,又暖又有料的四川好男人。


分享到:


相關文章: