zookeeper怎麼擴容,增加server
-
zookeeper 版本 3.4.6
-
現有zk叢集是五臺, myid分別為 0, 1, 2, 3, 4
-
三地機房 (1). 機房1, 現有叢集在該機房, 主機房, 服務的主要流量在該機房. 目前zk的5臺機器在該機房. (2). 機房2, 熱備機房, 有全量服務但是機器數量較機房1少, 分擔少部分負載, 在機房1不可用時,將會對外提供所有服務. (3). 機房3(延時較大,在100ms).
-
需要構建一個高可用zk環境, 服務主要部署在機房1, 機房2有全量服務但是機器數量較機房1少.
-
現在需要將機房1,2做成一個大的zk叢集, 但是由於zk對雙機房, 不能做到高可用, 所有加了一個機房3. 現在這三個機房的zk例項數為 5 + 5 + 1 .
-
現有zk例項為5, 但是我們需要擴容到11臺, 新增例項數比原有叢集例項數大.
-
在擴容過程中需要不影響使用現有zk叢集的服務. 不可以全部停止, 進行升級.
需要注意的問題
-
新增的機器數大於現有叢集zk例項數.
-
三地機房, 其中機房1為主機房, 資源最多, 儘量讓leader落在該機房. 機房1和機房2的延時在容忍範圍內, leader也可以落在該機房, 但是需要優先考慮機房1. 因為機房3延時較大, 儘量不可以讓機房3的例項擔任leader角色.
-
歷史遺留問題, 原有zk叢集的myid是從0開始的, 這是個坑(稍後會說).
具體步驟
修改myid
為什麼要先修改myid, 這是之前我們給自己挖的一個大坑, 這次一定要填上, 並且為以後的zk運維積累經驗.因為, 我們需要leader儘量落在機房1的機器上, 鑑於zk叢集進行leader中用到的快速選舉演算法, 叢集中的機器會優先匹配zxid最大的例項(這樣可以保證在資料同步時,這個例項上的資料是最新的), 如果所有例項中的zxid都一樣, 那麼所有例項會選舉出myid最大的例項為leader. 基於這樣的條件, 我們需要將機房1中的現有的5臺的myid進行提升, 給機房3的zk例項騰出myid的位置(以確保在zxid一樣時,它肯定不會是leader). 因為zk中myid的範圍必須是大於等於0(沒錯,你沒看錯,我們使用了0, 即使官方sample配置中是從1開始, 但是我們還是使用了0), 所有我們需要先將myid=0的例項進行myid變更.
1 . 修改myid=1的機器的myid為100, 依次對修改五個例項的zoo.cfg
修改完之後的配置類似如下:
1 2 3 4 5 |
server.1=192.168.1.101:2555:3555 server.2=192.168.1.102:2555:3555 server.3=192.168.1.103:2555:3555 server.4=192.168.1.104:2555:3555 server.100=192.168.1.100:2555:3555 |
2 . 記錄現在叢集中哪臺機器為leader, 該機器最後重啟.
3 . 依次重啟myid為1,2,3,4,100的例項(注意最後重啟leader)
ok, 這裡我說另外一個坑, 我們重啟服務的時候最好是依從myid從小到大依次重啟, 因為這個裡面又涉及到zookeeper另外一個設計.zookeeper是需要叢集中所有叢集兩兩建立連線, 其中配置中的3555埠是用來進行選舉時機器直接建立通訊的埠, 為了避免重複建立tcp連線,如果對方myid比自己大,則關閉連線,這樣導致的結果就是大id的server才會去連線小id的server,避免連線浪費.如果是最後重啟myid最小的例項,該例項將不能加入到叢集中,因為不能和其他叢集建立連線, 這時你使用nc命令, 會有如下的提示: This ZooKeeper instance is not currently serving requests. 在zookeeper的啟動日誌裡面你會發現這樣的日誌: Have smaller server identifier, so dropping the connection. 如果真的出現了這個問題, 也沒關係, 但是需要先將報出該問題的例項起著,然後按照myid從小到大依次重啟zk例項即可. 是的,我們確實碰到了這個問題, 因為我們稍後會將機房3的那個zk例項的myid變為0,並最後加入到11臺例項的叢集中,最後一直報這個問題.
新增新機器進入叢集
經過上面的步驟,現在來新增新機器進入叢集. 因為新叢集zk例項數量為11臺, 那麼如果能做到HA,需要保證叢集中存活機器至少為6臺. 鑑於這樣的要求,我們並不能一次性將11臺機器的配置修改為如下:
1 2 3 4 5 6 7 8 9 10 11 |
server.0=192.168.3.1:2555:355555 server.1=192.168.1.101:2555:3555 server.2=192.168.1.102:2555:3555 server.3=192.168.1.103:2555:3555 server.4=192.168.1.104:2555:3555 server.5=192.168.2.1:2555:3555 server.6=192.168.2.2:2555:3555 server.7=192.168.2.3:2555:3555 server.8=192.168.2.4:2555:3555 server.9=192.168.2.5:2555:3555 server.100=192.168.1.100:2555:3555 |
我們只能先將原有的5臺zk例項的叢集先擴充到7臺(為何不是8臺?慢慢梳理一下就知道了), 然後再擴充到11臺這樣的步驟. 鑑於這樣的思路,我們的步驟如下:
1 . 選出兩臺新的例項, 加上之前的5臺, 將他們的配置檔案修改為7臺,依次重啟原叢集zk例項,然後啟動兩臺新加入的例項, 注意最後重啟leader.
1 2 3 4 5 6 7 |
server.1=192.168.1.101:2555:3555 server.2=192.168.1.102:2555:3555 server.3=192.168.1.103:2555:3555 server.4=192.168.1.104:2555:3555 server.5=192.168.2.1:2555:3555 server.6=192.168.2.2:2555:3555 server.100=192.168.1.100:2555:3555 |
2 . 將zoo.cfg中的叢集機器數量設為11臺, 已經存在的7臺zk例項叢集進行重啟,然後重啟另外四臺新zk例項. 這裡你可能在啟動myid=0的zk例項會出現上面描述的問題,沒關係,按照上面說的步驟操作即可.
方案二:如果允許zookeeper的服務短暫停止,則可以
整體重啟
所謂叢集整體重啟,就是先將整個叢集停止,然後更新 ZooKeeper 的配置,然後再次啟動。如果在你的系統中,ZooKeeper 並不是個非常核心的元件,並且能夠允許短暫的服務停止(通常是幾秒鐘的時間間隔),那麼不妨選擇這種方式。在整體重啟的過程中,所有該叢集的客戶端都無法連線上叢集。等到叢集再次啟動,這些客戶端就能夠自動連線上——注意,整體啟動前建立起的客戶端會話,並不會因為此次整體重啟而失效。也就是說,在整體重啟期間花費的時間將不計入會話超時時間的計算中。
方案三:動態增加節點