自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

醒一醒,講到 ZooKeeper 的選舉機制了

大數(shù)據(jù)
Hi,這里是 HelloGitHub 推出的 HelloZooKeeper 系列,免費開源、有趣、入門級的 ZooKeeper 教程,面向有編程基礎(chǔ)的新手。

[[386810]]

本文轉(zhuǎn)載自微信公眾號「 HelloGitHub」,作者 HelloGitHub。轉(zhuǎn)載本文請聯(lián)系 HelloGitHub公眾號。

Hi,這里是 HelloGitHub 推出的 HelloZooKeeper 系列,免費開源、有趣、入門級的 ZooKeeper 教程,面向有編程基礎(chǔ)的新手。

項目地址:https://github.com/HelloGitHub-Team/HelloZooKeeper

今天開始我們將繼續(xù)深入 ZK 選舉相關(guān)的知識

一、選舉的基本規(guī)則

ZKr~這次我決定一反常態(tài),先不講故事了~先得聊聊在 ZK 選舉中非常重要的一些東西。

1.1 zxid

zxid 就是我們之前提到的事務(wù)編號,是一個 8 字節(jié)的整型數(shù)字,但是 ZK 設(shè)計的時候把這一個數(shù)字拆成了兩部分使用,一魚兩吃!

8 個字節(jié)的整數(shù)一共有 64 位長度,前 32 位用來記錄 epoch,后 32 位就是用來計數(shù)。你可能要問了?epoch?是啥?

zxid 初始化是 0,也就是這樣

  1. 00000000000000000000000000000000 00000000000000000000000000000000 

每一次寫請求都會增加后 32 位,假設(shè)現(xiàn)在進行了 10 次寫請求(無論該請求有沒有真的修改到數(shù)據(jù)),zxid 就會變成這樣

  1. 00000000000000000000000000000000 00000000000000000000000000001010 

當(dāng)進行一次選舉的時候,前 32 位就會增加 1,并且清零后 32 位

  1. 00000000000000000000000000000001 00000000000000000000000000000000 

除了選舉以外,當(dāng)后 32 位徹底用完(變成全 1,也就是 ZK 正常執(zhí)行了 2^32 - 1 次寫請求都沒進行過一次選舉,牛逼!)也會讓前 32 位增加 1,相當(dāng)于進位

  1. # 進位前 
  2. 00000000000000000000000000000000 11111111111111111111111111111111 
  3. # 進位后 
  4. 00000000000000000000000000000001 00000000000000000000000000000000 

到這里我就可以回答大家前面的問題了,epoch 就是 zxid 前 32 位的這個數(shù)字,epoch 本身的翻譯是“紀元,時代”的意思,意味著更新?lián)Q代,而 zxid 的后 32 位數(shù)字僅僅是寫請求的計數(shù)罷了

1.2 myid

在之前的小故事里,我給 ZK 的集群中的各個節(jié)點都起了一個好記的名字(神特么好記!)。但是 ZK 官方自己是如何給每一個集群中的節(jié)點起名字的呢?用的就是 myid!

ZK 的啟動配置 zoo.cfg 中有一項 dataDir 指定了數(shù)據(jù)存放的路徑(默認是 /tmp/zookeeper),在此路徑下新建一個文本文件,命名為 myid, 文本內(nèi)容就是一個數(shù)字,這個數(shù)字就是當(dāng)前節(jié)點的 myid

  1. /tmp 
  2. └── zookeeper 
  3.     ├── myid 
  4.     └── ... 

然后在 zoo.cfg 是這樣配置集群信息

  1. server.1=zoo1:2888:3888 
  2. server.2=zoo2:2888:3888 
  3. server.3=zoo3:2888:3888 

