閒聊註冊中心——ZK、Eureka、Sofa-Registry

文字 | jiayangchen

封面圖片 | Unsplash Clay Banks

1. 寫在前面

最開始服務之間的調用藉助的是域名,域名其實是個好東西,使用起來很方便,但所有調用請求都得走域名解析和負載均衡,相對來說性能就差一點,而且這些夾在中間的零部件會演變成性能瓶頸和潛在的單點風險。

後來大家一比較發現還不如直接端到端調用,那麼就需要一個東西把調用鏈的兩端連起來,這就是註冊中心。

圖片來源 主流微服務註冊中心淺析和對比

註冊中心提供服務的註冊發現,用來連接調用鏈路的 ProviderConsumer 這兩個端點。

一個註冊中心得管理好服務的擴縮容、故障轉移、流量分配這類的核心功能,自身同樣需要高可用,妥善解決跨地域部署情況下注冊中心節點之間的數據一致性。

因此我更傾向於認爲註冊中心是一個偏向體系化的產品,它的價值依賴於與之相匹配的服務規模和治理體系,它的思想雖然產生得很早,但是規模化地落地並不容易。

偏小的服務規模本身對於註冊中心的依賴並不明顯,實現的手段也沒有定式;大型服務又會對註冊中心的定位、功能提出更苛刻的需求。

2. CP 還是 AP

究竟是選擇強一致性還是高可用性,當下的主流技術選型傾向於後者,但這並不是說明 CP 組件沒有存在的意義,而是 AP 組件更契合互聯網對於註冊中心的定位。

互聯網系統高可用永遠是擺在首位的東西,因爲系統不可用的時間通常跟財產損失直接掛鉤。服務列表在短時間少了一兩個節點、多了一兩個節點,這點流量傾斜對於大多數服務來說感知並不明顯,只需要註冊中心在某個短暫的時間窗口內重新達到一致性的狀態就可以,註冊中心不應該在運行時影響到處於正常調用的兩個端點之間的連通性。

3. 放過 ZK 吧

CP 的代表就是 zookeeper,至今 zookeeper 也是非常流行的用於註冊中心的組件,這在一定程度上要感謝 dubbo

dubbozookeeper 中是用一個樹形結構的兩個節點,分別維護服務的 ProviderComsumer 的,列表註冊在這兩個節點下面,服務的健康檢查依賴 zookeeper 提供的臨時節點特性,實際上跟 session 的生命週期綁定在一起。但臨時節點的問題就是數據易失,一旦集羣故障節點重啓丟失服務列表,可能造成服務大面積癱瘓,電商新貴 PDD 就曾經出現過這個問題。

圖片來源 Dubbo 官網

CP 最關鍵的問題在於無法支持機房容災,例如 ABC 三個機房,機房 C 和其他兩個機房產生了網絡隔離,部署在機房 Czookeeper 節點是無法提供寫入的,這意味着機房 C 部署的 Provider 不能擴縮容、不能重啓,最好在故障期間一直保持原樣,否則 Provider 任何操作都會是高危的,會直接影響到部署在機房 CComsumer

順帶說一句,我認爲 zookeeper 真挺好的,它本身的定位就是個分佈式協調服務,並不是專門爲註冊中心設計的,你不能拿評價註冊中心的眼光去評價它,你要的功能 zookeeper 基本上都有,藉助 Curator 拿來就可以用,提供了 election,提供了 ZABTPS 低了點(其實也可以了)但是也滿足大部分服務規模。

4. Eureka 的掙扎

Eureka —— 奈飛的網紅組件,AP 註冊中心的代表。

Eureka 1.x 今天回頭看來是個很牽強的實現,因爲它的架構從誕生之日起,就意味着將來數據規模增長之後大概率會出問題,集羣整體可伸縮性很低,每擴容一臺 Eureka 節點意味着整體點對點之間需要多一份數據流,而這種 Peer 點對點機制的數據流很容易打滿網卡,造成服務端壓力。

