面試題 Zookeeper實現分布式鎖的原理

2021-10-21 06:30:34 字數 4474 閱讀 1759

在面位元組跳動時,遇到了這道面試題:如何用 zookeeper 實現分布式鎖?

相信大部分面試都是說用 redis 去實現分布式鎖,用 zookeeper 實現分布式鎖相對而言遇到的較少,最近在整理之前的面經答案,因此特意寫篇部落格解釋一下。

實現一把分布式鎖通常有很多方法,比較常見的有 redis 和 zookeeper。相信大家對 redis 實現分布式鎖已經非常了解,今天介紹的是如何通過 zookeeper 去實現一把分布式鎖。

首先 zookeeper 為什麼能實現一把分布式鎖呢?這是因為它有乙個特性,就是多個執行緒去 zookeeper 裡面去建立同乙個節點的時候,只會有乙個執行緒去執行成功。

在了解 zookeeper 實現分布式鎖之前,首先,我們需要了解 zookeeper 裡面節點相關的知識。

zookeeper 裡面的節點可以分為兩大類,一種是臨時節點,一種是持久化節點。

臨時節點,指的是節點建立後,如果建立節點的客戶端和 zookeeper 服務端的會話失效(例如斷開連線),那麼節點就會被刪除。

持久化節點指的是節點建立後,即使建立節點的客戶端和 zookeeper 服務端的會話失效(例如斷開連線),節點也不會被刪除,只有客戶端主動發起刪除節點的請求,節點才會被刪除。

另外還有一種節點叫做有序節點,這種節點在建立時會有乙個序號,這個序號是自增的。有序節點既可以是有序臨時節點,也可以是有序持久化節點。

zookeeper 中所有的資料都是通過節點來儲存的,它的目錄結構就像乙個檔案樹,如下圖。

圖中的 locks、register、data 這幾個目錄自定義建立的,分別用來儲存不同業務的資料,例如 locks 用來存放分布式鎖相關的資訊,register 用來存放註冊中心相關的資料。

採用 zookeeper 實現分布式鎖,有兩種方案:1. 基於臨時節點實現; 2. 基於臨時順序節點實現。下面以及介紹這種方案的實現原理。

首先,假設所有的分布式鎖都儲存在 locks 這個目錄中。

假設現在有客戶端 a、b、c 均來獲取同一把分布式鎖:key1。

首先,客戶端 a 來獲取分布式鎖 key1,那麼它就會嘗試在 locks 這個目錄下去建立乙個叫做 key1 的 znode 節點。如果這個時候 locks 目錄裡面沒有 key1 這個 znode 節點,那麼客戶端 a 就能成功建立 key1 節點,這就表示客戶端 a 成功獲取到了 key1 這把鎖鎖。

同時,客戶端 b 也來獲取 key1 這把鎖。客戶端 b 也需要去 locks 這個目錄裡面去建立 key1 znode 節點,這個時候,由於 key1 這個 znode 節點已經存在,所以客戶端 b 就會建立失敗。而建立失敗就表示客戶端 b 獲取鎖失敗,所以這個時候客戶端 b 就會向 zookeeper 註冊自己的***(watcher),監聽 key1 這個 znode 節點的變化(當 key1 節點發生變化時,zookeeper 會通知到客戶端 b)。

如果客戶端 a 和客戶端 b,是同時請求到 zookeeper,那麼 zookeeper 它有乙個機制,它會保證只會有其中乙個客戶端能建立成功 key1 這個 znode 節點。

同理,此時客戶端 c 來獲取 key1 鎖時,也是無法獲取到鎖,也會把自己的 watcher 註冊到 zk 中,監聽 key1 這個 znode 節點的變化。

當客戶端 a 處理完自己的業務邏輯之後,那麼就會執行釋放鎖的操作。釋放鎖時,客戶端刪除 key1 節點,如果節點刪除成功就表示鎖釋放成功。當 key1 這個節點被刪除後,zookeeper 就會通知所有監聽 key1 這個節點的客戶端,也就是客戶端 b、c。

當客戶端閉 b 和 c 接到通知以後,知道 key1 節點發生了變化,這個時候它們就會重新去請求 zookeeper,嘗試在 locks 目錄下面建立 key1 節點,這個時候也只會有乙個客戶端創能成功建立 key1 節點。假如說是客戶端 b 建立成功了,那麼就表示客戶端 b 成功獲取到了鎖.客戶端 c 獲取鎖失敗,那麼就繼續去監聽 key1 這個節點的變化。

為什麼不推薦

什麼意思呢?

從上面的過程中我們可以看到,當客戶端 a 釋放鎖成功以後,zookeeper 需要去通知所有監聽 key1 這個節點的客戶端。上面我們的例子中只有客戶端 b 和客戶端 c,但是在實際應用中可能有成百上千個客戶端,甚至更多。zookeeper 在這一瞬間需要傳送成百上千個請求,首先這個效率顯然是不高的,另外當分布式鎖的競爭較為激烈時,極有可能在這一瞬間 zookeeper 的網絡卡可能被撐爆。而且系統中可能並不僅僅存 key1 這一把鎖,還會存在 key2、key3、key4…,這些鎖也會存在競爭,zookeeper 的壓力會更大。

在這個過程中,我們很明顯地能感覺到這是不合理的,因為獲取分布式鎖時肯定是只有其中乙個客戶端能獲取到,那麼當 key1 這個節點被刪除以後,需要通知其他的客戶端來獲取鎖,這個時候我們有必要去通知所有的客戶端嗎?

顯然是沒有必要的,我們只需要通知其中乙個客戶端就可以了。因此方案二出現了。

基於臨時順序節點去實現分布式鎖時,就不是在 linux 這個目錄下面建立 key1 這個臨時節點了。而是先在 locks 這個目錄下面建立乙個 key1 目錄,然後在 key1 目錄裡面去建立臨時順序節點。

假設現在客戶端 a 來獲取分布式鎖 key1,那麼這個時候客戶端 a 就會在 key1 這個目錄裡面建立乙個臨時順序節點,這個臨時順序節點的序號是 001。

然後客戶端 a 會判斷自己建立的這個臨時順序節點 001 在 key1 這個目錄裡面,它的序號是不是最小的?如果是最小的,那麼就表示客戶端 a 獲取鎖成功。

接著客戶端 b 也來獲取 key1 這個分布式鎖,它也會在 key1 這個目錄下面去建立乙個臨時順序節點,由於這個時候自增序號已經變為 002 了,因為之前已經建立過 001 了,所以客戶端 b 會建立 002 這個臨時順序節點。

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-khkyvsct-1615016620172)(

同理,客戶端 b 也會判斷自己當前建立的臨時順序節點 002,是不是當前 key1 目錄中序號最小的臨時節點,顯然不是,因為前面有乙個 001 臨時順序節點,所以客戶端 b 這個時候是獲取鎖失敗。

當客戶端 b 獲取鎖失敗之後,它會把自己的***註冊到 zookeeper,它監聽的是它前面乙個臨時順序節點,也就是 001 這個順序節點。

此時如果客戶端 c 也來獲取分布式鎖 key1,這個時候它就會在 key 目錄中建立臨時順序節點 003,同樣 003 也不是序號最小的臨時順序節點,所以客戶端 c 也獲取鎖失敗,接著它會去監聽 002 這個臨時順序節點。

當客戶端 a 處理完業務邏輯之後,它就會去釋放鎖。釋放鎖的操作就是去刪除 key1 這個目錄下面客戶端 a 所建立的臨時順序節點,也就是刪除 001 這個臨時順序節點。當 001 這個順序節點被刪除以後,zookeeper 就會去通知監聽 001 這個順序節點的所有客戶端,也就是通知客戶端 b。客戶端 b 接收到 zookeeper 的通知之後,它就會去判斷我當前建立的臨時順序節點 002 是不是當前 key1 這個目錄中序號最小的乙個臨時順序節點。此時由於 001 這個順序節點已經不存在了,顯然 002 是最小的了,因此客戶端 b 就獲取鎖成功。

同樣當客戶端 b 釋放鎖之後,就會將 002 刪除,002 刪除以後,zookeeper 會通知客戶端 c,客戶端 c 發現我當前建立的臨時順序節點 003 是 key1 這個目錄裡面最小的序號,所以客戶端 c 獲取鎖成功。

當客戶端 a 獲取鎖成功以後,長時間不釋放鎖,或者說客戶端 a 所在的機器宕機,或者客戶端 a 所在的機器出現網路故障,這個時候會出現什麼狀況?

當客戶端 a 所在的機器出現宕機,或者出現網路故障後,長時間不和 zookeeper 通訊的時候,客戶端 a 和 zookeeper 之間建立的 session 就會失效,當這個 session 失效以後,zookeeper 會將客戶端 a 所建立的臨時順序節點給直接刪除,這個時候其他的客戶端就能正常獲取鎖了。

阿里面試題:線上介面變慢,如何排查

ZooKeeper面試題一

1.zookeeper 是什麼?zookeeper 是乙個 分布式 的,開放原始碼的分布式 應用程式協調服務 是 google 的 chubby 乙個開源的實現,它是 集群的管理者 監視著集群中各個節點的狀態根據節點提交的反饋進行下一步合理操作 最終,將簡單易用的介面和效能高效 功能穩定的系統提供給...

Zookeeper面試題集錦

目錄 一 什麼是zookeeper?二 zookeeper保證的是哪些特性?三 zookeeper的讀寫原理?四 怎麼解釋zookeeper的有序性?五 zookeeper提供了什麼?六 zookeeper的檔案系統是什麼?七 zab協議是什麼?八 zookeeper包含哪幾種型別的資料節點?九 z...

面試題 ZooKeeper部分

zookeeper 是什麼?zookeeper是乙個分布式的,開放原始碼的分布式應用程式協調服務,是google的chubby乙個開源的實現,是hadoop和hbase的重要元件。它是乙個為分布式應用提供一致性服務的軟體,提供的功能包括 配置維護 網域名稱服務 分布式同步 組服務等。zookeepe...