這個 server. 之后的數(shù)字就是 myid,這個 myid 在整個集群中,各個節(jié)點之間是不能重復(fù)的。我忘記之前在哪兒看到的了,說是 myid 只能是 1 到 255 的數(shù)字,我一直信以為真,直到這次,我本著嚴謹?shù)膽B(tài)度去做了實踐,一切以事實為主,并且我的實驗覆蓋了 3.4、3.5、3.6 三大版本(都是三臺機器的簡單集群),結(jié)論是:myid 只要是不等于 -1 就行(-1 是一個固定的值會導(dǎo)致當(dāng)前節(jié)點啟動報錯),不能大于 Long.MAX_VALUE 或者小于 Long.MIN_VALUE,但是如果在當(dāng)前的節(jié)點中配置了 zookeeper.extendedTypesEnabled=true 那當(dāng)前節(jié)點的最大 myid 是 254(負數(shù)不影響,我也不知道這個 254 的用意,但是代碼中的確有判斷) 是不是奇怪的知識又增加了呢~

關(guān)于配置更多的信息,之后單獨再整理,今天就點到為止

1.3 選舉規(guī)則

知道了上面這些有什么用呢?非常重要!因為選舉 Leader 完全看的就是這幾個值

  • epoch
  • 寫請求次數(shù)
  • myid

優(yōu)先級從上到下逐級比較,誰大誰就更有資格成為 Leader,當(dāng)前級一樣就比較下一級,直到分出勝負為止!因為 myid 是不能重復(fù)的,所以最終是一定能分出勝負的!

好了,現(xiàn)在大家知道了最基本的選舉規(guī)則了~讓我們進入下一節(jié)吧

二、三馬之爭

馬果果一定想不到,這輩子自己可以和兩位鼎鼎大名的明星企業(yè)家相提并論,讓我們一起去看看發(fā)生了什么吧~

2.1 準(zhǔn)備開工

之前馬果果規(guī)定了三個辦事處在對外開張前必須選出一個 Leader,在正式開始選之前,每一個辦事處也有一些準(zhǔn)備工作需要做:

  • 每一個辦事處必須得知道一共有多少個辦事處
  • 額外聘請一些專門負責(zé)和其他辦事處溝通的話務(wù)員
  • 準(zhǔn)備好一個票箱用來對投票統(tǒng)計和歸票
  • 為每一個辦事處設(shè)置一個固定的 myid

所以現(xiàn)在辦公室的布置變成了這樣(我省略了之前章節(jié)的其他要素):

有了這些準(zhǔn)備工作以后所有辦事處都可以進入選舉的階段了,并且村委會規(guī)定了幾種狀態(tài)用于表示當(dāng)前辦事處正處在的階段:

  • LOOKING,正在尋找 Leader,處于此階段的辦事處不能對外提供服務(wù)
  • LEADING,當(dāng)前辦事處就是 Leader,可以對外提供服務(wù)
  • FOLLOWING,當(dāng)前辦事處正在跟隨 Leader,可以對外提供服務(wù)

很明顯剛剛準(zhǔn)備好的各個辦事處現(xiàn)在都處于 LOOKING 狀態(tài),下面讓我們正式進入選舉流程吧

2.2 開始選舉

由于各個辦事處剛準(zhǔn)備好,所以彼此之間還沒有通過信,又加上大家都是姓馬的,心里面都是想當(dāng)老大的,所以每一個辦事都會率先擬一張寫著自己的選票發(fā)給其他辦事處。主要有這些信息:

  • sid:我是誰
  • leader:我選誰
  • state:我當(dāng)前的狀態(tài)
  • epoch:我當(dāng)前的 epoch
  • zxid:我選擇的 leader 的最大的事務(wù)編號

以馬果果舉例:

馬小云和馬小騰也一樣,一開始都選了自己做 Leader 候選人,并且都把自己認為的候選人(當(dāng)前場景下就是自己)的票分別發(fā)送給了其他兩位(以及自己)

2.2.1 馬果果視角

每個辦事處各自也會收到來自其他辦事處的選票(也有可能是自己的),每拿到一張選票,都需要和當(dāng)前自己認為的 Leader 候選人做比較,理論上自己投給自己的選票會先一步達到自己的票箱,因為不需要經(jīng)過通訊減少了傳輸?shù)穆窂?,自己的選票和自己的候選人是一致的所以不需要比較,只需要在票箱中記上一筆,我們還是以馬果果舉例:

=》的左邊是辦事處的名字,右邊是該辦事處選的 Leader。當(dāng)前投票統(tǒng)計是指,當(dāng)前節(jié)點所選的 Leader 獲得的選票統(tǒng)計。

