Categories
程式開發

運維老鳥告訴你這個經典Zookeeper問題的根因


本文由 dbaplus 社群授權轉載。

大家好,我是一名有著近二十年工作經驗的運維老鳥。

你問運維幹什麼的?呵呵…運維就像三國里的軍師,擅長排兵布陣,能夠運籌帷幄,統籌大局。再爛的系統,運維也能玩得轉!

你說什麼?重啟能夠解決運維90%的問題?

嗯…嗯…其實…你說的對!重啟能夠解決90%的問題,如果不行的話…那就再重啟一次試試!

好吧,看看大家眼中的運維是什麼樣的吧:

運維老鳥告訴你這個經典Zookeeper問題的根因 1

至於我對運維的理解…給大家講講我們最近解決的一個小問題吧。

一、問題緣由

最近從業務部門納管了一批ZooKeeper集群,在對納管集群進行巡檢的時候,發現其中一個5節點的集群存在兩個leader節點的情況。經與業務部門確認,該集群影響多個重要業務系統,所以在處理問題的時候既要保證ZooKeeper集群能夠恢復正常服務,又需要確保所有的業務數據不能丟失。

問題集群為三機房部署的可容災集群,集群信息如下(本文所有IP等關鍵信息已脫敏):

運維老鳥告訴你這個經典Zookeeper問題的根因 2

正常情況下一個ZooKeeper集群只能有一個leader節點,若干個follower節點。如下圖:

運維老鳥告訴你這個經典Zookeeper問題的根因 3

但是該集群在兩個leader節點的情況下,各節點依然狀態正常,並能夠正常提供服務,確實有點奇怪。為了能夠說明清楚該問題,我們先了解下ZooKeeper集群的選舉原則。

二、ZooKeeper集群選舉原則

ZooKeeper集群的leader選舉三原則:

  • 集群中只有超過半數以上的節點啟動,集群才能正常工作;
  • 在集群正常服務前,myid小的節點給myid大的節點投票,直到集群正常,選出Leader;
  • 選出Leader之後,之前的節點狀態由Looking變為Following,以後的節點都是Follower。

假設一個5節點的集群,myid分別是1、2、3、4、5,依序啟動:

1)節點1啟動

  • 各節點狀態(1:啟動;2:關停;3:關停;4:關停;5:關停)
  • 選取狀態(1: LOOKING;2:-;3:-;4:-;5:-)
  • 集群狀態(節點未滿半數:失敗)

2)節點2啟動

  • 各節點狀態(1:啟動;2:啟動;3:關停;4:關停;5:關停)
  • 選取狀態(1: LOOKING;2:LOOKING;3:-;4:-;5:-)
  • 集群狀態(節點未滿半數:失敗)

3)節點3啟動

  • 各節點狀態(1:啟動;2:啟動;3:啟動;4:關停;5:關停)
  • 選取狀態(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:-;5:-)
  • 集群狀態(節點過半數:成功)

4)節點4啟動

  • 各節點狀態(1:啟動;2:啟動;3:啟動;4:啟動;5:關停)
  • 選取狀態(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:FOLLOWING;5:-)
  • 集群狀態(節點過半數:成功)

5)節點5啟動

  • 各節點狀態(1:啟動;2:啟動;3:啟動;4:啟動;5:啟動)
  • 選取狀態(1: FOLLOWING;2:FOLLOWING;3:LEADING;4:FOLLOWING;5:FOLLOWING)
  • 集群狀態(節點過半數:成功)

三、問題分析

根據集群信息表:

運維老鳥告訴你這個經典Zookeeper問題的根因 4

查看192.176.238.219的日誌發現4號節點成為LEADING狀態時,集群中有3個節點:

[myid:4] - INFO  [QuorumPeer[myid=4]/0:0:0:0:0:0:0:0:2181:[email protected]] - Have quorum of supporters, sids: [ 1,2,4 ];

滿足節點數過半的原則,集群正常服務,但是查看節點內容,發現節點1、2的內容和4不一致,反而是節點1、2、3、5內容是一致的。

查看節點4的內容:

運維老鳥告訴你這個經典Zookeeper問題的根因 5

查看節點5內容:

運維老鳥告訴你這個經典Zookeeper問題的根因 6

通過內容排查可以看出節點1、2、3、5內容一致,可能屬於同一集群,那麼節點4為什麼和其它節點內容不一致呢?

