單元化架構(gòu)在字節(jié)跳動(dòng)的落地實(shí)踐
1. 什么是單元化
單元化的核心理念是將業(yè)務(wù)按照某種維度劃分成一個(gè)個(gè)單元,理想情況下每個(gè)單元內(nèi)部都是完成所有業(yè)務(wù)操作的自包含集合,能獨(dú)立處理業(yè)務(wù)流程,各個(gè)單元均有其中一部分?jǐn)?shù)據(jù),所有單元的數(shù)據(jù)組合起來是完整的數(shù)據(jù)(各企業(yè)實(shí)際落地過程中會結(jié)合實(shí)際業(yè)務(wù)和基建情況做一些折中)。流量按照某種分區(qū)維度(例如流量所屬用戶)Sharding 到不同的單元,調(diào)度上按照流量攜帶的分區(qū)信息進(jìn)行調(diào)度,保證同一時(shí)刻該分區(qū)的數(shù)據(jù)寫入都在同一個(gè)單元,簡化版示意圖如下:
2. 為什么要做單元化
業(yè)界各企業(yè)演進(jìn)到單元化一般主要都是出于下面幾個(gè)原因:
- 資源限制:單機(jī)房受物理資源上限限制,同城多機(jī)房受地區(qū)的能評和供電等限制,無法做到機(jī)房的無限擴(kuò)展,隨著業(yè)務(wù)規(guī)模的擴(kuò)大,長期一定會面臨多地?cái)?shù)據(jù)中心的布局;
- 合規(guī)要求:全球化產(chǎn)品通常會面臨不同地區(qū)的合規(guī)要求(例如歐盟的 GDPR),會有當(dāng)?shù)赜脩魯?shù)據(jù)只能存儲在當(dāng)?shù)氐囊?,業(yè)務(wù)天然需要考慮圍繞不同的合規(guī)區(qū)域構(gòu)建單元;
- 容災(zāi)考慮:核心業(yè)務(wù)有城市級異地容災(zāi)需求,通過單元化方式可以構(gòu)建異地單元,每個(gè)單元都有常態(tài)真實(shí)流量,流量可以靈活地在單元間進(jìn)行調(diào)度。
除了上述最關(guān)鍵的問題外,建設(shè)單元化還能有其他方面的收益:
- 業(yè)務(wù)體驗(yàn)提升:通過結(jié)合就近調(diào)度,能夠?qū)⒂脩袅髁空{(diào)度到最近的單元,從而降低請求耗時(shí),提升用戶體驗(yàn);
- 成本方面:相比于異地冷備,兩地三中心等傳統(tǒng)容災(zāi)架構(gòu),各個(gè)單元都能直接承載流量,減少資源冗余;
- 隔離方面:在最小的單元范圍內(nèi)去做各種技術(shù)演進(jìn),能夠有效控制風(fēng)險(xiǎn)半徑。
3. 異地單元化的主要挑戰(zhàn)
機(jī)房延遲問題:一般同城機(jī)房之間物理距離 <200KM,網(wǎng)絡(luò)延遲和機(jī)房內(nèi)差別不大,大部分業(yè)務(wù)場景無需過多考慮。但跨城異地機(jī)房之間的延遲會大很多,例如北京和上海之間 RTT P99 達(dá) 40 毫秒,此時(shí)跨機(jī)房請求耗時(shí)需要慎重考慮,特別是單個(gè)請求如果出現(xiàn)多次跨機(jī)房,增加的請求耗時(shí)可能是幾百毫秒甚至更大的。
數(shù)據(jù)同步問題:
- 容災(zāi)單元之間的數(shù)據(jù)需要互通,以支持一個(gè)單元故障時(shí)能夠切流到另一個(gè)單元進(jìn)行容災(zāi),因此需要在單元間進(jìn)行數(shù)據(jù)同步;
- 數(shù)據(jù)同步需要考慮不同的存儲引擎(數(shù)據(jù)庫、緩存、消息隊(duì)列等),不同引擎特性不一,實(shí)現(xiàn)成本和復(fù)雜度巨大;
- 跨城機(jī)房間的延遲大而且是弱網(wǎng)環(huán)境,網(wǎng)絡(luò)的質(zhì)量很難保證,進(jìn)一步導(dǎo)致數(shù)據(jù)同步質(zhì)量保證難度大。
流量路由的問題:所謂流量路由也就是如何將流量調(diào)度到正確的單元問題,需要考慮在請求鏈路哪個(gè)環(huán)節(jié)(客戶端、流量入口、內(nèi)網(wǎng) RPC、存儲層等)、根據(jù)請求什么信息(用戶 ID、地理位置等)進(jìn)行用戶歸屬單元的識別,以及如何進(jìn)行走錯(cuò)單元流量的糾偏。
數(shù)據(jù)正確性問題:
- 例如歸屬
單元1
的用戶 A 評論了歸屬單元2
的用戶 B 的抖音短視頻,系統(tǒng)在單元1
給 B 發(fā)了一個(gè)通知,但 B 查看評論的流量被按 B 的單元?dú)w屬調(diào)度到了單元2
,由于數(shù)據(jù)同步延遲問題,B 打開抖音后看不到評論。業(yè)務(wù)上需要感知這類同步延遲帶來的正確性問題; - 另外兩個(gè)單元的數(shù)據(jù)庫構(gòu)建了雙向數(shù)據(jù)同步后,如果同一個(gè)用戶短時(shí)間在兩個(gè)單元讀寫同一份數(shù)據(jù),可能會出現(xiàn)數(shù)據(jù)沖突問題。
成本問題:
- 每個(gè)單元都需要有完整的業(yè)務(wù)資源以及支撐這些業(yè)務(wù)資源(計(jì)算、存儲、網(wǎng)絡(luò))的基礎(chǔ)設(shè)施(運(yùn)維平臺、觀測平臺等),需要綜合考慮對成本的影響;
- 異地單元化的改造落地涉及到包括基建、架構(gòu)、業(yè)務(wù)多方的配合支持,需要考慮人力上的成本。
管理復(fù)雜度問題:隨著單元的增加,不同的單元都需要管理對應(yīng)的服務(wù)和基建,管理和運(yùn)維的復(fù)雜性會有較大增加。
4. 字節(jié)跳動(dòng)異地單元化架構(gòu)
在本文中,我們僅對字節(jié)跳動(dòng)在中國大陸的單元化架構(gòu)做討論,目前我們的單元化部署架構(gòu)如下圖所示:
我們圍繞客戶端選路、接入層糾偏、計(jì)算層糾偏、存儲訪問層管控四個(gè)維度構(gòu)建了單元化流量調(diào)度和管控能力,通過技術(shù)手段確保單元化流量調(diào)度的正確性(將流量調(diào)度到正確的單元)和數(shù)據(jù)訪問的正確性(數(shù)據(jù)不寫臟),具體來說:
- 客戶端:在客戶端通過調(diào)度組件將用戶流量從第一跳開始就調(diào)度到正確的單元,減少在內(nèi)網(wǎng)的跨單元流量;
- 接入層:在網(wǎng)關(guān)通過網(wǎng)關(guān)的開放能力實(shí)現(xiàn)調(diào)度插件,按需對客戶端調(diào)度出錯(cuò)的流量進(jìn)行路由信息計(jì)算和糾偏;
- 計(jì)算層:計(jì)算層通過研發(fā)框架和 Mesh 的開放能力實(shí)現(xiàn)流量切面,確保對未經(jīng)過網(wǎng)關(guān)的內(nèi)部 RPC 流量的路由信息計(jì)算和糾偏;
- 存儲層:通過存儲訪問中間件和 Mesh 的開放能力實(shí)現(xiàn)流量切面,確保對存儲層路由出錯(cuò) / 異常單元化流量進(jìn)行審計(jì)和攔截。
目前包括抖音、抖音電商、抖音支付、抖音直播、抖音本地生活等業(yè)務(wù)均啟動(dòng)了異地單元化改造落地,生產(chǎn)環(huán)境已接入數(shù)千個(gè)核心微服務(wù)、超過 100 萬實(shí)例。
5. 單元化架構(gòu)落地的關(guān)鍵問題
5.1 如何選擇單元的維度
單元維度的選擇很大程度上決定了單元化架構(gòu)的水平擴(kuò)展能力、運(yùn)維成本和容災(zāi)方式,需要結(jié)合業(yè)務(wù)推進(jìn)單元化架構(gòu)想要解決的核心問題(資源、合規(guī)、容災(zāi))和業(yè)務(wù)特性來選型。業(yè)界實(shí)踐大部分是圍繞物理維度(例如 Region、機(jī)房)構(gòu)建單元,也有少部分是邏輯維度的。
結(jié)合我們面臨的業(yè)務(wù)特性:
- 同時(shí)有包括社交、電商、本地生活、直播、支付等多種類型的業(yè)務(wù),不同業(yè)務(wù)在單元化架構(gòu)上有不同考慮;
- 存在大量中臺,各中臺同時(shí)支持不同類型的業(yè)務(wù),這些中臺需要適配好不同上游業(yè)務(wù)的單元化流量和數(shù)據(jù);
- 業(yè)務(wù)之間有比較復(fù)雜的依賴,例如電商和本地生活有從抖音入口進(jìn)來的流量,也有自己獨(dú)立入口的流量。
綜合考慮,我們認(rèn)為字節(jié)跳動(dòng)的單元應(yīng)該是物理維度的,單元的建設(shè)隨著基建的規(guī)劃和建設(shè)去演進(jìn),而不是業(yè)務(wù)自行構(gòu)建,這種物理意義上的唯一調(diào)度依據(jù)能夠保證不同的業(yè)務(wù)長期演進(jìn)中能夠在一個(gè)單元內(nèi)閉環(huán),避免調(diào)度混亂。
同時(shí)考慮我們目前最核心要解決的問題是資源和容災(zāi)問題,因此我們最終選擇是 Region 維度構(gòu)建單元,形成當(dāng)前的 同城容災(zāi)+異地多活
容災(zāi)架構(gòu)。
5.2 如何選擇分區(qū)維度
分區(qū)維度決定了數(shù)據(jù)和流量在單元間的劃分標(biāo)準(zhǔn),選擇分區(qū)維度的時(shí)候需要重點(diǎn)考慮:
- 每個(gè)分區(qū)對應(yīng)的數(shù)據(jù)互相不能重疊,以保證同一時(shí)刻同一個(gè)分區(qū)維度的數(shù)據(jù)寫只在一個(gè)單元;
- 分區(qū)的粒度需要能支撐流量調(diào)度的靈活性要求,確保流量能按預(yù)期分布到各個(gè)單元;
- 路由信息的計(jì)算需要足夠輕量;
- 確保單元內(nèi)調(diào)用邏輯盡可能閉環(huán),避免產(chǎn)生跨單元調(diào)用。
一般 ToC 類業(yè)務(wù)最常見的就是以用戶作為分區(qū)維度,我們目前大部分業(yè)務(wù)選擇用戶(UserID)作為分區(qū)維度(抖音、電商等業(yè)務(wù)),少部分選擇 Region 維度(搜索等業(yè)務(wù))。
5.3 如何進(jìn)行流量的單元化調(diào)度
◇ 5.3.1 管理分區(qū)和單元的映射
分區(qū)和單元的映射也就是對于一個(gè)請求我們找到它應(yīng)該調(diào)度到哪個(gè)單元的依據(jù),需要綜合業(yè)務(wù)上對管理成本和靈活性的要求來考慮,我們通過以下兩種方式結(jié)合來管理:
- 映射表:通過
UserID -> Set
的映射表管理,面向 QA 測試、高價(jià)值用戶群灰度等明確指定歸屬單元場景; - 表達(dá)式:通過流量分片的方式,按比例將流量在單元間分配,以支持比較低的管理和計(jì)算成本,例如
0 <= Hash(UserID) % 100000 < 70000 -> Set1、70000 <= Hash(UserID) % 100000 < 100000 -> Set2
。
◇ 5.3.2 計(jì)算路由信息和糾偏
路由信息的計(jì)算邏輯一般不復(fù)雜,更關(guān)鍵的是決策需要在哪些環(huán)節(jié)計(jì)算以及怎么糾偏(把走錯(cuò)單元的流量調(diào)度到正確單元),一般來說,整個(gè)請求鏈路包括客戶端、接入層、計(jì)算層和存儲層四層,需要結(jié)合公司基建情況和業(yè)務(wù)要求來決策落地方式,以下是我們對于各層實(shí)現(xiàn)糾偏能力的必要性和實(shí)現(xiàn)方式上的思考和建議。
客戶端:
- 必要性分析:在客戶端直接計(jì)算流量歸屬單元并調(diào)度,可以減少在內(nèi)網(wǎng)出現(xiàn)跨單元訪問的情況,減少跨單元導(dǎo)致的耗時(shí)影響;
- 實(shí)現(xiàn)方式:可以在客戶端集成調(diào)度組件來實(shí)現(xiàn),具體調(diào)度邏輯需要結(jié)合單元的維度來設(shè)計(jì),例如最簡單可以不同單元對應(yīng)不同域名,按 UserID 映射到對應(yīng)域名。
接入層(負(fù)載均衡、網(wǎng)關(guān)):
- 必要性分析:客戶端由于改造依賴用戶升級、同時(shí)網(wǎng)絡(luò)環(huán)境復(fù)雜導(dǎo)致配置變更時(shí)生效時(shí)間無法保證,因此存在無法 100% 保證流量調(diào)度正確的情況,需要在接入層兜底計(jì)算路由信息并對走錯(cuò)單元的流量進(jìn)行糾偏;
- 實(shí)現(xiàn)方式:在流量入口,結(jié)合 LB / 網(wǎng)關(guān)的開放能力,實(shí)現(xiàn)路由信息的計(jì)算和流量糾偏能力。
計(jì)算層:
- 必要性分析:實(shí)際業(yè)務(wù)上,存在很多內(nèi)部的 RPC 流量,例如消息隊(duì)列的 Consumer 發(fā)起請求、后臺定時(shí)任務(wù)發(fā)起的請求等,這種流量不經(jīng)過接入層,需要在計(jì)算層 RPC 接口兜底進(jìn)行路由信息計(jì)算并對走錯(cuò)單元的流量進(jìn)行糾偏;
- 實(shí)現(xiàn)方式:可以結(jié)合研發(fā)框架或者 Service Mesh 的開放能力實(shí)現(xiàn)。
存儲層:
- 必要性分析:業(yè)務(wù)上會存在例如一個(gè)用戶去讀寫另一個(gè)用戶的數(shù)據(jù)(例如社交場景的點(diǎn)贊、評論)這類不經(jīng)過 RPC 接口調(diào)度的場景,需要在存儲訪問的時(shí)候兜底計(jì)算路由信息并對走錯(cuò)單元的流量進(jìn)行糾偏;
- 實(shí)現(xiàn)方式:一般可以結(jié)合存儲訪問中間件或者 ServiceMesh 開放能力實(shí)現(xiàn)。實(shí)際落地的時(shí)候,考慮到存儲訪問層實(shí)現(xiàn)糾偏成本和風(fēng)險(xiǎn)偏高(例如連接數(shù)風(fēng)險(xiǎn)),實(shí)際業(yè)務(wù)落地上可以考慮只做攔截,推動(dòng)業(yè)務(wù)進(jìn)行改造。
一個(gè)比較完整的分層示例:
5.4 如何適配復(fù)雜的業(yè)務(wù)調(diào)度場景
理想的單元化架構(gòu)是所有服務(wù)都能在單元內(nèi)閉環(huán),不出現(xiàn)跨單元的流量,但是在實(shí)際業(yè)務(wù)場景下很難滿足理想的單元化架構(gòu)。以電商場景為例,如果用買家作為分區(qū)維度,那商家的數(shù)據(jù)必然會被多單元讀寫,因此一定存在部分服務(wù)的流量不能單元化調(diào)度的情況,單元化架構(gòu)需要能做好適配。和業(yè)界基本思路類似,我們對服務(wù)類型做了區(qū)分:
- 本地服務(wù)/LocalService:單元化拆分后能夠本地閉環(huán)讀寫的業(yè)務(wù)服務(wù),比如在電商場景的買家業(yè)務(wù)相關(guān)服務(wù)。業(yè)務(wù)的大部分微服務(wù)應(yīng)當(dāng)都是 LocalService 類似,否則傾向于部署單 vRegion 部署;
- 中心服務(wù)/CentralService:無法進(jìn)行單元化拆分的業(yè)務(wù),固定在某個(gè)單元部署,通常是一些對于數(shù)據(jù)一致性要求非常高的服務(wù),例如電商的商家、商品庫存等服務(wù)。
服務(wù)類型決定了流量調(diào)度方式和服務(wù)訪問的數(shù)據(jù)的同步方式。基于此,研發(fā)核心需要關(guān)注業(yè)務(wù)上服務(wù)類型的定義即可,其他包括數(shù)據(jù)同步管理、流量調(diào)度的細(xì)節(jié)都可以由框架/平臺內(nèi)部收斂解決,極大降低業(yè)務(wù)上的理解和管理復(fù)雜度:
實(shí)際業(yè)務(wù)落地過程中,甚至?xí)霈F(xiàn)同一個(gè)服務(wù)不同接口的訪問行為不一致的情況,需要細(xì)化到接口維度區(qū)分類型,和服務(wù)類型類似設(shè)計(jì)即可,這里不贅述。
5.5 如何進(jìn)行多單元數(shù)據(jù)管理
◇ 5.5.1 單元間數(shù)據(jù)同步
單元化架構(gòu)下的數(shù)據(jù)同步有兩種場景:
- 中心服務(wù)訪問的數(shù)據(jù)在單元間單向同步,支持延遲敏感且接受一定程度數(shù)據(jù)不一致的業(yè)務(wù)場景本地只讀;
- 本地服務(wù)訪問的數(shù)據(jù)在容災(zāi)單元間的雙向同步,支持一個(gè)單元出現(xiàn)故障的時(shí)候能夠?qū)⒘髁壳械饺轂?zāi)單元進(jìn)行容災(zāi),數(shù)據(jù)同步需要考慮好防回環(huán)和唯一 Key 沖突處理。
◇ 5.5.2 數(shù)據(jù)同步一致性比對
數(shù)據(jù)對賬一般是全增結(jié)合,實(shí)時(shí)增量比對確保 Diff 發(fā)現(xiàn)的實(shí)時(shí)性,但寫入 TPS 高時(shí)會有誤差,周期全量比對兜底保證整體一致率,常見的一致性比對流程如下:
設(shè)計(jì)增量數(shù)據(jù)一致性比對能力的時(shí)候,需要重點(diǎn)考慮對熱鍵的檢測和處理,部分熱鍵一直在 Update 的話需要能識別出來,否則會導(dǎo)致持續(xù)有不一致誤報(bào)警,一個(gè)簡單的基于重試比對的實(shí)現(xiàn)如下:
5.6 如何保證數(shù)據(jù)多活的正確性
◇ 5.6.1 日常態(tài):異常單元化流量的識別和攔截
以 UserID 作為單元化分區(qū)維度的話,在實(shí)際業(yè)務(wù)場景可能出現(xiàn)兩種異常情況:
從請求里面無法解析到正常的 UserID 或者未接入流量調(diào)度組件導(dǎo)致未正常計(jì)算路由信息;
一個(gè)用戶的流量在代碼邏輯層直接訪問數(shù)據(jù)庫,寫了另一個(gè)非歸屬本單元的用戶的數(shù)據(jù)。
這兩種情況我們都認(rèn)為是異常單元化流量,在存儲訪問層通過管控中間件支持了識別和攔截能力,兜底保障數(shù)據(jù)不被寫臟:
◇ 5.6.2 切流態(tài):避免數(shù)據(jù)同步延遲導(dǎo)致臟寫
在做單元間切流的時(shí)候,由于下面兩個(gè)問題,可能導(dǎo)致數(shù)據(jù)出現(xiàn)臟寫:
- 跨城異地單元之間的數(shù)據(jù)同步延遲一般接近或達(dá)到秒級,用戶流量從一個(gè)單元切換到另一個(gè)單元的時(shí)候可能由于數(shù)據(jù)還未同步完成從而出現(xiàn)臟寫;
- 單元間切流本質(zhì)上是分區(qū)和單元映射配置的變化和重新下發(fā)的過程,在大規(guī)模分布式架構(gòu)下,這份配置需要下發(fā)到多個(gè)獨(dú)立的實(shí)例上去生效,這些不同的實(shí)例生效時(shí)間無法完全一致,就導(dǎo)致同一個(gè)用戶的流量短時(shí)間可能進(jìn)入不同單元從而導(dǎo)致數(shù)據(jù)臟寫。
我們對切流過程引入 兩階段配置變更+存儲訪問禁寫
來解決上述數(shù)據(jù)臟寫問題,整體切流流程如下:
得益于我們整體單元化調(diào)度和存儲訪問中間件設(shè)計(jì),我們的禁寫是 UserID 維度的,能夠控制到每次切流僅禁寫切流中的用戶,將切流的影響做的盡可能小。
5.7 如何確保切流的可靠性和風(fēng)險(xiǎn)控制
◇ 5.7.1 優(yōu)化配置下發(fā)時(shí)效
結(jié)合前面關(guān)于切流期間通過 兩階段配置變更+存儲訪問禁寫
來避免數(shù)據(jù)出現(xiàn)臟寫的說明,可以看到配置下發(fā)生效的時(shí)間對于禁寫時(shí)長是一個(gè)非常大的影響因素,而禁寫生效時(shí)長直接影響切流那部分用戶的使用體驗(yàn),因此我們需要盡可能提升配置下發(fā)時(shí)效。
目前字節(jié)接入單元化的 Pod 數(shù)已超過 100萬,在這么大規(guī)模的實(shí)例數(shù)下快速下發(fā)調(diào)度配置的挑戰(zhàn)是非常大的,我們通過 長連接主動(dòng)推送+定時(shí)輪詢拉取
的方式進(jìn)行配置分發(fā),提高配置收斂速度,減少配置不一致中間態(tài)的時(shí)間:
◇ 5.7.2 防止路由死循環(huán)
配置發(fā)布過程中,同一個(gè) PSM 不同單元實(shí)例的生效時(shí)間不一樣,可能導(dǎo)致流量糾偏到目標(biāo)單元后由于目標(biāo)單元重新計(jì)算糾偏回來,出現(xiàn)路由死循環(huán)的情況。我們通過單元化調(diào)度組件在流量上下文中記錄并傳遞糾偏次數(shù),攔截重復(fù)糾偏的流量,及時(shí)阻斷回環(huán)流量:
◇ 5.7.3 切流過程業(yè)務(wù)架構(gòu)各層狀態(tài)檢查
多實(shí)例配置生效版本觀測檢查:每次配置發(fā)布會分配一個(gè)遞增的版本號,數(shù)據(jù)面組件通過長連接上報(bào) Pod 當(dāng)前配置版本號給配置中心,從而支持單元化控制面查詢和觀測配置收斂情況:
數(shù)據(jù)同步延遲觀測檢查:由于我們的切流禁寫是用戶維度的,不是整個(gè)數(shù)據(jù)庫禁寫,禁寫過程中數(shù)據(jù)庫并不是完全沒有新的寫流量,因此我們是根據(jù) 數(shù)據(jù)實(shí)時(shí)的同步延遲+禁寫等待時(shí)間
結(jié)合來判斷切流范圍的用戶禁寫后的數(shù)據(jù)是否已經(jīng)同步:
業(yè)務(wù)核心指標(biāo)觀測檢查:切流過程中對業(yè)務(wù)成功率、負(fù)載、延遲等指標(biāo)的觀測。
5.8 如何保證跨地區(qū) RPC 質(zhì)量
單元之間通常物理距離較遠(yuǎn),網(wǎng)絡(luò)專線建設(shè)難度大成本高,網(wǎng)絡(luò)質(zhì)量(延遲、丟包、可用帶寬)也差于同城機(jī)房間。前面介紹的各種單元路由糾偏都會產(chǎn)生跨單元 RPC,相比單元內(nèi) RPC 其成功率/耗時(shí)指標(biāo)有所劣化。為了提升跨單元 RPC 質(zhì)量,除了網(wǎng)絡(luò)專線本身的穩(wěn)定性建設(shè)(屬于網(wǎng)絡(luò)基建范疇,此處不展開),也可以在架構(gòu)設(shè)計(jì)和帶寬使用策略上進(jìn)行針對性的優(yōu)化。
跨單元 RPC 通道收斂:在單元化流量路由場景,某個(gè)流量很大的 RPC 服務(wù)可能僅小比例命中跨單元糾偏,此時(shí)由于下游實(shí)例數(shù)量很多可能導(dǎo)致連接復(fù)用效果較差。此時(shí)如果讓所有跨單元 RPC 先統(tǒng)一經(jīng)過本地邊界網(wǎng)關(guān),然后傳輸?shù)狡渌麊卧倪吔缇W(wǎng)關(guān),最后再轉(zhuǎn)發(fā)給實(shí)際下游,則建連過程拆分成了 3 段,中間段(網(wǎng)關(guān)之間)被所有跨單元 RPC 共用,可以保持較高的鏈接復(fù)用率; 另外 2 段為本地建連,即使連接復(fù)用率低,帶來的耗時(shí)增加也較少。此外收斂到網(wǎng)關(guān)通道也更容易集中對跨單元 RPC 進(jìn)行其他優(yōu)化,比如按接口等級進(jìn)行 QoS 管控、在專線完全故障情況下對重要的控制信令做加密后 Fallback 到公網(wǎng)傳輸?shù)龋?/span>
跨單元網(wǎng)絡(luò)分級 QoS 管控:長距離專線建設(shè)成本高,帶寬有限,也更容易因?yàn)楦黝惍惓?dǎo)致可用帶寬變少,無法滿足所有場景的跨單元網(wǎng)絡(luò)傳輸?shù)男枨?,因此需要對不同類型的跨單元流量進(jìn)行分級 QoS 管控。跨機(jī)房 RPC 失敗要么直接影響用戶體驗(yàn),要么導(dǎo)致故障無法操作止損,應(yīng)在跨單元網(wǎng)絡(luò)傳輸中給予更高的優(yōu)先級; 離線數(shù)據(jù)傳輸容易短時(shí)間大量占用帶寬,異常對用戶感知相對不明顯,應(yīng)給以較低優(yōu)先級,嚴(yán)格限制上限,必要時(shí)還應(yīng)讓出帶寬:
6. 未來演進(jìn)思考
6.1 多單元研發(fā)成本和效率優(yōu)化
字節(jié)跳動(dòng)從原本的單 Region 內(nèi)同城容災(zāi)架構(gòu)演進(jìn)到多 Region 異地單元化架構(gòu)周期比較短(一年半左右),基礎(chǔ)設(shè)施對多 Region 視角的支持還比較不足,對業(yè)務(wù)的整體研發(fā)和業(yè)務(wù)管理成本偏高,需要將多 Region 的研發(fā)和業(yè)務(wù)管理成本打平到單 Region。
6.2 極致的成本優(yōu)化
從計(jì)算資源成本視角:在原來三機(jī)房同城容災(zāi)模式下,每個(gè)機(jī)房需要預(yù)留 50% 的 Buffer 用于機(jī)房故障容災(zāi),演進(jìn)到異地單元化架構(gòu)后,基于兩個(gè)容災(zāi)單元間的六個(gè)機(jī)房,部分業(yè)務(wù)機(jī)房故障可以將流量分?jǐn)偟狡渌鍌€(gè)機(jī)房,此時(shí)各機(jī)房僅需 20% 的 Buffer。
從存儲資源成本視角:我們現(xiàn)在是 同城容災(zāi)+異地多活
的容災(zāi)模式,各單元都支持同城容災(zāi),因此部分業(yè)務(wù)可以直接進(jìn)行數(shù)據(jù)的單元化拆分,單元內(nèi)各自只有一部分?jǐn)?shù)據(jù)(加起來是全量數(shù)據(jù)),理想情況下存儲成本減少一半。
6.3 更復(fù)雜的單元化架構(gòu)演進(jìn)
未來字節(jié)跳動(dòng)在國內(nèi)會有更多的區(qū)域,不同業(yè)務(wù)在各單元的排布模型會越來越復(fù)雜,結(jié)合我們復(fù)雜的業(yè)務(wù)依賴關(guān)系,這里的流量調(diào)度模型、數(shù)據(jù)單元化和同步模型都需要演進(jìn)。
未來區(qū)域增多后,業(yè)務(wù)隨著發(fā)展機(jī)房排布會調(diào)整,可能會需要在非容災(zāi)單元之間調(diào)整流量,此時(shí)存在數(shù)據(jù)單元化拆分和用戶維度數(shù)據(jù)單元間搬遷能力,需要解決用戶維度數(shù)據(jù)的識別和低成本搬遷問題。
6.4 更完善的數(shù)據(jù)多活能力
字節(jié)跳動(dòng)目前的存儲對 AP 場景更友好(側(cè)重抖音這種社交類場景),主要圍繞單 Region 構(gòu)建,在多單元場景下對于電商、支付類(對數(shù)據(jù)一致要求非常高)的業(yè)務(wù)支持較弱,在異地單元化架構(gòu)下強(qiáng)依賴數(shù)據(jù)同步能力來支持多單元數(shù)據(jù)多活能力,業(yè)務(wù)上的限制偏大(例如寫只能統(tǒng)一在一個(gè)單元),有跨 Region 強(qiáng)一致數(shù)據(jù)庫的需求。