以下只在特殊情況下使用,不要用在生產環境。
一、問題背景
公司的產品使用Zookeeper做為集群支持,但是客戶在驗收的時候提出了一個很為難人的要求,那就是3台集群服務,停止2台以后,還要求我們的應用能提供服務,這就有點難為人了。
因為用過Zookeeper的人都知道,Zookeeper的leader的選舉需要大多數同意,也就是說三台機器的Zookeeper集群那么選舉leader就需要兩台,如果只剩下一台Zookeeper那么是無法完成leader選舉的,也就是說Zookeeper將不能對外提供服務。
我是在公司研發群里得到別的研發團隊的幫助請求,而我正好在研究Zookeeper,所以給出了解決方案,並測試通過。
二、解決方案
解決方法還是比較簡單的,此處不再講解Zookeeper的leader選舉,后續可以參照我的博客,Zookeeper leader選舉。
2.1 修改源碼
修改org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical類的containsQuorum方法為:
public boolean containsQuorum(HashSet<Long> set){ return true; }
修改org.apache.zookeeper.server.quorum.flexible.QuorumMaj類的containsQuorum方法為:
public boolean containsQuorum(HashSet<Long> set){ return true; }
這兩個方法是關於選舉的算法,應用了大多數原則,現在直接去掉。
2.2 打包
將這兩個類單獨打包,命名為_patch-0.1.jar,這么命名的目的就是,加載的時候優先加載我修改的類,下划線優先加載。
2.3 安裝及測試步驟
2.3.1 安裝
首先停止Zookeeper集群。
然后將壓縮包解壓得到的_patch-0.1.jar放置到每個節點的:${zkPath}/lib/下。
2.3.2 測試
- 在集群未啟動時,使用zk客戶端連接集群(-server ip:port,ip:port,ip:port),此時客戶端會持續報連接異常,然后啟動任意一個節點,zk客戶端就能正常使用。
- 集群完全啟動后,任意停止其中兩個,zk依然可以提供服務,客戶端能正常使用,
- 使用java的zk客戶端zkclient-0.8.jar進行測試,測試通過
2.4 注意事項
測試比較簡單,只涉及到單節點提供服務以及leader選舉,未經過更深層次的測試,不建議在正式生產環境下使用,所以通過測驗以后,建議移除單節點支持。移除方式:依次將每個節點停止服務->移除補丁包->重啟;即可。