天天看點

【轉載】對 Zookeeper 的一些分析

1. zookeeper 不是為高可用性設計的 

由于要跨機房容災,很多系統實際上是需要跨機房部署的。出于成本效益的考慮我們通常會讓多個機房同時工作,而不會搭建 n 倍的備援。也就是說單個機房肯定撐不住全流量(你能設想谷歌在全球隻剩下一個機房在幹活嗎)。由于 zookeeper 叢集隻能有一個 master ,是以一旦機房之間連接配接出現故障,zookeeper master 就隻能照顧一個機房,其他機房運作的業務子產品由于沒有 master 都隻能停掉。于是所有流量集中到有 master 的那個機房,于是系統 crash 。

即使是在同一個機房裡面,由于網段的不同,在調整機房交換機的時候偶爾也會發生網段隔離的情況。實際上機房每個月基本上都會發生短暫的網絡隔離之類的子網段調整。在那個時刻 zookeeper 将處于不可用狀态。如果整個業務系統基于 zookeeper(比如要求每個業務請求都先去 zookeeper 擷取業務系統的master 位址),則系統的可用性将非常脆弱。

由于 zookeeper 對于網絡隔離的極度敏感,導緻 zookeeper 對于網絡的任何風吹草動都會做出激烈反應。這使得 zookeeper 的‘不可用’時間比較多,我們不能讓 zookeeper 的‘不可用’,變成系統的不可用。

2. zookeeper 的選舉過程速度很慢 

這是一個很難從理論分析上看到的弱點,但是你一旦遇到就會痛不欲生。

前面我們已經說過,網絡實際上常常是會出現隔離等不完整狀态的,而 zookeeper 對那種情況非常敏感。一旦出現網絡隔離,zookeeper 就要發起選舉流程。

zookeeper 的選舉流程通常耗時 30 到 120 秒,期間 zookeeper 由于沒有 master,都是不可用的。

對于網絡裡面偶爾出現的,比如半秒一秒的網絡隔離,zookeeper 會由于選舉過程,而把不可用時間放大幾十倍。

3. zookeeper 的性能是有限的 

典型的 zookeeper 的 tps 大概是一萬多,無法覆寫系統内部每天動辄幾十億次的調用。是以每次請求都去zookeeper 擷取業務系統 master 資訊是不可能的。

是以 zookeeper 的 client 必須自己緩存業務系統的 master 位址。

是以 zookeeper 提供的‘強一緻性’實際上是不可用的。如果我們需要強一緻性,還需要其他機制來進行保障:比如用自動化腳本把業務系統的 old master 給 kill 掉,但是那會有很多陷阱(這裡先不展開這個議題,讀者可以自己想想會有哪些陷阱)。

4.zookeeper 無法進行有效的權限控制 

zookeeper 的權限控制非常薄弱。

在大型的複雜系統裡面,使用 zookeeper 必須自己再額外的開發一套權限控制系統,通過那套權限控制系統再通路 zookeeper 。

額外的權限控制系統不但增加了系統複雜性和維護成本,而且降低了系統的總體性能。

5.即使有了 zookeeper 也很難避免業務系統的資料不一緻 

前面已經讨論過了,由于 zookeeper 的性能限制,我們無法讓每次系統内部調用都走 zookeeper,是以總有某些時刻,業務系統會存在兩個 master(業務系統 client 那邊緩存的業務系統 master 資訊是定時從zookeeper 更新的,是以會有更新不同步的問題)。

如果要在業務系統 client 的 master 資訊不一直的情況下,仍要保持系統的資料一緻性,唯一的方法是“先 kill 掉老 master,再在 zookeeper 上更新 master 資訊”。但是在是否要 kill current master 這個問題上,程式是無法完全自動決定的(因為網絡隔離的時候 zookeeper 已經不可用了,自動腳本沒有全局資訊,不管怎麼做都可能是錯的,什麼都不做也可能是錯的。當網絡故障的時候,隻有運維人員才有全局資訊,程式是無法接電話得知其他機房的情況的)。是以系統無法自動的保障資料一緻性,必須要人工介入。而人工介入的典型時間是半個小時以上,我們不能讓系統這麼長時間不可用。是以我們必須在某個方向上進行妥協,最常見的妥協方式是放棄‘強一緻性’,而接受‘最終一緻性’。

如果我們需要人工介入才能保證‘可靠的強一緻性’,那麼 zookeeper 的價值就大打折扣。

6.我們能做什麼 

我們或者選擇人工介入的強一緻性,或者選擇程式自動化進行的弱一緻性。需要進行取舍。

最終一緻性甚至未必是程式來做的,有時候人工修正資料反而在靈活、可靠、低成本上有優勢。這需要權衡。

不要迷信 zookeeper,有時候不妨考慮一下主備資料庫。資料庫自帶權限控制,用起來比 zookeeper 友善多了。

zookeeper 比較有價值的東西也許是内容變化的時候,可以阻塞回調的方式通知所有線上的 client 實時更新資訊,但這個功能用處不大。因為 php 這樣的子產品你很難說它是線上還是離線,每次都是新發起的。一旦這個功能無法支援 php,就無法覆寫整個系統,那麼就無法保證強一緻性了。

ps:以上隻是個人對 zookeeper 的一些認識,歡迎讨論和指正。 

繼續閱讀