假設(shè)他再收到了馬小云的選票:

  • 馬果果首先看到的是馬小云也處在 LOOKING 狀態(tài)
  • 接著就會比較自己候選人和馬小云的選票(左邊代表當(dāng)前辦事處的候選人,右邊代表收到的選票信息,下同)
  1. e:0      ==  e:0 
  2. z:0      ==  z:0 
  3. l: 馬果果(69) >   l: 馬小云(56) 

最終因為馬果果的 myid 69 要比馬小云的 myid 56 要大,所以馬果果最終勝出!雖然馬小云勝出了,但是當(dāng)前投票統(tǒng)計是不能修改的,因為馬小云這一輪的選票就是選的馬小云,需要等待他重新改票后再投才能修改投票統(tǒng)計。

之后會往投票箱記錄:

緊接著是馬小騰的投票:

  1. e:0      ==  e:0 
  2. z:0      ==  z:0 
  3. l: 馬果果(69) >   l: 馬小騰(49) 

馬果果還是勝出!

記錄投票箱:

每次收到投票的時候,馬果果都會依據(jù)當(dāng)前的投票統(tǒng)計進行歸票,但是很遺憾選舉仍然無法結(jié)束,因為結(jié)束的規(guī)則必須有某一個辦事處獲得半數(shù)以上的選票,現(xiàn)在只有一個馬果果自己的選票,不滿足半數(shù)以上,所以馬果果只能再等等了。

而在馬果果這邊忙的熱火朝天的同時,馬小云和馬小騰也在進行著同樣的動作。

2.2.2 馬小云視角

我們這省略描述馬小云記錄自己選票的過程,假設(shè)他這邊是先收到馬果果的選票,是怎么處理的呢?

  1. e:0      ==  e:0 
  2. z:0      ==  z:0 
  3. l: 馬小云(56) <   l: 馬果果(69) 

馬小云看到自己認為的 Leader 候選人被馬果果的選票擊敗了,所以將自己的候選人改為馬果果,并將新的選票重新廣播出去

然后在自己的投票箱中記錄:

為了敘述的完整性,我們還是把馬小騰的票也看完

  1. e:0      ==  e:0 
  2. z:0      ==  z:0 
  3. l: 馬果果(69) >   l: 馬小騰(49) 

馬果果還是勝出了,所以馬小云的投票箱最終變成這樣:

講道理接下來應(yīng)該以馬小騰為主視角,再講一遍剛才的過程,但是可以認為幾乎和馬小云是一樣的,為了故事的順暢,我們需要回到馬果果的視角,因為馬小云輸給馬果果之后改票了,又發(fā)了一輪選票

2.2.3 馬果果視角(再)

馬果果又再一次收到了馬小云的選票(改票后),投票箱就會改成這樣:

收到這個投票后,當(dāng)前投票統(tǒng)計就會增加馬小云的記錄,然后馬果果進行歸票就發(fā)現(xiàn)了這次自己的選票超過半數(shù)了,然后會進行二次確認,會等待一會看看還能不能收到更新的選票,這里假設(shè)沒有收到更新的投票,就會進行判斷,當(dāng)前過半數(shù)的候選人是不是自己?如果是的話,那自己就是 Leader,不是的話,自己就是 Follower。

很明顯,馬果果就是 Leader,然后會把自己的狀態(tài)修改為 LEADING。

與此同時,馬小云、馬小騰也進行歸票,歸票結(jié)果自己為 Follower,把自己狀態(tài)修改為 FOLLOWING,然后各自都會和 Leader 進行數(shù)據(jù)的同步,同步完成之后整個辦事處就都可以對外提供服務(wù)了。

2.3 馬小騰停電啦

選舉本身涉及到集群間的通信、節(jié)點自身的狀態(tài)管理和狀態(tài)變更,本身就是一個比較復(fù)雜的過程,剛才只是舉例了一個最簡單的啟動選舉流程,下面會舉更多的例子幫助大家能理解整個選舉的邏輯。

現(xiàn)在假設(shè)辦事處安然無恙得對外提供了一段時間服務(wù)后,馬小騰的辦事處突然停電了,就不能和另外兩馬進行通訊了,而另外兩馬在一段時間內(nèi)都沒有收到過馬小騰的信息的時候就知道,出事了!但是各自盤點了下目前仍然還有兩個辦事處可以對外提供服務(wù),是達到整個集群總數(shù)的半數(shù)以上的,是可以繼續(xù)讓村民們來辦理業(yè)務(wù)的,所以現(xiàn)在整個集群變成了這樣:

沒過一會,因為電力公司的積極搶修,馬小騰的辦事處恢復(fù)供電了,重新開張了,但是每一個辦事處在開張前都是處在 LOOKING 狀態(tài)的,還是會優(yōu)先投票給自己,并會通過復(fù)盤本地的存檔來得到自己辦事處最新的數(shù)據(jù),假設(shè)馬小騰停電前是這樣:

  1. e:0      
  2. z:21       
  3. l: 馬小騰(49) 
  4. LOOKING 

他和之前一樣會給另外兩個辦事處發(fā)自己的選票

但和之前的情況不同,無論是馬果果還是馬小云他們現(xiàn)在都處在工作的狀態(tài),收到了馬小騰的選票后就會把當(dāng)前的 Leader 也就是馬果果的選票信息以及自己當(dāng)前的狀態(tài)發(fā)送給他。

馬果果發(fā)送的選票信息:

  1. e:0      
  2. z:30       
  3. l: 馬果果(69) 
  4. LEADING 

馬小云發(fā)送的選票信息:

  1. e:0      
  2. z:30       
  3. l: 馬果果(69) 
  4. FOLLOWING 

馬小騰收到兩位的選票信息后,知道了當(dāng)前的 Leader 是馬果果,并且馬果果本人也確認了是 LEADING 狀態(tài),就馬上把自己的狀態(tài)修改為了 FOLLOWING 狀態(tài),并且會和之前一樣與 Leader 進行數(shù)據(jù)的同步,關(guān)于具體怎么同步的,我打算留到之后再進行講解~

同步之后,馬小騰的狀態(tài)變成了和馬小云一樣的了。

我再假設(shè)這里有一個平行世界,回到馬小騰剛恢復(fù)完供電準(zhǔn)備開張上線的時候,此時的馬小騰的狀態(tài)假設(shè)是這樣的:

  1. e:1      
  2. z:7       
  3. l: 馬小騰(49) 
  4. LOOKING 

哪怕 epoch 比目前的 Leader 還要大,其實照道理是更有資格當(dāng) Leader,但是由于當(dāng)前集群中的其他辦事處已經(jīng)有了一個明確的 Leader,馬小騰也只能忍辱負重(誰讓你停電了呢)還是以 Follower 的身份加入到集群中來,并且仍然以當(dāng)前 Leader 的信息來同步,你也可以理解為降級(把自己的 epoch 降級回 0 )

職場就是這么殘忍,你稍微請個長假再回來可能已經(jīng)是物是人非了~

2.4 馬果果又病啦

馬果果畢竟年事已高,又又又生病了,辦事處只能含淚關(guān)門,但是和上一次馬小騰停電不同,這次是作為 Leader 的馬果果停止服務(wù)了,因為之前定下的規(guī)定,整個辦事處集群必須得有一個 Leader?,F(xiàn)在馬小云和馬小騰發(fā)現(xiàn) Leader 聯(lián)系不上了,說明 Leader 無法服務(wù)了,他們就知道必須選出一個新的 Leader。于是紛紛將自己的狀態(tài)都修改為 LOOKING 狀態(tài),并且再次把候選人選為自己,重新向其他仍然可以提供服務(wù)的辦事處廣播自己的選票(當(dāng)前這個場景就是互相發(fā)選票了)。

無論誰收到選票后經(jīng)過比較后都會知道是馬小騰勝出

  1. e:1      ==  e:1 
  2. z:77      <   z:80 
  3. l: 馬小云(56)     l: 馬小騰(49) 

馬小云會把自己的候選人修改為馬小騰之后重新再把自己的選票發(fā)出去,現(xiàn)在馬小騰就獲得了 2 票通過,同時也滿足大于整個辦事處集群半數(shù)以上,所以馬小騰和馬小云各自修改狀態(tài)為 LEADING 和 FOLLOWING 后,并且會和之前說的一樣,把 epoch 加 1 同時清空計數(shù)部分,最后重新恢復(fù)對村民提供服務(wù)。

而馬果果這邊病好以后,會重新開張和之前的例子一樣也是先從 LOOKING 狀態(tài)開始,最后會從其他兩馬那里得知目前的 Leader 是馬小騰之后,就會主動和馬小騰同步數(shù)據(jù)并以 Follower 的身份加入到辦事處集群中對外提供服務(wù)。

2.5 招商引資

辦事處的熱火朝天被村委會看在了眼里,心想只有三個辦事處就能達到這樣的效果,如果有更多的辦事處呢?于是和三馬商量了下,決定對外招商引入社會資本,讓他們自己按照現(xiàn)有模式建立新的辦事處,這樣村委會不用出一分錢,村民還能獲得實在的好處,秒啊!

圖片

此舉一度引來社會資本的大量關(guān)注,但是商量過后,三馬又覺得如果過多的引入外部力量勢必會削弱自己手中的權(quán)力,所以又出了一個規(guī)定,三馬自封為 Participant 只有他們?nèi)齻€才有資格進行 Leader 的競選,而引入的社會資本所創(chuàng)建的辦事處只能作為 Observer 加入辦事處的集群中對外提供只讀服務(wù),沒有資格競爭 Leader,這樣就可以在不增加選舉復(fù)雜程度的同時,提升整個辦事處集群對讀請求的吞吐量。

要聲明當(dāng)前節(jié)點是 Observer,需要在 zoo.cfg 中先配置 peerType=observer

同時聲明的集群信息最后要多加一個 :observer 用來標(biāo)識,這樣其他節(jié)點也會知道當(dāng)前 myid 為 1 和 2 都是 Observer

  1. server.69=maguoguo:2888:3888 
  2. server.56=maxiaoyun:2888:3888 
  3. server.49=maxiaoteng:2888:3888 
  4. server.1=dongdong:2888:3888:observer 
  5. server.2=jitaimei:2888:3888:observer 

而在 LOOKING 狀態(tài)的 Observer 一開始的 Leader 候選人也會選自己,但是選票信息被設(shè)置成了這樣,以東東舉例:

  1. e:Long.MIN_VALUE      
  2. z:Long.MIN_VALUE       
  3. l: 東東(1) 
  4. LOOKING 

因為 epoch 被設(shè)置成了最小值所以這個選票等同于形同虛設(shè),可以被直接忽略,并且在三馬那里會維護一個 Participant 的列表,如果他們收到了來自 Participant 以外的辦事處的選票會直接選擇忽略,所以可以說 Observer 的選票對選舉結(jié)果是完全沒有影響的。最終是等待 Participant 之間的選舉結(jié)果通知,Observer 自身修改狀態(tài)為 OBSERVING,開始和 Leader 進行同步數(shù)據(jù),這點和 Follower 沒區(qū)別,之后 Observer 和 Follower 會統(tǒng)稱為 Learner

2.6 小結(jié)

競選 Leader 看的是 epoch、寫請求操作數(shù)、myid 三個字段,依次比較誰大誰就更有資格成為 Leader

獲選超過半數(shù)以上的辦事處正式成為 Leader,修改自己狀態(tài)為 LEADING

其他 Participant 修改為 FOLLOWING,Observer 則修改為 OBSERVING

如果集群中已經(jīng)存在一個 Leader,其他辦事處如果中途加入的話,直接跟隨該 Leader 即可

還得提一句,如果當(dāng)前可提供服務(wù)的節(jié)點已經(jīng)不足半數(shù)以上了,那么這個選舉就永遠無法選出結(jié)果,每個節(jié)點都會一直處在 LOOKING 狀態(tài),整個辦事處集群也就無法對外提供服務(wù)了

三、猿話一下

扯蛋扯完了,現(xiàn)在用咱的行話對有一些概念再深入一下。

首先我必須要說的是,故事里的三馬,為了一定的節(jié)目效果,我描述成了三個角色,但是實際中 ZK 服務(wù)端是不會做這樣的區(qū)分的,都是相同的代碼,根據(jù)不同的配置啟動,才有了運行時期 Leader、Follower、Observer 的角色之分,所以更貼近于實際的應(yīng)該類似于火影里的影分身或者龍珠里的殘像拳之類的(好像混入了什么奇怪的東西)。

我畫了下選舉的簡單流程圖:

其他地方我基本上都講過了,這里再講下紅色部分,因為可能一些網(wǎng)絡(luò)因素,發(fā)出去的選票對方卻沒收到,這個發(fā)起重新廣播投票就是為了能讓對方再重新發(fā)一次剛剛的選票。

同監(jiān)聽客戶端 2181 端口不同的是,服務(wù)端集群之間相互通信,直接使用的是原生的 Socket 并沒有使用 NIO 或者是 Netty,因為服務(wù)端節(jié)點一共就這么幾個而且針對每一個其他節(jié)點都會啟動一個線程去監(jiān)聽,所以直接采用了這種比較原始的并且是阻塞的方式通信,更簡單直接,而且假設(shè)對方服務(wù)不可用了的話, Socket 會直接報錯退出。

收發(fā)選票也是采用了 ZK 中非常常見的生產(chǎn)者-消費者模式,分別維護了兩個阻塞隊列,一個對應(yīng)發(fā)送出去的選票,一個對應(yīng)收到的選票,各自使用一個子線程去輪詢該阻塞隊列。

之前的 ZK 是擁有 3 種選舉策略的,雖然另外兩種之前都是被廢棄的狀態(tài),不建議使用,但是通過配置文件還是可以強行使用的。不過在最新的 3.6.2 中另兩種策略直接從源碼中刪除了,現(xiàn)在只有一種選舉的策略,源碼中對應(yīng) FastLeaderElection,另外兩個我也沒研究過,就不展開了。

關(guān)于服務(wù)端之間的心跳檢測:

  • 服務(wù)端之間的心跳檢測(PING)是由 Leader 發(fā)起的,發(fā)向所有集群中的其他節(jié)點
  • Follower 收到 PING 后會回一個PING 給 Leader 并帶上自己這邊的客戶端會話數(shù)據(jù)
  • 而 Leader 收到 Follower 的 PING 后,就會對這些客戶端進行會話連接

關(guān)于會話相關(guān)的知識點留到之后再說~

四、總結(jié)

 

今天我們介紹了選舉的規(guī)則,以及舉例了一些選舉的場景并加以說明。為了介紹 Follower 或者 Observer 是如何在選舉完成之后和 Leader 同步數(shù)據(jù)的,下一篇我們會先介紹 ZK 是如何進行持久化的,期待一下吧,ZKr~

 

責(zé)任編輯:武曉燕 來源: HelloGitHub
相關(guān)推薦

2020-08-24 14:56:27

iPhone蘋果微信

2011-08-29 14:44:06

喬布斯

2017-11-22 07:07:27

路由SD-WAN互聯(lián)網(wǎng)

2021-04-13 09:36:53

阿里互聯(lián)網(wǎng)反壟斷

2020-12-04 06:40:46

Zookeeper選舉機制

2017-09-22 08:44:02

數(shù)據(jù)中心等級機架

2020-01-16 11:23:32

Zookeeper數(shù)據(jù)結(jié)構(gòu)API

2013-11-13 09:32:00

2021-10-08 20:30:12

ZooKeeper選舉機制

2021-06-21 08:59:55

監(jiān)控Netflix優(yōu)化

2021-06-21 08:30:14

Netflix監(jiān)控系統(tǒng)微服務(wù)

2015-12-18 18:35:21

歪評互聯(lián)網(wǎng)大會

2010-07-26 15:33:13

蘋果喬布斯

2020-08-17 07:55:45

數(shù)據(jù)分析技術(shù)IT

2019-08-26 10:43:06

Python統(tǒng)一碼代碼

2009-03-10 10:09:31

面試講演面試準(zhǔn)備HR

2024-10-29 11:32:33

2022-07-28 19:19:21

Zookeeper中心化架構(gòu)

2013-07-24 11:59:30

網(wǎng)絡(luò)·安全技術(shù)周刊

2022-05-12 13:09:18

Linux英偉達開源
點贊
收藏

51CTO技術(shù)棧公眾號