運(yùn)維老鳥告訴你這個經(jīng)典Zookeeper問題的根因
來自:DBAplus社群
作者介紹
鄒春華,新炬網(wǎng)絡(luò)中間件專家。10年軟件開發(fā)工作經(jīng)驗(yàn),9年運(yùn)營商行業(yè)IT系統(tǒng)維護(hù)經(jīng)驗(yàn)。精通C、C++、JAVA、PHP、SHELL等語言,有著深厚的大型IT軟件系統(tǒng)開發(fā)功底,精通MQ、Redis、Zookeeper、nginx、tomcat等技術(shù)組件的配置和優(yōu)化,也擅長zabbix、Grafana 、cacti、ansbile等組件的運(yùn)用,有大量的自動化運(yùn)維開發(fā)實(shí)踐。
大家好,我是一名有著近二十年工作經(jīng)驗(yàn)的運(yùn)維老鳥。
你問運(yùn)維干什么的?呵呵…運(yùn)維就像三國里的軍師,擅長排兵布陣,能夠運(yùn)籌帷幄,統(tǒng)籌大局。再爛的系統(tǒng),運(yùn)維也能玩得轉(zhuǎn)!
你說什么?重啟能夠解決運(yùn)維90%的問題?
嗯…嗯…其實(shí)…你說的對!重啟能夠解決90%的問題,如果不行的話…那就再重啟一次試試!
好吧,看看大家眼中的運(yùn)維是什么樣的吧:
至于我對運(yùn)維的理解…給大家講講我們最近解決的一個小問題吧。
最近從業(yè)務(wù)部門納管了一批ZooKeeper集群,在對納管集群進(jìn)行巡檢的時候,發(fā)現(xiàn)其中一個5節(jié)點(diǎn)的集群存在兩個leader節(jié)點(diǎn)的情況。經(jīng)與業(yè)務(wù)部門確認(rèn),該集群影響多個重要業(yè)務(wù)系統(tǒng),所以在處理問題的時候既要保證ZooKeeper集群能夠恢復(fù)正常服務(wù),又需要確保所有的業(yè)務(wù)數(shù)據(jù)不能丟失。
問題集群為三機(jī)房部署的可容災(zāi)集群,集群信息如下(本文所有IP等關(guān)鍵信息已脫敏):
正常情況下一個ZooKeeper集群只能有一個leader節(jié)點(diǎn),若干個follower節(jié)點(diǎn)。如下圖:
但是該集群在兩個leader節(jié)點(diǎn)的情況下,各節(jié)點(diǎn)依然狀態(tài)正常,并能夠正常提供服務(wù),確實(shí)有點(diǎn)奇怪。為了能夠說明清楚該問題,我們先了解下ZooKeeper集群的選舉原則。
ZooKeeper集群的leader選舉三原則:
集群中只有超過半數(shù)以上的節(jié)點(diǎn)啟動,集群才能正常工作;
在集群正常服務(wù)前,myid小的節(jié)點(diǎn)給myid大的節(jié)點(diǎn)投票,直到集群正常,選出Leader;
選出Leader之后,之前的節(jié)點(diǎn)狀態(tài)由Looking變?yōu)镕ollowing,以后的節(jié)點(diǎn)都是Follower。
假設(shè)一個5節(jié)點(diǎn)的集群,myid分別是1、2、3、4、5,依序啟動:
1)節(jié)點(diǎn)1啟動
各節(jié)點(diǎn)狀態(tài)(1:啟動;2:關(guān)停;3:關(guān)停;4:關(guān)停;5:關(guān)停)
選取狀態(tài)(1: LOOKING;2:-;3:-;4:-;5:-)
集群狀態(tài)(節(jié)點(diǎn)未滿半數(shù):失?。?/span>
2)節(jié)點(diǎn)2啟動
各節(jié)點(diǎn)狀態(tài)(1:啟動;2:啟動;3:關(guān)停;4:關(guān)停;5:關(guān)停)
選取狀態(tài)(1: LOOKING;2:LOOKING;3:-;4:-;5:-)
集群狀態(tài)(節(jié)點(diǎn)未滿半數(shù):失敗)
3)節(jié)點(diǎn)3啟動
各節(jié)點(diǎn)狀態(tài)(1:啟動;2:啟動;3:啟動;4:關(guān)停;5:關(guān)停)
選取狀態(tài)(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:-;5:-)
集群狀態(tài)(節(jié)點(diǎn)過半數(shù):成功)
4)節(jié)點(diǎn)4啟動
各節(jié)點(diǎn)狀態(tài)(1:啟動;2:啟動;3:啟動;4:啟動;5:關(guān)停)
選取狀態(tài)(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:FOLLOWING;5:-)
集群狀態(tài)(節(jié)點(diǎn)過半數(shù):成功)
5)節(jié)點(diǎn)5啟動
各節(jié)點(diǎn)狀態(tài)(1:啟動;2:啟動;3:啟動;4:啟動;5:啟動)
選取狀態(tài)(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:FOLLOWING;5:FOLLOWING)
集群狀態(tài)(節(jié)點(diǎn)過半數(shù):成功)
根據(jù)集群信息表:
查看192.176.238.219的日志發(fā)現(xiàn)4號節(jié)點(diǎn)成為LEADING狀態(tài)時,集群中有3個節(jié)點(diǎn):
[myid:4] - INFO [QuorumPeer[myid=4]/0:0:0:0:0:0:0:0:2181:Leader@946] - Have quorum of supporters, sids: [ 1,2,4 ];
滿足節(jié)點(diǎn)數(shù)過半的原則,集群正常服務(wù),但是查看節(jié)點(diǎn)內(nèi)容,發(fā)現(xiàn)節(jié)點(diǎn)1、2的內(nèi)容和4不一致,反而是節(jié)點(diǎn)1、2、3、5內(nèi)容是一致的。
查看節(jié)點(diǎn)4的內(nèi)容:
查看節(jié)點(diǎn)5內(nèi)容:
通過內(nèi)容排查可以看出節(jié)點(diǎn)1、2、3、5內(nèi)容一致,可能屬于同一集群,那么節(jié)點(diǎn)4為什么和其它節(jié)點(diǎn)內(nèi)容不一致呢?
繼續(xù)排查節(jié)點(diǎn)的配置信息,發(fā)現(xiàn)節(jié)點(diǎn)4配置的內(nèi)部通訊端口:選舉端口與其它節(jié)點(diǎn)配置的不一致!
節(jié)點(diǎn)4配置情況:
節(jié)點(diǎn)1、2、3、5的配置情況:
通過配置排查可以確認(rèn)1、2、3、5是屬于同一個集群,那4節(jié)點(diǎn)又是哪個集群呢?
繼續(xù)排查發(fā)現(xiàn),在同一批主機(jī)下面部署了另一個ZooKeeper實(shí)例,開放的服務(wù)端口是2182,而其配置的內(nèi)部通訊端口:選舉端口正是2888:3888。
通過排查這個集群節(jié)點(diǎn)的內(nèi)容發(fā)現(xiàn):節(jié)點(diǎn)1、2的內(nèi)容和上面集群的節(jié)點(diǎn)4內(nèi)容是一致的,而這個集群3、4、5節(jié)點(diǎn)的內(nèi)容又是一致的!通過推斷,集群狀態(tài)如下表:
由于集群2和集群3都有三個節(jié)點(diǎn),配置的總節(jié)點(diǎn)數(shù)是5,均滿足節(jié)點(diǎn)數(shù)過半的原則!
那么這種情況下會出現(xiàn)什么問題呢?
本來正常情況下A類業(yè)務(wù)系統(tǒng)只讀寫2181端口的集群、B類業(yè)務(wù)系統(tǒng)只讀寫2182端口的集群,而現(xiàn)在集群2既可以服務(wù)A類業(yè)務(wù),又可服務(wù)B類業(yè)務(wù),如果集群2的數(shù)據(jù)丟失,將影響兩類業(yè)務(wù)的正常運(yùn)行。
集群2是一個異常集群,但是如果將集群2的節(jié)點(diǎn)恢復(fù)正常并分別加入到集群1和集群3后,集群2的數(shù)據(jù)勢必會丟失。由于ZooKeeper集群的數(shù)據(jù)是由A類業(yè)務(wù)系統(tǒng)和B類業(yè)務(wù)系統(tǒng)進(jìn)行讀寫的,解決的方法首先需要將集群2的數(shù)據(jù)導(dǎo)出并根據(jù)業(yè)務(wù)類型進(jìn)行區(qū)分,待集群恢復(fù)正常后,再將這部分?jǐn)?shù)據(jù)依據(jù)業(yè)務(wù)歸屬分別重新寫入到對應(yīng)的集群。
集群恢復(fù)步驟:
1)為防止數(shù)據(jù)丟失,備份集群1、集群2、集群3的數(shù)據(jù)(snapshot和log)。
2)提取集群2的數(shù)據(jù),并依據(jù)業(yè)務(wù)類型將數(shù)據(jù)分類,并準(zhǔn)備重新寫入。
3)關(guān)停集群2節(jié)點(diǎn)4(192.176.238.219:2181)實(shí)例,集群2剩余2個節(jié)點(diǎn),不滿足半數(shù)要求,集群重新進(jìn)行選舉,由于集群2的1、2兩個節(jié)點(diǎn)的通訊、選舉端口和集群3配置一致,并且集群3已經(jīng)選舉了節(jié)點(diǎn)5為leader,那么集群2的節(jié)點(diǎn)1、2將加入到集群3成為follower,形成5節(jié)點(diǎn)的集群。
4)修改集群2節(jié)點(diǎn)4(192.176.238.219:2181)的內(nèi)部通訊端口:選舉端口為2889:3889
5)啟動192.176.238.219:2181實(shí)例,由于該實(shí)例的通訊、選舉端口和集群1配置一致,并且集群1已經(jīng)選舉了節(jié)點(diǎn)5為leader, 該實(shí)例將加入集群1成為follower,形成5節(jié)點(diǎn)的集群。
6)分別將原集群2的數(shù)據(jù)分類后重新寫入到集群1和集群3。
7)檢查集群狀態(tài),檢查集群數(shù)據(jù)信息,并進(jìn)行業(yè)務(wù)測試。
恢復(fù)后的集群信息如下:
通過以上操作步驟后,集群恢復(fù)正常,丟失數(shù)據(jù)重新寫入,所有業(yè)務(wù)驗(yàn)證正常。
該問題根因很簡單,只是一個配置的小問題,但是處理卻很容易出錯。因?yàn)檫@是一個已經(jīng)在線運(yùn)行了很久的系統(tǒng),往往不會懷疑是配置的問題,在處理該問題時,如果沒有理清楚問題根因,只是簡單將問題集群重啟,表面上問題已經(jīng)解決,但是大量數(shù)據(jù)將會丟失會嚴(yán)重影響到業(yè)務(wù),并且根因沒有找到,問題依舊存在,隨時可能復(fù)發(fā)…
說了這么多,你還認(rèn)為運(yùn)維只是簡單的重啟就能解決問題嗎?那什么是運(yùn)維呢?
其實(shí)啊,運(yùn)維是個灶臺,上面背著個黑鍋,下面還有個大坑…
特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點(diǎn)個在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!