Java面試題解析:ZooKeeper集羣如何實現高可用部署?

Zookeeper 我想大家都不陌生,在很多場合都聽到它的名字。它是 Apache 的一個頂級項目,爲分佈式應用提供一致性高性能協調服務。可以用來做:配置維護、域名服務、分佈式鎖等。有很多開源組件,尤其是中間件領域,使用 Zookeeper 作爲配置中心或者註冊中心。它是 Hadoop 和 HBase 的重要組件,是 Kafka 的管理和協調服務,是 Dubbo 等服務框架的註冊中心等。

原理

在介紹高可用部署前,我們先了解下 Zookeeper 的基本知識,這對充分理解它的高可用部署非常重要。

架構

下圖是 Zookeeper 的架構圖,ZooKeeper 集羣中包含 Leader、Follower 以及 Observer 三個角色:

  • Leader:負責進行投票的發起和決議,更新系統狀態,Leader 是由選舉產生;
  • Follower: 用於接受客戶端請求並向客戶端返回結果,在選主過程中參與投票;
  • Observer:可以接受客戶端連接,接受讀寫請求,寫請求轉發給 Leader,但 Observer 不參加投票過程,只同步 Leader 的狀態,Observer 的目的是爲了擴展系統,提高讀取速度。

Client 是 Zookeeper 的客戶端,請求發起方。

高可用

Zookeeper 系統中只要集羣中存在超過一半的節點(這裏指的是投票節點即非 Observer 節點)能夠正常工作,那麼整個集羣就能夠正常對外服務

基於此,如果想搭建一個能夠允許 N 臺機器 down 掉的集羣,那麼就要部署一個由 2*N+1 臺服務器構成的 ZooKeeper 集羣。

因此,如果部署了 3 個 Zookeeper 節點(非 Observer),則如果至少有 2個節點可用則整個集羣就可用,意味着 1 個節點故障,不影響 Zookeeper 集羣對外提供服務;如果部署了 5 個節點,意味着 2 個節點同時故障,Zookeeper 集羣依然能夠正常對外提供服務。

Zookeeper 集羣部署的節點(非 Observer)數一般爲奇數個

部署的節點數一般爲奇數個,這裏不是說不能爲偶數個。例如如果部署了 4 個節點,這意味着需要 4/2+1 = 3 個節點正常,集羣才能正常對外服務,即可以容忍 1 個節點故障,但是這個部署 3 個節點,其實效果是一樣的,也就是說部署偶數個,從高可用方面來說只是浪費了 1 臺機器而已。

部署

既然只要 Zookeeper 集羣中存在超過一半的節點能夠正常工作,集羣就能夠正常服務,那 Zookeeper 如果想要 Zookeeper 高可用豈不是很簡單,是不是多部署幾個節點不就好了呢?

多部署節點就高可用了?

多部署節點,貌似確實是能夠增強可用性,但是這裏還需要考慮以下兩個問題:

  • 多增加節點對性能和寫可用性有影響 增加節點,意味了能夠容忍非正常節點數更多,聽起來高可用是更高了。但是,節點數越多意味着 Leader 發出的提案需要更多的節點(半數以上)來接受提案,這必然增加提案 commit 的耗時,也就意味着對寫請求的性能以及可用性影響比較大。因此,對於正常的業務系統來說需要完美的權衡利弊,來調整節點的個數。
  • 需要考慮容災需求 部署還得結合容災要求,需要能在機房故障,地區故障時整個 Zookeeper 集羣是否能正常對外提供服務。

機房容災

如果要保證在整個機房出現故障的情況下,保證 Zookeeper 集羣的高可用,是要對 Zookeeper 做跨機房部署的。

單機房

我們先看下單機房部署情況下,下圖是單個機房 5 個節點的部署情況。在單機房部署的情況下是不能做到機房容災的,一旦機房出現問題,整個 Zookeeper 集羣就不能對外工作。

