B 站配置中心架構的演進

本期作者

王宗寶

嗶哩嗶哩資深開發工程師

陳碧仁

嗶哩嗶哩資深開發工程師

1、前言

配置中心的誕生和項目架構的演進有着密切的聯繫。傳統單體應用存在一些潛在缺陷,如隨着規模的擴大,部署效率降低,團隊協作效率差,系統可靠性變差,維護困難,新功能上線週期長等,所以迫切需要一種新的架構去解決這些問題,而微服務( microservices )架構正是當下一種流行的解決方案。不過,解決一個問題的同時,往往會面臨很多新的問題,所以微服務化的過程中伴隨着很多的挑戰,其中一個挑戰就是有關服務(應用)配置的。

(1)當系統從一個單體應用,被拆分成分佈式系統上一個個服務節點後,配置文件也必須跟着遷移(分割),這樣配置就分散了,各個服務都有自己的配置,隨着項目需求的不斷壯大發展,配置會越來越多,到最後繁瑣的配置文件會讓你越來越崩潰,稍不注意出個錯配置錯了就得修改配置重新打包部署,特別麻煩。

(2)在集羣部署的情況下,如果新版本的配置會給系統帶來很大的影響,我們往往會選擇灰度發佈,即先發布部分服務器,進行測試,穩定後再將配置同步到所有服務器,如果說還用傳統的方式,那麼我們就需要將配置文件一個個的修改然後重啓服務,雖然不需要我們開發自己去做,有運維,那也挺煩人的,運維發佈完了,我們還得檢查他改的是不是正確,費時費力。

(3)而且在系統不斷的迭代的過程中有些配置在多個服務之間都是相同或相近的,就會有很大的冗餘。

所以在分佈式、微服務這種大環境下,傳統的項目配置方式的弊端就慢慢的凸顯出來了,這個問題變得非常棘手,亟待一種管理配置、治理配置的解決方案。這時,配置中心就應運而生了。

2、配置中心 v1(Config)

自 2017 年 B 站開始着手配置中心的研發工作。希望能解決配置的統一管理,配置的訂閱與熱更,業務的透明接入等問題。

2.1 統一管理頁面

配置中心 v1 提供一個統一的配置管理後臺,對不同環境、不同應用進行權限隔離,實現操作配置方便和安全。在功能方面提供了公共配置和配置搜索等功能。

圖片

圖片

2.2 高可用

Config 在可用性上採用 Admin 廣播的形式進行集羣中各個節點的數據同步;在性能上採用 MySQL 存儲和磁盤存儲兩種存儲方式,MySQL 做持久化儲存,磁盤主要加快訪問速度。配置讀取時服務首先讀取本地磁盤數據,如果未命中,則直接讀取數據庫並緩存到內存中。

2.3 配置訂閱

配置中心 v1 在配置訂閱時採用長輪詢(long polling)方式實時監聽配置變更通知,如果沒有變更則 30 秒後返回 304,如果有變更立即返回。具體流程如下:

圖片

2.4 業務透明

配置中心對外提供統一的 SDK,用戶可以直接通過 SDK 接入配置中心。同時也對外提供 SDK 的訂閱和讀取接口,用戶可以根據需求自行實現各個接口。

2.5 侷限性

3、配置中心 v2(Paladin)

在配置中心 v1 使用多年情況下,隨着公司的規模不斷擴大,業務不斷擴展,越來越多的業務形態出現,原來的配置中心已經不能很好的滿足當前的業務需求,且配置中心 v1 版本也存在一定的侷限性,所以配置中心 v2 便應運而生。

v2 主要解決了以下幾個問題:

3.1 配置生命週期的管理和配置簡化

Config 將配置與版本獨立管理,變更發佈和管理難度大,配置的生命週期很難管理,且新用戶學習成本高。Paladin 將配置直接綁定到分組中,配置不在擁有獨立的版本。配置的變更只有在發佈後纔會有變更記錄,其版本的迭代和回滾以分組維度進行,不在分組版本中的配置即生命週期終止。同時也極大的簡化了配置變更和發佈的流程,降低了用戶的使用成本。

3.2 配置隔離

在 Config 中,配置的隔離不明顯,很容易因爲變更一個區域的配置導致所有區域的配置全部改變。在 Paladin 中配置隔離分爲租戶(Tenant)隔離、命名空間(Namespace)隔離和分組(Group)隔離。用戶可以根據自己業務爲維度做租戶進行配置的隔離,如:直播業務,電商業務,遊戲業務等等均可以作爲獨立的租戶。命名空間的隔離是在租戶隔離的基礎上業務根據不同環境,區域和功能做第二級別隔離,用戶只需保證同租戶下命名空間全局唯一即可保證配置隔離,如:電商業務:測試環境 - 上海區域 - 支付功能。分組隔離是在租戶和命名空間基礎上做的第三級隔離,用戶可以根據自己的需求使用不同的分組,分組之間的自定義配置是相互獨立相互隔離的,不會因爲改動一個配置而導致其他分組配置的變化。如下圖,Tenant 爲默認 public,Namespace 爲 Env,Zone 和 App 的組合,Group 即爲分組;業務可以據此做不同隔離。