根據公開的資料,Eureka 在實例規模五千左右時就會出現明顯的性能瓶頸,甚至是服務不可用的情況。

但是從另一個方面來說,Eureka 的架構清晰、運維部署都很方便,而且 Eureka 作爲 SpringCloud 推薦的註冊中心實現,國內用戶數目也相當可觀,可見在服務規模恰當的情況下其性能並沒有問題,從攜程的分享資料也可以看出,其內部的註冊中心也是類似於 Eureka 的實現。

可見沒有絕對完美的架構設計,適合自己、滿足業務需求才是最主要的。

圖片來源 infoQ:微服務註冊中心 Eureka 架構深入解讀,作者馬軍偉

Eureka 服務端多節點架構其實有點去中心化的意思,有意保持了每個節點的無狀態特性,但是代價就是每個節點都持有全量數據,新增的數據可以往任意一個節點寫入,然後由這個節點向其他節點廣播,最終達到一致性。

數據都沒有持久化,僅保存在內存中,帶來了更好的讀寫性能、更短的響應時間,但是無法處理數據瓶頸,大節點擴容造成的數據同步存在打滿網卡的風險,這點跟 redis 集羣很像。

客戶端 30s 定期上報心跳、客戶端緩存服務列表這些都沒什麼好談的,Eureka 有個很有意思的點是,它的集羣節點實現了一個自我保護機制,用來預測到底是集羣出問題還是客戶端出問題,實現很簡單但是思想挺實用的。

Eureka 2.0 的設計文檔上體現了讀寫分離集羣的思想,本質上是爲了提升集羣性能和容量,但是非常遺憾,目前 2.0 的狀態是 Discontinued,短時間應該不會有成熟的產品出現。

圖片來源 網絡

5. Sofa-Registry = 未來?

雖然沒有 Eureka 2.0,但是可以從螞蟻開源的 Sofa-Registry 中瞭解類似思想的實現,Sofa-Registry 脫胎於阿里的 ConfigServer,從公開的資料顯示,國內阿里應該是最早做註冊中心讀寫分離實踐的。

圖片來源 ConfigServer架構,作者庫昊天

這種架構帶來的直接好處就是可以支持海量數據。

第一層的 session 集羣可以無限水平擴展,彼此之間完全不需要通信,session 集羣在內存中維護了註冊中心需要的一切拓撲關係,客戶端僅僅連接一部分 session 集羣中的機器,如果某臺 session 機器掛了客戶端會選擇另一臺重連。

背後的 data 集羣則通過分片存儲所有的源數據,分片之間通過主從副本保證高可用,再將源數據推送到 session 集羣保存下來,供客戶端讀取。

缺點也很明顯,這種架構人力投入、運維成本肯定高於 Eureka

6. 跨地域部署

這幾乎是註冊中心不可避免的問題,高可用、機房容災、網絡延遲等都會催生出要求註冊中心節點能夠跨地域部署,這會引申出另一個問題就是如何做數據同步。

這種情況下已經不可能通過客戶端註冊或者是集羣節點數據流複製來保證異地註冊中心集羣之間的數據一致,而是會研發單獨的數據同步組件,通過跨地域專線實現地域間註冊中心的數據同步。

如果專線斷開,此時各自地域的註冊中心依舊可以獨立服務於本地域內服務的調用,等到專線恢復,二者的數據繼續進行同步合併糾正,最終達到一致性。

對這個知識點感興趣的可以瞭解下 Nacos-Sync 組件,是 Nacos 項目專門推出的開源數據同步服務。

7. 寫在最後

文章略過了一些註冊中心通用的概念,例如數據模型的分層、服務列表本地緩存、健康檢查的方式、推拉權衡等,我認爲敘述這些細節的意義並不大。

很多時候,理解某個組件我認爲最重要的是理清它的架構演進過程,這是寶貴的經驗財富,你可以抓住並學習每次架構演進的方向和原因。

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