-
zookeeper不是為高可用設計的
- 由於要跨機房容災,很多系統實際上是需要跨機房部署的。出於性價比的考慮,通常會讓多個機房同時工作,而不會搭建N倍冗余。也就是說單個機房肯定撐不住全流量。由於zookeeper集群只能有一個master,因此一旦機房之間出現故障,zookeeper master就只能照顧一個機房,其他機房由於沒有master,都只能停止工作。於是所有的流量集中到有master的那個機房,於是系統crash。
- 即使同一個機房里面,由於網段不同,在調整機房交換機的時候偶爾也會發生網段隔離的情況。實際上機房每個月基本都會發生短暫的網絡隔離之類的子網段調整。在那個時刻zookeeper處於不可用狀態。如果整個業務系統基於zookeeper,則系統的可用性將非常脆弱。
- 由於zookeeper對於網絡隔離的極度敏感,導致zookeeper對於網絡的風吹草動都會做出激烈反應。這使得zookeeper的不可用時間比較多,我們不能讓zookeeper的不可用,變為系統的不可用。
zookeeper選舉過程很慢
- 這是一個很難從理論分析上看到的弱點,但是你一點遇上就會很痛苦
- 之前說過,網絡實際上常常會出現隔離等不完整狀態的,而zookeeper對那種情況非常敏感。一旦出現網絡隔離,zookeeper就會發起選舉流程。
- zookeeper的選舉流程非常耗時間,通常耗時30至120秒,期間zookeeper由於沒有master,都是不可用的。
- 對於網絡里面偶爾出現的,比如半秒一秒的網絡隔離,zookeeper會由於選舉過程,而把不可用時間放大幾十倍。
zookeeper性能是有限的
- 典型的zookeeper的tps大概是一萬多,無法覆蓋系統每天動輒幾十億的調用。因此每次請求都去zookeeper獲取業務系統master是不可能的。
- 因此zookeeper的client必須自己緩存業務系統的master地址。
- 因此zookeeper提供的強一致性實際上是不可用的。如果我們需要強一致性,還需要其他機制來進行保證。比如:用腳本自動將系統old master給Kill掉。
zookeeper權限薄弱
- zookeepr權限系統非常薄弱
- 在大型分布式系統中,使用zookeeper必須再額外開發一套權限系統。
- 額外的權限系統不但增加了系統的復雜度和維護成本,而且降低了系統的性能。
即使有了zookeeper也很難避免業務系統的數據不一致
- 前面已經討論過了,由於zookeeper的性能限制,我們無法讓每次系統內部調用都走zookeeper,因此總有某些時刻,業務系統會存在兩個master(業務系統client那邊緩存的業務系統master信息是定時從zookeeper更新的,因此會有更新不同步的問題)。
- 如果要在業務系統client的master信息不一致的情況下,仍要保持系統的數據一致性,唯一的方法是“先kill掉老master,再在zookeeper上更新master信息”。但是在是否要kill current master這個問題上,程序是無法完全自動決定的(因為網絡隔離的時候zookeeper已經不可用了,自動腳本沒有全局信息,不管怎么做都可能是錯的,什么都不做也可能是錯的。當網絡故障的時候,只有運維人員才有全局信息,程序是無法接電話得知其他機房的情況的)。因此系統無法自動的保障數據一致性,必須要人工介入。而人工介入的典型時間是半個小時以上,我們不能讓系統這么長時間不可用。因此我們必須在某個方向上進行妥協,最常見的妥協方式是放棄‘強一致性’,而接受‘最終一致性’。
- 如果我們需要人工介入才能保證‘可靠的強一致性’,那么zookeeper的價值就大打折扣。
如何做能更大提升zookeeper可用性
- 我們或者選擇人工介入的強一致性,或者選擇程序自動化進行的弱一致性。需要進行取舍。
- 最終一致性甚至未必是程序來做的,有時候人工修正數據反而在靈活、可靠、低成本上有優勢。這需要權衡。
- 不要迷信zookeeper,有時候不妨考慮一下主備數據庫。數據庫自帶權限控制,用起來比zookeeper方便多了。
- zookeeper比較有價值的東西也許是內容變化的時候,可以阻塞回調的方式通知所有在線的client實時更新信息,但這個功能用處不大。因為php這樣的模塊你很難說它是在線還是離線,每次都是新發起的。一旦這個功能無法支持php,就無法覆蓋整個系統,那么就無法保證強一致性了。