ZooKeeper 並不適合做注冊中心


zookeeper 的 CP 模型不適合注冊中心

zookeeper 是一個非常優秀的項目,非常成熟,被大量的團隊使用,但對於服務發現來講,zookeeper 真的是一個錯誤的方案。

在 CAP 模型中,zookeeper 是 CP,意味着面對網絡分區時,為了保持一致性,他是不可用的。

因為 zookeeper 是一個分布式協調系統,如果使用最終一致性(AP)的話,將是一個糟糕的設計,他的核心算法是 Zab,所有設計都是為了一致性。

對於協調系統,這是非常正確的,但是對於服務發現,可用性是第一位的,例如發生了短暫的網絡分區時,即使拿到的信息是有瑕疵的、舊的,也好過完全不可用。

zookeeper 為協調服務所做的一致性保障,用在服務發現場景是錯誤的。

注冊中心本質上的功能就是一個查詢函數:

ServiceList = F(service-name)

service-name 為查詢參數,得到對應的可用的服務端點列表 endpoints(ip:port)

我們假設不同的客戶端得到的服務列表數據是不一致的,看看有什么后果。

一個 serviceB 部署了 10 個實例,都注冊到了注冊中心。

現在有 2 個服務調用者 service1 和 service2,從注冊中心獲取 serviceB 的服務列表,但取得的數據不一致。

s1 = { ip1,ip2 ... ip9 }
s2 = { ip2,ip3 ... ip10 }

這個不一致帶來的影響是什么?

就是 serviceB 各個實例的流量不均衡

ip1 和 ip10 的流量是單份的,ip2-ip9 流量是雙份的。

這個不均衡有什么嚴重影響嗎?並沒有,完全可以接受,而且,又不會一直這樣。

所以,注冊中心使用最終一致性模型(AP)完全可以的。

現在我們看一下 CP 帶來的不可用的影響。

3個機房部署 5 個 ZK 節點。

現在機房3出現網絡分區了,形成了孤島。

發生網絡分區時,各個區都會開始選舉 leader,那么節點數少的那個分區將會停止運行,也就是 ZK5 不可用了。

這時,serviceA 就訪問不了機房1和機房2的 serviceB 了,而且連自己所在機房的 serviceB 也訪問不了了。

不能訪問其他機房還可以理解,不能訪問自己機房的服務就理解不了了,本機房內部的網絡好好的,不能因為你注冊中心有問題就不能訪問了吧。

因為注冊中心為了保障數據一致性而放棄了可用性,導致同機房服務之間無法調用,這個是接受不了的。

所以,注冊中心的可用性比數據強一致性更加重要,所以注冊中心應該是偏向 AP,而不是 CP。

以上表述的是 zookeeper 的 CP 模型並不適合注冊中心的需求場景。

zookeeper 的性能不適合注冊中心

在大規模服務集群場景中,zookeeper 的性能也是瓶頸。

zookeeper 所有的寫操作都是 leader 處理的,在大規模服務注冊寫請求時,壓力巨大,而且 leader 是單點,無法水平擴展。

還有所有服務於 zookeeper 的長連接也是很重的負擔。

zookeeper 對每一個寫請求,都會寫一個事務日志,同時會定期將內存數據鏡像dump到磁盤,保持數據一致性和持久性。

這個動作會降低性能,而且對於注冊中心來講,是不需要的。

小結

從 CP 模型上來講,zookeeper 並不適合注冊中心高可用的需要。

從性能上來講,zookeeper 也無法滿足注冊中心大規模且頻繁注冊寫的場景。

你可能會問,zookeeper 既然這么多問題,他咋不改呢?

其實,這並不算是 zookeeper 的問題,是人家本來就不適合做注冊中心,非要用他的話,肯定一堆問題。

zookeeper 的特長是做分布式協調服務,例如 kafka、hbase、flink、hadoop 等大項目都在用 zookeeper,用的挺好的,因為是用對了地方。

例如可以看下:kafka 中 zookeeper 具體是做什么的?

你有什么看法,歡迎留言交流。

參考資料:

http://jm.taobao.org/2018/06/13/做服務發現?/

https://medium.com/knerd/eureka-why-you-shouldnt-use-zookeeper-for-service-discovery-4932c5c7e764

推薦閱讀:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM