MongoDB Replica Set 選舉過程

什麼是選舉?html

選舉是副本集選擇某個成員成爲primary的過程。primary是一個副本集中惟一可以接收寫操做的成員。sql

下面的事件可以引起一次選舉:安全

  1. 第一次初始化一個副本集
  2. Primary失效。replSetStepDown命令可以使Primary失效,或者當前secondary成員中有合適的選舉者且優先級更高。當Primary與集合中的大多數成員失去聯繫時也會失效,它會關閉全部的客戶端鏈接,以此防止客戶端向一個沒有primary成員寫數據。
  3. 一個secondary成員於primary失去聯繫。當secondary成員不能與primary創建一個穩定的鏈接時會發起選舉。
  4. 故障切換髮生。

在選舉過程當中,全部的成員都有一票,包括隱藏成員、仲裁者和正在恢復的成員。任意mongod可以否決一次選舉服務器

                副本集角色屬性一覽表網絡

 

成爲primarynosql

對客戶端可見socket

參與投票spa

延遲同步htm

複製數據對象

Default (Secondary)

Secondary-Only

Hidden

Delayed

Arbiters

Non-Voting

 


心跳檢測
假設咱們有三個節點的replica sets:X,Y和Z節點。在replica sets結構中,這三個節點每2秒會各自向其它兩個節點發送一個心跳檢測請求。好比X節點向Y和Z節點各發送了一個心跳檢測請求,在正常狀況下,Y、Z會返回一個包含自身信息的回覆包,回覆包中主要包括了下面一些信息:它們如今是什麼角色(primary 仍是 secondary),他們是否可以在必要的時候成爲 primary,以及他們當前時鐘時間等等。
X節點在收到回覆包後,會用這些信息更新本身的一個狀態映射表,更新的內容包括:是否有新的節點加入或有老的節點宕掉,這個請求的網絡傳輸時間等等。
而當X節點的映射表發生了變化,那X會進行下面的邏輯判斷:若是X是 primary,而另一個節點出現故障,那麼它會看本身是否還能和集羣中大多數節點進行通訊,若是不能與大多數節點通訊,那麼他會把本身從 primary 降級爲 secondary。(在replica sets中,primary 必須可以和集羣中的大多數節點進行通訊,以避免發生網絡斷開造成兩個或多個節點羣各自爲政的狀況,這樣會影響到數據的一致性)

關於降級
在節點從 primary 降級爲 secondary 的過程當中,會有一些問題出現。在 MongoDB 中,寫操做默認是經過 fire-and-forget 的模式來進行的,也就是說寫操做一般不關心是否成功,發完請求後客戶端就認爲成功了。但若是這時候 primary 進行降級操做,那麼客戶端並不知道這時候 primary 已經降級成爲 secondary 了,客戶端可能還會將後續的寫操做發送給這個節點。這時候剛剛降級的這個 secondary 能夠發送一個包說「我已經不是 primary 了」,可是咱們上面說過了,客戶端根本就無視你這個包。因此客戶端根本不知道此次寫入已經失敗了。
對於這個問題,你可能會說」那咱們每次都使用安全寫入不就好了「(安全寫入意思是說等待服務器返回成功後客戶端才認爲寫成功了),可是很明顯,這很是不靠譜。因此咱們的作法是,在一個 primary 降級成爲 secondary 後,它會將原來的全部鏈接關閉。這樣客戶端在下一次寫入的時候就會出現 socket 錯誤。而客戶端在發現這個錯誤以後,就會從新向集羣獲取新的 primary 的地址,並將後續的寫操做都往新的服務器上寫入。

選舉
咱們回頭再來看心跳監測請求:若是X是一個 secondary,那麼X會定時檢測是否須要選舉本身成爲 primary。其檢測內容包括:是否集羣中有其它節點認爲本身是 primary?X節點本身是否已是 primary?X節點本身是否有資格成爲 primary?若是這三個問題中的任何一個回答是否認的,那麼X節點就不會試圖把本身變成primary。(也就是說,只有當X節點是一個可以當 primary 的secondary,而且其它節點都不是primary時,X纔會發起選舉並選本身爲primary)
而當X發現集羣如今須要一個primary而且本身又正好能夠充當時,它就會發起一輪選舉:X節點會向Y、Z節點各發起一個請求包,告知他們」我認爲我能夠接管primary的角色,大家以爲怎麼樣?「

當Y和Z收到上面的請求包時,他們會進行下面幾項檢測:集羣中是否有一個 primary了?他們本身的數據是否比X節點更新嗎?是否有其它節點的數據比X節點更新?若是上面條件有任何一個知足,那麼他們都會認爲X不夠資格成爲 primary,他們會發送一個返回包告知X說」中止選舉!「。而若是三個條件都不成立,也就是說他們認爲目前集羣中確實沒有 primary,而且X的數據又是最新的,那麼他們會發送返回包告知X說」沒問題「。
若是X收到」中止選舉!「,那麼他會立刻中止選舉並保持本身爲 sencondary 狀態。
若是X收到全部其它節點都返回說」沒問題「,那麼他會進入選舉過程的第二階段。
在第二階段中,X會向其它節點發送一個包,說」我宣佈我已是 primary 了「。這時候,Y和Z節點再進行一些最終的確認:上面的判斷過的全部條件是否依然代表X能夠作 primary,若是確實如此,那麼他們會在本輪 primary 選舉中向X出同意票。而且他們投完同意票後,30秒內不會再作其它投票決定。
那麼若是最終確認沒有經過,他們會投一個反對票,反對X成爲 primary,若是有任何反對票產生,那麼這一輪選舉就失敗了。X仍是保持 secondary 的身份。
下面咱們假設一種狀況,若是Y給X投了同意票,而Z給X投了反對票。那這時候Y因爲投了同意票,它在30秒內不能再進行投票。因此若是這時候Z發起選舉想讓本身成爲 primary,那麼Z這時候必需要得到X的同意票。由於這時候Y不能投票,爲了獲取多數票,Z必須得到X的同意票。


因此投票的規則是這樣的:若是沒有投反對票,而且同意票的比例過半,那麼本輪選舉對象就可以成爲 primary

 

轉載於http://blog.nosqlfan.com/html/3621.html

相關文章
相關標籤/搜索