單機房部署還需考慮所選的節點應該儘量不在同一個宿主機,不同機櫃,避免多個節點同時出現問題。

同城雙機房

既然單機房做不到機房容災,那雙機房呢?

如下圖在“機房 1”部署 3 個節點,“機房 2”部署 2 個節點,總共 5 個節點的 Zookeeper 集羣,這能做到機房容災嗎?任意一個機房故障,集羣都能正常對外提供工作嗎?

其實,還是不行的。假如“機房 2”故障,“機房 1”正常,這種情況下,因爲“機房 1”存在 3 個節點,大於半數,因此還是能夠正常工作的;但是,假如“機房 1”故障,那存活節點數只有 2 個,整個集羣是不能正常工作的。

因此,Zookeeper 雙機房部署,是不能夠做到機房容災的。

同城三機房

我們再來看看三機房部署,三機房部署,是能夠做到機房容災的。還是以 5 個節點的集羣爲例:

如下圖,在“機房 1”、“機房 2”同時部署 2 個節點,而“機房 3” 部署 1 個節點。在任意一個機房故障的情況下,都能滿足正常節點數大於半數及以上,所以能夠保證機房容災。

異地容災

僅僅做到機房級別的容災,對於一般的業務應該就夠了,不過目前很多公司採用的是兩地三中心模式,螞蟻金服甚至做到了三地五中心。在這種情況下,我們的 Zookeeper 集羣應該如何部署呢?

兩地三中心

“兩地三中心”即生產數據中心、同城災備中心、異地災備中心建設方案。這種模式下,兩個城市的三個數據中心互聯互通,如果一個數據中心發生故障或災難,其他數據中心可以正常運行並對關鍵業務或全部業務實現接管。

在兩地三中心的的模式下,Zookeeper 集羣的部署有哪些考量呢?

如下圖,一般兩地三中心採用的是下面這種部署方式。在“地區 1”有兩個同城數據中心,“中心 1”和“中心2”,在異地“地區 2” 有一個異地中心“中心 1”。這裏你可能有兩個疑問:

  • 爲什麼投票節點(Follower 和 Leader)都放在“地區 1 中心 1”,而不是按照三機房類似的方案在三個中心都進行部署呢?
  • 這裏是因爲由於異地之間的物理距離比較長,網絡傳輸時延比較大,導致集羣的投票節點的決策時間比較長,進而影響寫性能。試想一下,如果兩地選用的是北京和上海兩座城市,走專線網絡延時約 30ms,在寫數據時,需要半數節點同意提案,一個寫請求才能成功。因此,一次寫成功的時間會比較長。 另外,異地之間的網絡比較複雜,很容易出現集羣重新選舉,導致整個集羣不可用,而且選舉時間會比較長。 因此,一般只在一箇中心內做到三機房部署,其他中心都是用 Observer 節點,可以看出,部署上 Zookeeper 集羣無法做到異地容災的。
  • 爲什麼引入了 Observer 節點?
  • Observer 能很好的對 Zookeeper 集羣進行擴展,Observer 可以提供 Client 讀寫,但不參與投票。因此,Observer 節點對集羣不影響投票耗時,也不影響集羣選舉。另外,加入 Observer 對讀性能是一個很大的提升。

三中心優化

爲了保護集羣,在三個中心都部署上 Observer 節點,而 Client 只與 Observer 機點進行交互,用這種方式可以降低投票節點的工作負載,降低 Leader 和 Follower 的不穩定性,從而提高整個集羣的穩定性和可用性。

總結

Zookeeper 的高可用在部署上也是有很多考量的,Zookeeper 集羣在部署上可以做到機房容災,但是做不到異地容災。另外,爲了提升集羣的擴展性和穩定性,可以引入 Observer 節點,提升讀性能,保護 Leader 與 Follower 節點。

共同進步,學習分享

歡迎大家關注我的公衆號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裏面更新,整理的資料也會放在裏面。

覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章