來源:https://www.dazhuanlan.com/2019/12/07/5deb12e161eb1/
楔子:剛好在整Redis緩存高可用,阿湯哥的一句話Redis哨兵集群只有2個節(jié)點無法正常工作把俺給說暈了,網(wǎng)上也沒找到比較通俗易懂的文章,所以自己理解了一下哨兵選舉算法,為啥兩個結(jié)點就是一個死局?。才疏學(xué)淺有錯誤的地方還望指出,多多包涵
一、類比開車舉報算法
1.1、假如kitty萌新來到了一個不允許開車的世界,人們互相監(jiān)督其他人是不是在開車,最開始大家都沒有證據(jù)
假如一旦確認(rèn)為了周某開車了,并且有了證據(jù),那么我們將對這個老司機判刑,但是還是需要人民在法院投票確定是否周某犯了開車罪,所有人民同時擁有舉報和投票的權(quán)利,但是如果你被舉報,你將剝奪投票自己是否入刑的權(quán)利(總不能說我認(rèn)為我沒開車嘛
當(dāng)然,我們假設(shè)這個世界只要有人民指出一個人在開車我們就可以說有證據(jù)了,就可以交往法院裁決,由人民投票,假如這個世界有n個人.
那么問題來了,多少個人舉報才算有證據(jù),多少人投票同意判刑周某才能入獄
于是這個世界的老大在《不允許開車法》中寫入一下幾條
(首先給出一些定義,n表示世界總?cè)藬?shù),quorum代表舉報周某開車的人數(shù),majority代表大多數(shù)人-可以理解為這個值代表了大多數(shù)人民的選擇-在n確定的時候為定值)

我們來討論一下這三條
1、第一條肯定是沒問題的,必須要有人舉報才能送溫暖嘛
2、第二條意思就是如果是少數(shù)人舉報周某開車,那么需要大多數(shù)人投票入刑才能生效、
3、第三條就是如果舉報的人數(shù)已經(jīng)多與了國家的majority都認(rèn)為周某開車,那么僅僅是majority投票法院是不夠的,可能是因為入刑生效是嚴(yán)肅的,具體細(xì)節(jié)去問那個世界的扛把子
4、這個算法其實類似于(n+1)/2向下取整,但是除了2個人的時候,法律就是法律吧。
1.2、所以現(xiàn)在模擬兩個場景
場景1、這個世界只有兩個人,A舉報B開車是否有效
分析:
這個環(huán)境中n=2,majority=2,quorum=1(世界人數(shù)2,根據(jù)法律majority人數(shù)為2,只有A一個人舉報了B所以quorum=1
因為quorum>0,所以舉報生效
根據(jù)規(guī)則quorum<majority,所以需要majority(2)個人投票有罪
但是現(xiàn)在只有A一個人擁有投票權(quán)限,所以無效
場景2、假如這個世界有三個人,A,B,C中有人舉報了C開車,并且A,B都愿意將C投票入獄
分析1:假如A,B中有一個人舉報了C
這個環(huán)境中n=3,majority=2,quorum=1(世界人數(shù)2,根據(jù)法律majority人數(shù)為2,A舉報了C所以quorum=1
因為quorum>0,所以舉報生效
根據(jù)規(guī)則quorum<majority,所以需要majority(2)個人投票有罪
但是現(xiàn)在只有A擁有授權(quán)權(quán)限,所以無效
分析2:假如A,B中兩個人都舉報了C
這個環(huán)境中n=3,majority=2,quorum=2(世界人數(shù)2,根據(jù)法律majority人數(shù)為2,兩個人都舉報了C所以quorum=2
因為quorum>0,所以舉報生效
根據(jù)規(guī)則quorum>=majority,所以需要quorum(2)個人投票有罪
現(xiàn)在有A,B兩個個人擁有投票權(quán)限,所以投票有效
(以上則是經(jīng)典的Redis三節(jié)點哨兵集群
二、Redis哨兵核心選舉算法分析
2.1、哨兵的主要功能如下
(1)集群監(jiān)控,負(fù)責(zé)監(jiān)控redismaster和slave進程是否正常工作
(2)消息通知,如果某個redis實例有故障,那么哨兵負(fù)責(zé)發(fā)送消息作為報警通知給管理員
(3)故障轉(zhuǎn)移,如果master掛掉了,會自動轉(zhuǎn)移到slavenode
(4)配置中心,如果故障轉(zhuǎn)移發(fā)生了,通知client客戶端新的master地址
2.2、Redis哨兵核心知識
(1)哨兵至少需要3個實例,來保證自己的健壯性
(2)哨兵 + redis主從的部署架構(gòu),是不會保證數(shù)據(jù)零丟失的,只能保證redis集群的高可用性
(3)對于哨兵 + redis主從這種復(fù)雜的部署架構(gòu),盡量在測試環(huán)境和生產(chǎn)環(huán)境,都進行充足的測試和演練
2.3:sdown和odown兩種宕機
sdown和odown兩種失敗狀態(tài)
sdown是主觀宕機,就一個哨兵如果自己覺得一個master宕機了,那么就是主觀宕機 。
odown是客觀宕機,如果quorum數(shù)量的哨兵都覺得一個master宕機了,那么就是客觀宕機 。
sdown達(dá)成的條件很簡單,如果一個哨兵ping一個master,超過了is-master-down-after-milliseconds指定的毫秒數(shù)之后,就主觀認(rèn)為master宕機 。
sdown到odown轉(zhuǎn)換的條件很簡單,如果一個哨兵在指定時間內(nèi),收到了quorum指定數(shù)量的其他哨兵也認(rèn)為那個master是sdown了,那么就認(rèn)為是odown了,客觀認(rèn)為master宕機 。
在這里宕機可以類比于上面的開車了
2.4、quorum和majority
算法中的核心參數(shù),如果看了上面的類比就很容易理解,quorum表示認(rèn)為某機子宕機的哨兵數(shù)量(舉報開車的人數(shù)),majority表示授權(quán)進行主從切換的最少的哨兵數(shù)量(最少投票入刑的人數(shù)) 。
2.5、主備切換工作
1、首先至少一個哨兵認(rèn)為某機宕機了
2、如果quorum < majority,那么最少majority個哨兵授權(quán)就可以執(zhí)行切換
3、如果quorum >= majority,那么必須quorum數(shù)量的哨兵都授權(quán)才能執(zhí)行切換
4、majority取值如下:
n= 2,majority=2
n= 3,majority=2
n= 4,majority=2
n= 5,majority=3
你會發(fā)現(xiàn)這個規(guī)則和上面的開車判斷一模一樣
問題回答阿湯哥:為什么Redis哨兵集群只有2個節(jié)點無法正常工作?
和場景1一模一樣,A哨兵,舉報了B機
這個環(huán)境中n=2,majority=2,quorum=1(2機子,根據(jù)規(guī)定majority為2,只有A舉報了B所以quorum=1
因為quorum>0,所以舉報生效
根據(jù)規(guī)則quorum<majority,所以需要majority(2)授權(quán)
但是現(xiàn)在只有A臺機擁有授權(quán)權(quán)限,所以無效
那么為什么三臺以上就行呢,自己看場景2吧。
ps:從Redis經(jīng)典三節(jié)點哨兵集群看得出來,最少3個人才擁有維持規(guī)矩的基礎(chǔ),如果最后只剩下2個人,那么規(guī)則系統(tǒng)必定崩塌