3.3 增量發佈與讀取

對於大多數情況下應用的配置變更都是部分文件的變更,以及大文件變更和多客戶端訂閱,如果全量推送會佔用大量的帶寬。Paladin 中採用了版本信息與配置信息獨立存儲的方式進行,版本信息 Message 中保存該版本的所有配置文件信息列表,其中配置文件信息包括配置的 ID,變更狀態,配置內容的校驗信息(Checksum)以及配置信息的存儲 Key(KeyLink)。配置發佈時 Portal 將變更的配置與最近一次發佈生效的配置 merge,做到增量發佈。SDK 可以根據各個配置文件的變更狀態信息或者根據本地緩存對比最新的 Checksum 判斷配置是否需要更新,做到讀增量。

**3.4 提高 QPS 和推送延遲 **

Paladin 採用緩存的方式提高 QPS 和推送延遲。如下圖,緩存層分爲兩個部分,一部分爲存儲配置內容的 LRU 緩存,主要是用來加速配置的讀取。另一部是通知的緩存,爲了提高通知性能,Paladin 不在使用 Redis 做推送緩存,而是採用的是 HashMap 的形式做緩存,將各個 Namespace 下的配置存儲到同一個 Key 下,如果更新將會通知該租戶和命名空間下的所有分組,服務根據訂閱的 Labels 判斷是否通知 Client,這樣極大的提高了通知的效率和擴展性。

3.5 同集羣中各個節點數據一致性

Paladin 不在像 v1 一樣使用廣播的形式進行數據同步,而是採用 Raft 協議 [1,2] 保證集羣中各節點數據的一致性和集羣的高可用行。保證一半以上節點正常情況下數據讀寫正常。如下圖複製狀態機體系結構

3.6 高可用

爲了實現多活部署,Paladin 在模塊設計方面:

(1)將基礎數據層(Node)獨立成服,並將其與數據庫以及其他基礎組建解耦,全量保存所有用戶配置(一定的歷史版本),對外僅提供 Clients 的配置獲取和變更監聽。

(2)將 Portal 定位爲業務邏輯層,保存有配置的歷史數據,用戶信息,權限等。同時也統一對接公司內部的其他三方系統,提供了配置管理需要的所有元信息;

(3)Admin 組件僅封裝核心配置的修改、發佈等接口以及權限管理的支持,提供了統一對外的 OpenAPIs。

數據同步方面:Paladin 採用單數據庫中心,多集羣部署的方案。持久化數據保存在數據庫中,在配置發佈時 Portal 將同步發佈數據到各個 Node 集羣中,保證各個集羣數據同步。通過 anycast 保證各個機房的服務就近讀取該機房的配置中心配置。在某機房配置中心宕機後可以切換到其他機房讀取相應的配置,保證容災降級。

這樣可以保證:

(1)如果 Admin 故障,前端只需連接到其他的 Admin 服務即可保證業務繼續。

(2)如果 Portal 故障,Admin 可以重新連接其他的 Portal 服務也可以對外服務。

(3)如果某臺 Node 故障,每個節點都有完整的配置副本,客戶端重新連接到該區域其他節點即可。

(4)如果某個 Node 集羣故障,服務將會自動降級到其他的配置中心集羣讀取配置。

3.7 客戶端訂閱連接複用

在新的業務使用中,會遇到用戶單個服務監聽多個分組或者多個應用的情況。所以 SDK 支持連接複用有助於簡化用戶操作。同時爲了避免像 v1 一樣出現 SDK 不可控的情況,Paladin 團隊將維護所有語言的 SDK,對於不支持的語言 Paladin 提供物理機的 Agent 和 K8s 的 Sidecar 等方式將配置寫入服務自定義目錄下。這樣可以有效的控制 SDK 的版本以及後續 Paladin 的迭代升級。

4、功能特性

在借鑑 Config 的反饋之後,Paladin 提供更多的功能和特性以滿足新的業務需求,包括:

4.1 無感知接入

Paladin 提供了應用配置,這也是配置中心針對 B 站業務形態做的無感知接入。應用在滿足相應條件的情況下,業務可以在 PaaS 平臺直接創建和部署自己的業務,無須關心配置中心的存在,方便業務的使用。Paladin 是怎麼做到的?配置中心的應用配置規定了一套使用標準,而 PaaS 平臺按照該標準將相應的應用參數直接注入應用容器的環境變量中,業務在使用相應的默認配置參數時即無須關心配置中心和 PaaS 的聯動做到開箱即使用。

4.2 平臺空間