繼續排查節點的配置信息,發現節點4配置的內部通訊端口:選舉端口與其它節點配置的不一致!

節點4配置情況:

運維老鳥告訴你這個經典Zookeeper問題的根因 7

節點1、2、3、5的配置情況:

運維老鳥告訴你這個經典Zookeeper問題的根因 8

通過配置排查可以確認1、2、3、5是屬於同一個集群,那4節點又是哪個集群呢?

繼續排查發現,在同一批主機下面部署了另一個ZooKeeper實例,開放的服務端口是2182,而其配置的內部通訊端口:選舉端口正是2888:3888。

運維老鳥告訴你這個經典Zookeeper問題的根因 9

通過排查這個集群節點的內容髮現:節點1、2的內容和上面集群的節點4內容是一致的,而這個集群3、4、5節點的內容又是一致的!通過推斷,集群狀態如下表:

運維老鳥告訴你這個經典Zookeeper問題的根因 10

由於集群2和集群3都有三個節點,配置的總節點數是5,均滿足節點數過半的原則!

四、問題影響

那麼這種情況下會出現什麼問題呢?

本來正常情況下A類業務系統只讀寫2181端口的集群、B類業務系統只讀寫2182端口的集群,而現在集群2既可以服務A類業務,又可服務B類業務,如果集群2的數據丟失,將影響兩類業務的正常運行。

運維老鳥告訴你這個經典Zookeeper問題的根因 11

五、解決問題

集群2是一個異常集群,但是如果將集群2的節點恢復正常並分別加入到集群1和集群3後,集群2的數據勢必會丟失。由於ZooKeeper集群的數據是由A類業務系統和B類業務系統進行讀寫的,解決的方法首先需要將集群2的數據導出並根據業務類型進行區分,待集群恢復正常後,再將這部分數據依據業務歸屬分別重新寫入到對應的集群。

集群恢復步驟:

1)為防止數據丟失,備份集群1、集群2、集群3的數據(snapshot和log)。

2)提取集群2的數據,並依據業務類型將數據分類,並準備重新寫入。

3)關停集群2節點4(192.176.238.219:2181)實例,集群2剩餘2個節點,不滿足半數要求,集群重新進行選舉,由於集群2的1、2兩個節點的通訊、選舉端口和集群3配置一致,並且集群3已經選舉了節點5為leader,那麼集群2的節點1、2將加入到集群3成為follower,形成5節點的集群。

4)修改集群2節點4(192.176.238.219:2181)的內部通訊端口:選舉端口為2889:3889

5)啟動192.176.238.219:2181實例,由於該實例的通訊、選舉端口和集群1配置一致,並且集群1已經選舉了節點5為leader, 該實例將加入集群1成為follower,形成5節點的集群。

6)分別將原集群2的數據分類後重新寫入到集群1和集群3。

7)檢查集群狀態,檢查集群數據信息,並進行業務測試。

恢復後的集群信息如下:

運維老鳥告訴你這個經典Zookeeper問題的根因 12

通過以上操作步驟後,集群恢復正常,丟失數據重新寫入,所有業務驗證正常。

六、小結

該問題根因很簡單,只是一個配置的小問題,但是處理卻很容易出錯。因為這是一個已經在線運行了很久的系統,往往不會懷疑是配置的問題,在處理該問題時,如果沒有理清楚問題根因,只是簡單將問題集群重啟,表面上問題已經解決,但是大量數據將會丟失會嚴重影響到業務,並且根因沒有找到,問題依舊存在,隨時可能複發…

說了這麼多,你還認為運維只是簡單的重啟就能解決問題嗎?那什麼是運維呢?

其實啊,運維是個灶台,上面背著個黑鍋,下面還有個大坑…

作者介紹

鄒春華,新炬網絡中間件專家。 10年軟件開發工作經驗,9年運營商行業IT系統維護經驗。精通C、C++、JAVA、PHP、SHELL等語言,有著深厚的大型IT軟件系統開發功底,精通MQ、Redis、Zookeeper、nginx、tomcat等技術組件的配置和優化,也擅長zabbix、Grafana 、cacti、ansbile等組件的運用,有大量的自動化運維開發實踐。

原文鏈接

https://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&mid=2650787351&idx=2&sn=5332cc47bc2fd2f043f3462dc7f5773e&chksm=f3f97b82c48ef294a82ce33edd9166b159a0cbeaee292b40e991fba37daa6c26b06c00174f9a&scene=27#wechat_redirect