亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Zookeeper中分布式鎖的原理是什么

發布時間:2021-08-09 14:49:09 來源:億速云 閱讀:149 作者:Leah 欄目:大數據

Zookeeper中分布式鎖的原理是什么,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

Zookeeper 的 ZNode 節點

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

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

臨時節點,指的是節點創建后,如果創建節點的客戶端和 Zookeeper 服務端的會話失效(例如斷開連接),那么節點就會被刪除。

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

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

Zookeeper 中所有的數據都是通過節點來存儲的,它的目錄結構就像一個文件樹,如下圖。

Zookeeper中分布式鎖的原理是什么

Zookeeper結構

圖中的 locks、register、data 這幾個目錄自定義創建的,分別用來存儲不同業務的數據,例如 locks  用來存放分布式鎖相關的信息,register 用來存放注冊中心相關的數據。

現在我們要獲取一個分布式的所,那么假設這個鎖的 K 叫做 K1,那么現在有一個客戶端 a,然后去 JK 里面去創建一個分布式的,所創建 K1  這個分布式鎖,那么他就會在 nex 這個目錄下面創建一個叫做 K1 的文件夾,叫做 K1 的文件。現在我們要獲取一個分布式的所,那么假設這個鎖的 K 叫做  K1,那么現在有一個客戶端 a,然后去 JK 里面去創建一個分布式的,所創建 K1 這個分布式鎖,那么他就會在 nex 這個目錄下面創建一個叫做 K1  的文件夾,叫做 K1 的文件。

如何實現

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

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

方案一:基于臨時節點實現(不推薦)

假設現在有客戶端 A、B、C 均來獲取同一把分布式鎖:Key1。

首先,客戶端 A 來獲取分布式鎖 Key1,那么它就會嘗試在 locks 這個目錄下去創建一個叫做 Key1 的 ZNode 節點。如果這個時候  locks 目錄里面沒有 Key1 這個 ZNode 節點,那么客戶端 A 就能成功創建 Key1 節點,這就表示客戶端 A 成功獲取到了 Key1  這把鎖鎖。

Zookeeper中分布式鎖的原理是什么

圖1

同時,客戶端 B 也來獲取 Key1 這把鎖。客戶端 B 也需要去 locks 這個目錄里面去創建 Key1 ZNode 節點,這個時候,由于 Key1  這個 ZNode 節點已經存在,所以客戶端 B 就會創建失敗。而創建失敗就表示客戶端 B 獲取鎖失敗,所以這個時候客戶端 B 就會向 Zookeeper  注冊自己的監聽器(Watcher),監聽 Key1 這個 ZNode 節點的變化(當 Key1 節點發生變化時,Zookeeper 會通知到客戶端  B)。

如果客戶端 A 和客戶端 B,是同時請求到 Zookeeper,那么 Zookeeper 它有一個機制,它會保證只會有其中一個客戶端能創建成功 Key1  這個 ZNode 節點。

Zookeeper中分布式鎖的原理是什么

圖2

同理,此時客戶端 C 來獲取 Key1 鎖時,也是無法獲取到鎖,也會把自己的 Watcher 注冊到 ZK 中,監聽 Key1 這個 ZNode  節點的變化。

當客戶端 A 處理完自己的業務邏輯之后,那么就會執行釋放鎖的操作。釋放鎖時,客戶端刪除 Key1 節點,如果節點刪除成功就表示鎖釋放成功。當 Key1  這個節點被刪除后,Zookeeper 就會通知所有監聽 Key1 這個節點的客戶端,也就是客戶端 B、C。

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

Zookeeper中分布式鎖的原理是什么

圖3

為什么不推薦

以上就是基于臨時節點這個方案去實現 Zookeeper  分布式鎖,但是這個方案通常是不被推薦的。為什么呢?這是因為使用這個方案會存在一個很大的問題:羊群效應。

什么意思呢?

從上面的過程中我們可以看到,當客戶端 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 這個臨時順序節點。

Zookeeper中分布式鎖的原理是什么

圖4

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

當客戶端 B 獲取鎖失敗之后,它會把自己的監聽器注冊到 Zookeeper,它監聽的是它前面一個臨時順序節點,也就是 001 這個順序節點。

Zookeeper中分布式鎖的原理是什么

圖5

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

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

Zookeeper中分布式鎖的原理是什么

圖6

同樣當客戶端 B 釋放鎖之后,就會將 002 刪除,002 刪除以后,Zookeeper 會通知客戶端 C,客戶端 C 發現我當前創建的臨時順序節點  003 是 Key1 這個目錄里面最小的序號,所以客戶端 C 獲取鎖成功。

看完上述內容,你們掌握Zookeeper中分布式鎖的原理是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

三都| 寿阳县| 乐东| 大连市| 融水| 离岛区| 浦县| 龙游县| 石柱| 蓬溪县| 桂阳县| 乐清市| 白城市| 将乐县| 沙河市| 德江县| 永泰县| 固阳县| 于都县| 五原县| 东阿县| 贵阳市| 页游| 保定市| 木兰县| 云霄县| 大田县| 云安县| 武冈市| 松滋市| 闽清县| 顺平县| 河西区| 会同县| 林口县| 临潭县| 沁阳市| 东丰县| 绥阳县| 达拉特旗| 贡嘎县|