Paladin 支持平臺空間能力,允許不同平臺利用配置中心高可用、高容災能力以及穩定的配置下發通道,構建相應的平臺空間。平臺空間不能直接被普通業務直接感知,以一種類似於可擴展插件的方式提供。現在 B 站新一代的 ABTest 平臺以及服務治理平臺均已接入。我們以 ABTest 平臺爲例,業務可以根據自己的產品試驗需求,在 ABTest 平臺配置 A/B 測試配置,並在該平臺進行配置發佈,業務即可在其 ABTest 的平臺空間獲取到 A/B 配置,可以有效的降低業務對不同平臺的感知和接入複雜度。

4.3 Keyspace 配置

配置中心針對中間件如網關等,會涉及到各式各樣的應用,如果每一個應用在使用網關等中間件時都需要配置或者針對相應的 SDK 做大量的配置,將會極大的增加了業務的接入複雜度,同時如果中間件升級也需要所有接入業務做相應的大的變更,增大的非必須的成本。Paladin 針對該問題推出了 Keyspace 配置。該配置不在涉及到應用問題,可以集成到中間件的 SDK 中,業務應用只需引用相應的 SDK 既可以接入。同時中間件也可以根據不同需求或者功能對指定的配置做變更,作用與指定的業務。這將極大的降低接入和迭代的困難。

4.4 配置格式校驗

Paladin 支持如 xml,toml,yaml,json 等 10 餘種格式極其校驗。配置解析時如果配置格式錯誤將會導致客戶端解析失敗,所以配置中心會配置進行格式校驗,可以有效的防止因人爲操作導致的配置問題。

4.5 權限管理

配置的變更是會直接影響應用服務,對於重要的服務因配置的變更可能會帶來不可估量的後果。Paladin 在權限管理方面支持用戶權限管理,OpenAPI 權限管理,同時還支持變更通知與發佈審覈通知。

4.6 版本控制與回滾

當用戶需要對配置進行復盤時可以通過版本歷史和版本對比查看各個歷史上各個版本的配置,並能通過對比功能查看各個版本直接的差異。如果配置變更未達到預期也可以通過回滾操作將配置回滾到指定版本。

4.7 染色發佈

Paladin 提供染色發佈的能力,當配置變更影響較大時,用戶可以通過染色發佈在部分實例上發佈最新配置測試是否符合預期。如果符合則全量所有實例,如果不符合則可以直接取消染色迴歸到之前的配置。配置中心的染色發佈和公司服務治理平臺進行了完全打通,支持了相關多泳道能力的建設。如配置中心和 PaaS 平臺的聯動,做到發佈染色服務讀取染色配置等一整套流程。

4.8 增量發佈與讀取

Paladin 提供對配置的增量讀,一個配置版本的可能含有多個未變化配置,客戶端只需要加載變化的配置。

4.9 模版配置

Paladin 還支持模板配置,對於中間件或者其他公共服務的 SDK 需要的配置格式是固定的,絕大部分的 Value 也是固定的,這個時候中間件可以創建相應的模板,其他使用該中間件應用只需引用該模板從而可以降低因各個用戶的理解不同導致的配置問題。

4.10 複製與導入

Paladin 對不同區域的之間的配置可以使用導入或者複製功能直接操作,可以有效防止因人爲操作問題導致的配置出錯。

4.11 命令行運維工具

爲了更好的提供運維服務,Paladin 可以在僅有 Node 組件的情況下運維操作,即有助於運維,也可以在 Admin 和 Portal 均不能有效提供服務的情況下做緊急操作。

5、性能

作爲基礎服務,Paladin 的性能也是考察服務的關鍵點。配置中心本身是一個多讀的服務,在服務器 48 核 2.8GHZ,單節點 30 萬條配置的情況下,可以同時連接 6.5 萬個客戶端,平均推送耗時在 40 毫秒以下。在同樣服務器和配置的前提下,有一萬個客戶端同時監聽一個配置文件的變更,所需的推送時間也在 600 毫秒以內。

6、展望

配置中心是微服務基礎架構中不可或缺的核心組件,未來我們將繼續研究配置中心的應用模式與場景。Paladin 在功能上基本覆蓋了配置的大部分使用方式,後續我們將進一步優化用戶的使用體驗,抽象出 feature/vars 等場景化能力,並對大模型的數據的分發性能進行進一步的優化,以及結合公司的容器平臺研究適配 K8s 替代相應的 ETCD 提高相應的性能方面做努力。現代微服務架構和雲原生環境,對應用配置管理提出了更高的要求。配置驅動資源正在成爲雲計算的一個重要技術趨勢,雲計算相關的所有資源都可以通過配置去驅動 [3],未來也將研究如何在雲服務平臺上與其他服務整合。

參考文獻

[1]https://github.com/hashicorp/raft

[2]https://pages.cs.wisc.edu/~remzi/Classes/739/Spring2004/Papers/raft.pdf

[3]https://aws.amazon.com/cn/blogs/china/technical-selection-and-landing-practice-for-building-a-cloud-native-configuration-center

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/hu9RamJfUwJgDXX_jDYlVQ