作者 | 弘遠(yuǎn)君
導(dǎo)讀
introduction
本文以百度垂類離線計(jì)算系統(tǒng)的演進(jìn)方向?yàn)橹骶€,詳細(xì)描述搜索垂類離線計(jì)算系統(tǒng)發(fā)展過程中遇到的問題,以及對(duì)應(yīng)的解決方案。架構(gòu)演進(jìn)過程中一直奉行“沒有最好的架構(gòu),只有最合適的架構(gòu)”的宗旨,面對(duì)不同階段遇到的問題,給出了適合的解決方案。尤其是近10年來的超大規(guī)模系統(tǒng)架構(gòu)的升級(jí), 一方面需要考慮系統(tǒng)本身的通用性和適配性,以滿足多個(gè)業(yè)務(wù)方的需求;另一方面需要結(jié)合系統(tǒng)當(dāng)前運(yùn)行的特點(diǎn),在易用性、穩(wěn)定性、智能化等不同方面進(jìn)行提升。希望讀者能在了解系統(tǒng)演進(jìn)的過程中獲得一些啟發(fā)。
全文9127字,預(yù)計(jì)閱讀時(shí)間23分鐘。
GEEK TALK
01
相關(guān)背景介紹
在過去,用戶通過“百度一下”得到的搜索結(jié)果是從互聯(lián)網(wǎng)上抓取來的結(jié)果,也被稱為“自然結(jié)果”。隨著網(wǎng)絡(luò)信息日益豐富,自然結(jié)果不能有效滿足用戶需求。為了解決自然結(jié)果無法滿足搜索需求的問題,提出了針對(duì)各個(gè)垂類深耕的搜索結(jié)果的解決方案,一方面為用戶帶來的更優(yōu)質(zhì)的內(nèi)容,讓用戶體驗(yàn)即搜即得的便捷,另一方面也可以幫助優(yōu)質(zhì)內(nèi)容生產(chǎn)者提升訪問量。
隨著業(yè)務(wù)發(fā)展,除了標(biāo)準(zhǔn)通用的業(yè)務(wù)處理需求變更之外,越來越多的業(yè)務(wù)有自定義代碼的更新需求。通過自定義數(shù)據(jù)處理,一方面,產(chǎn)品負(fù)責(zé)同學(xué)可以將原始傳入的數(shù)據(jù)按照業(yè)務(wù)需求進(jìn)行定制化處理,將原始數(shù)據(jù)轉(zhuǎn)化為最終搜索的結(jié)果數(shù)據(jù)。 另一方面,通用默認(rèn)的一些功能機(jī)制限制了少量垂類的發(fā)展,業(yè)務(wù)希望引入更多的策略 模型邏輯 信號(hào)等處理以及打分機(jī)制,提升排序召回的效果。
在這樣的背景下,業(yè)務(wù)對(duì)于數(shù)據(jù)加工計(jì)算的框架引擎的需求越來越強(qiáng)烈,并且功能也逐漸成為整個(gè)垂搜離線處理過程中不可或缺的一部分。
GEEK TALK
02
計(jì)算系統(tǒng)演進(jìn)過程
百度搜索系統(tǒng)離線數(shù)據(jù)處理從時(shí)間線的發(fā)展階段來說一共經(jīng)歷如下幾個(gè)階段:
a.原始離線處理系統(tǒng): 本階段主要是實(shí)現(xiàn)業(yè)務(wù)加工入口從0到1的構(gòu)建。整體上還沒有形成完備的框架體系并且開發(fā)成本較高,并且所有業(yè)務(wù)邏輯混在一個(gè)公共服務(wù)中,不同數(shù)據(jù)通過不同配置調(diào)用不同的策略邏輯。
b.業(yè)務(wù)離線處理架構(gòu): 本階段初步形成一整套的業(yè)務(wù)服務(wù)處理框架,有統(tǒng)一的服務(wù)框架和開發(fā)階段,實(shí)現(xiàn)了云原生和服務(wù)隔離的模式。
c.Serverless架構(gòu): 本階段業(yè)務(wù)的接入效率上進(jìn)一步提高,業(yè)務(wù)從管理服務(wù)面向轉(zhuǎn)向管理業(yè)務(wù)加工函數(shù),業(yè)務(wù)只需注冊(cè)函數(shù)就可以快速測(cè)試上線,同時(shí)支持容器實(shí)例的自動(dòng)伸縮,使得在業(yè)務(wù)的使用效率得到的極大提升的同時(shí)相應(yīng)資源成本急劇壓縮。
d.數(shù)據(jù)智能架構(gòu): 在原有服務(wù)部署的基礎(chǔ)上同時(shí)實(shí)現(xiàn)了數(shù)據(jù)的管理,從函數(shù)管理進(jìn)一步升級(jí)成為需求管理,實(shí)現(xiàn)多語言服務(wù)框架支持的基礎(chǔ)上,成本進(jìn)一步壓縮&效率提升。
GEEK TALK
03
計(jì)算系統(tǒng)核心設(shè)計(jì)核心思路
&核心實(shí)現(xiàn)
下面詳細(xì)闡述各個(gè)階段的詳細(xì)特點(diǎn)以及核心實(shí)現(xiàn)。
3.1 原始離線處理系統(tǒng)
這套架構(gòu)應(yīng)用于2018以前,當(dāng)時(shí)垂類的發(fā)展整體屬于起步階段。該階段業(yè)務(wù)主要的需求就是可以將原始的業(yè)務(wù)數(shù)據(jù)直接上線。架構(gòu)的主要精力聚焦于通用業(yè)務(wù)能力的建設(shè)。隨著業(yè)務(wù)的逐步深耕,發(fā)現(xiàn)有少量的業(yè)務(wù)慢慢演化出來自定義加工的需求。
根據(jù)當(dāng)時(shí)的業(yè)務(wù)需求,最終從原有的數(shù)據(jù)加工模塊中衍生出業(yè)務(wù)數(shù)據(jù)加工系統(tǒng)。當(dāng)前階段的數(shù)據(jù)加工處理方式是使用統(tǒng)一Handler處理方式,當(dāng)然這個(gè)處理并非是必選項(xiàng),多數(shù)業(yè)務(wù)仍然不需要自定義加工處理。各業(yè)務(wù)之間也完全沒有數(shù)據(jù)隔離,這種架構(gòu)最核心的意義就是從無到有提供業(yè)務(wù)的自定義加工能力。如下圖所示,此時(shí)計(jì)算系統(tǒng)只包含計(jì)算引擎部分,其他系統(tǒng)完全沒有建設(shè)。下面會(huì)對(duì)該系統(tǒng)的部分細(xì)節(jié)進(jìn)行詳細(xì)說明。
3.1.1 業(yè)務(wù)特點(diǎn)
這個(gè)時(shí)期的業(yè)務(wù)特點(diǎn)主要有兩個(gè):
- 多數(shù)業(yè)務(wù),核心訴求最主要的是通用能力的建設(shè)。
- 個(gè)別業(yè)務(wù),有少量簡單的自定義加工處理的需求。
所以這個(gè)時(shí)間點(diǎn)的核心主要是為了解決業(yè)務(wù)加工入口的問題。
3.1.2 核心設(shè)計(jì)
初版本的離線架構(gòu)模塊非常簡單,如下圖所示藍(lán)色部分。隨著業(yè)務(wù)發(fā)展,為了滿足業(yè)務(wù)自定義加工的需求,引入紅色數(shù)據(jù)通路,其中統(tǒng)一數(shù)據(jù)加工模塊就是主要處理業(yè)務(wù)自定義加工邏輯。
如上圖所示,灰色部分是業(yè)務(wù)外層接入的數(shù)據(jù)系統(tǒng),最開始的時(shí)候只有XML、POST 和 數(shù)據(jù)隊(duì)列的這種模式。藍(lán)色部分就是業(yè)務(wù)沒有自定義時(shí)候原始的數(shù)據(jù)框架代碼。紅色部分就是為了針對(duì)業(yè)務(wù)自定義需求引入的框架模塊:
用戶數(shù)據(jù)代理:主要是為了適配業(yè)務(wù)數(shù)據(jù)接入方式,數(shù)據(jù)的協(xié)議打平,主要是不同用戶協(xié)議的RPC做建庫層的數(shù)據(jù)轉(zhuǎn)化。
用戶通用需求:主要是為用戶共性需求做統(tǒng)一處理,會(huì)根據(jù)不同業(yè)務(wù)的不同配置做功能處理:比如業(yè)務(wù)圖片視頻的轉(zhuǎn)化處理,業(yè)務(wù)用戶版本管理處理以及用戶的核心機(jī)制等。
統(tǒng)一數(shù)據(jù)加工模塊:主要是為了統(tǒng)一用戶數(shù)據(jù)的加工處理,主要是給所有接入的業(yè)務(wù)的數(shù)據(jù)提供了一個(gè)可以數(shù)據(jù)加工的入口。
3.2 業(yè)務(wù)處理架構(gòu)
如上文所述3.1架構(gòu)核心價(jià)值是自定義加工能力的從0到1的建設(shè),然而隨著業(yè)務(wù)的快速發(fā)展,越來越多的業(yè)務(wù)需要自定義加工能力。業(yè)務(wù)自定義加工的需求從原來個(gè)位數(shù)迅速膨脹了10倍。因此,為了滿足業(yè)務(wù)在自定義開發(fā)上易用性和穩(wěn)定性的訴求,將原來3.1的中心化的處理模式升級(jí)成為服務(wù)框架的模式。總體上來說,當(dāng)前階段的計(jì)算系統(tǒng)建設(shè)已經(jīng)基本具備了服務(wù)層和業(yè)務(wù)層兩層:
業(yè)務(wù)層:業(yè)務(wù)通過平臺(tái)已經(jīng)基本上可以實(shí)現(xiàn),基礎(chǔ)的服務(wù)管理。
服務(wù)層:對(duì)計(jì)算引擎進(jìn)行重構(gòu),讓新的服務(wù)框架支持業(yè)務(wù)的高效開發(fā)。
下面會(huì)對(duì)該系統(tǒng)的部分細(xì)節(jié)進(jìn)行詳細(xì)說明。
3.2.1 業(yè)務(wù)特點(diǎn)
由于3.1中上一代系統(tǒng)數(shù)十個(gè)業(yè)務(wù)自定義需求統(tǒng)一在同一個(gè)模塊里面開發(fā)&統(tǒng)一線上運(yùn)行,遇到了主要如下幾方面問題:
效率:業(yè)務(wù)在相同的模塊里面開發(fā),導(dǎo)致業(yè)務(wù)開發(fā)上線的過程中經(jīng)常遇到?jīng)_突,以及上線排隊(duì)的問題,導(dǎo)致整體生效周期比較長。
穩(wěn)定性:由于這種業(yè)務(wù)流量混合的模式隔離性比較差,導(dǎo)致單個(gè)業(yè)務(wù)出問題,經(jīng)常會(huì)影響所有的業(yè)務(wù)。
因此,架構(gòu)構(gòu)建出完善的服務(wù)框架,業(yè)務(wù)可以基于服務(wù)框架構(gòu)建自己的業(yè)務(wù)代碼,從效率和穩(wěn)定性兩個(gè)方面解決上述問題:
效率:服務(wù)開發(fā)上線的過程是完全隔離的,業(yè)務(wù)在開發(fā)上線的過程中完全沒有業(yè)務(wù)阻塞,整體服務(wù)上線周期從天級(jí)縮短到小時(shí)級(jí)別。
穩(wěn)定性:由于每個(gè)業(yè)務(wù)服務(wù)執(zhí)行邏輯都有完全獨(dú)立的App,導(dǎo)致業(yè)務(wù)的穩(wěn)定性大大提升,不會(huì)存在業(yè)務(wù)之間的互相影響。
3.2.3 核心設(shè)計(jì)
業(yè)務(wù)處理框架:建設(shè)一個(gè)數(shù)據(jù)處理框架,業(yè)務(wù)可以基于這個(gè)框架來實(shí)現(xiàn)自己的業(yè)務(wù)處理功能。
任務(wù)平臺(tái):每個(gè)任務(wù)注冊(cè)、升級(jí)、管理都可以通過任務(wù)平臺(tái)來進(jìn)行管理。
統(tǒng)一網(wǎng)關(guān):所有數(shù)據(jù)的統(tǒng)一入口,統(tǒng)一接收上游數(shù)據(jù),并且做數(shù)據(jù)的轉(zhuǎn)發(fā)和分發(fā)。
業(yè)務(wù)APP:每個(gè)業(yè)務(wù)都有自己獨(dú)立服務(wù)的app,每個(gè)業(yè)務(wù)開發(fā)是基于框架的獨(dú)立分支開發(fā),上線是每個(gè)業(yè)務(wù)單獨(dú)上線,業(yè)務(wù)處理的服務(wù)流量也都是完全隔離的。
3.3 Serverless架構(gòu)
如上文中3.2表述已經(jīng)解決系統(tǒng)隔離性的問題,業(yè)務(wù)快速發(fā)展從最開始的幾十個(gè),發(fā)展到上百個(gè)業(yè)務(wù)應(yīng)用。當(dāng)業(yè)務(wù)發(fā)展到井噴狀態(tài)后,服務(wù)框架的形式已經(jīng)完全不能滿足業(yè)務(wù)的開發(fā)需求。
Serverless架構(gòu)如下圖所示,此時(shí)計(jì)算系統(tǒng)整體版圖已經(jīng)相對(duì)完善,相比上一代計(jì)算架構(gòu),不僅僅業(yè)務(wù)層包含的全流程的優(yōu)化,提供了完整的工具功能;服務(wù)層充分考慮的架構(gòu)的設(shè)計(jì)和復(fù)用,同時(shí)增加控制層增加智能調(diào)度的功能針對(duì)系統(tǒng)流量進(jìn)行資源的動(dòng)態(tài)調(diào)度。
下面會(huì)對(duì)該系統(tǒng)的部分細(xì)節(jié)進(jìn)行詳細(xì)說明。
3.3.1 業(yè)務(wù)特點(diǎn)&解決問題
業(yè)務(wù)學(xué)習(xí)成本:大量的新業(yè)務(wù)接入需要進(jìn)行開發(fā),導(dǎo)致框架本身學(xué)習(xí)成本需要幾天的時(shí)間,新業(yè)務(wù)的接入和開發(fā)的時(shí)間基本上都在周級(jí)別。
資源如何節(jié)省:大量的業(yè)務(wù)也帶來app的高速膨脹,原來接入的數(shù)百臺(tái)機(jī)器已經(jīng)用滿,到了資源瓶頸,當(dāng)前的資源量無法支持業(yè)務(wù)的快速膨脹。
3.3.3 核心設(shè)計(jì)
應(yīng)用層:針對(duì)于基礎(chǔ)服務(wù)架構(gòu),上面給業(yè)務(wù)開放的各種云服務(wù),從業(yè)務(wù)的 接入、開發(fā)到后面的調(diào)試、測(cè)試,到服務(wù)上線后的監(jiān)控。
服務(wù)層:這部分是整體架構(gòu)的基礎(chǔ),應(yīng)用層都是基于這里進(jìn)行開發(fā)的,這部分是整個(gè)系統(tǒng)的基石,屬于整體系統(tǒng)的核心框架。
調(diào)度層:通過根據(jù)流量形式的擴(kuò)縮容,保證后續(xù)服務(wù)可以自動(dòng)化的進(jìn)行服務(wù)操作。
下面重點(diǎn)介紹一下 服務(wù)層的主要內(nèi)容,對(duì)業(yè)務(wù)來說主要包含兩部分:
極致抽象的業(yè)務(wù)框架:是核心框架基礎(chǔ)中的基礎(chǔ),提供新的開發(fā)范式同時(shí),為后續(xù)智能調(diào)度奠定良好基礎(chǔ)。
高度復(fù)用的基礎(chǔ)服務(wù):強(qiáng)大豐富的后端服務(wù)能力封裝,支持業(yè)務(wù)低成本復(fù)用,降低開發(fā)成本同時(shí)提升穩(wěn)定性。同時(shí)系統(tǒng)還提供強(qiáng)大的編排能力,低成本支持業(yè)務(wù)從簡單到復(fù)雜的發(fā)展。
極致抽象的業(yè)務(wù)框架
業(yè)務(wù)框架作為FaaS層和業(yè)務(wù)代碼的載體,是整個(gè)業(yè)務(wù)邏輯的代碼框架。框架本身維護(hù)數(shù)據(jù)流語義,面向有向無環(huán)圖(DAG)的數(shù)據(jù)流,調(diào)用業(yè)務(wù)函數(shù)代碼。業(yè)務(wù)框架是面向有向無環(huán)圖的數(shù)據(jù)流實(shí)時(shí)計(jì)算,基于公司基礎(chǔ)的數(shù)據(jù)流框架支持完備的流式計(jì)算語義,結(jié)合業(yè)務(wù)場(chǎng)景需要功能構(gòu)建出業(yè)務(wù)框架:
如上圖左邊就是用戶實(shí)際的執(zhí)行代碼,對(duì)于函數(shù)的接口定義:入?yún)⒑头祷刂刀际荄ict類型。業(yè)務(wù)的代碼邏輯直接在函數(shù)中實(shí)現(xiàn),需要變更的數(shù)據(jù),如上圖所示業(yè)務(wù)在根目錄下增加了一個(gè)時(shí)間戳字段,然后把更新后的結(jié)果傳遞給下游。
業(yè)務(wù)端使用開發(fā)成本低的腳本語言進(jìn)行開發(fā)(例如Python/ target=_blank class=infotextkey>Python),基礎(chǔ)服務(wù)框架使用C++實(shí)現(xiàn),結(jié)合數(shù)據(jù)壓縮、批處理、數(shù)據(jù)預(yù)分發(fā)等機(jī)制,使得業(yè)務(wù)可以在簡化服務(wù)框架開發(fā)同時(shí)優(yōu)化服務(wù)運(yùn)行性能。通過架構(gòu)層面的優(yōu)化策略來達(dá)到服務(wù)性能和開發(fā)成本的平衡。
高度復(fù)用的基礎(chǔ)服務(wù)
業(yè)務(wù)依賴的后端服務(wù),包括多媒體長留服務(wù),數(shù)據(jù)存儲(chǔ)服務(wù),策略計(jì)算等十項(xiàng)服務(wù)能力,所有的服務(wù)架構(gòu)的支持目標(biāo)都是通過簡單配置、少量代碼的方式進(jìn)行服務(wù)接入。
架構(gòu)通用能力:包括索引處理(倒排、正排、向量索引),數(shù)據(jù)審核(政治敏感數(shù)據(jù)/色情數(shù)據(jù)識(shí)別&過濾),多路分發(fā)、數(shù)據(jù)建庫等能力。
與業(yè)務(wù)聯(lián)合研發(fā)的能力:數(shù)據(jù)的低質(zhì)過濾能力(實(shí)現(xiàn)數(shù)據(jù)清洗/歸一化/數(shù)據(jù)去重/類目拼接),數(shù)據(jù)多元融合,數(shù)據(jù)質(zhì)量打分計(jì)算(質(zhì)量打分/作弊識(shí)別/物料打分)。
基于公司強(qiáng)大基礎(chǔ)能力: 多媒體處理服務(wù)(外鏈轉(zhuǎn)內(nèi)鏈/OCR/水印計(jì)算/重復(fù)圖計(jì)算/主體識(shí)別/視頻轉(zhuǎn)儲(chǔ)等),自然語言處理服務(wù),數(shù)據(jù)沉淀服務(wù)。
支持的基礎(chǔ)服務(wù)(BaaS服務(wù))主要是兩個(gè)特點(diǎn): 簡單穩(wěn)定 & 充分集成公司內(nèi)其他優(yōu)質(zhì)能力。用戶通過SDK調(diào)用、算子復(fù)用和數(shù)據(jù)流復(fù)用等方式直接進(jìn)行能力復(fù)用,完全不需要進(jìn)行服務(wù)的部署和管理,服務(wù)易用性、穩(wěn)定性由搜索中臺(tái)來處理。使用任何服務(wù)后端都可以收口在一個(gè)地方,避免業(yè)務(wù)頻繁跟多個(gè)服務(wù)團(tuán)隊(duì)進(jìn)行交流處理,極大降低業(yè)務(wù)使用成本。業(yè)務(wù)最開始接入通常只需要簡單的少數(shù)功能(例如,修改部分字段的信息),多數(shù)業(yè)務(wù)直接用我們提供的平臺(tái)化的開發(fā)模板即可完成開發(fā)。但是隨著業(yè)務(wù)的逐步深耕,業(yè)務(wù)逐步使用,業(yè)務(wù)會(huì)向復(fù)雜逐步過渡,例如搜索中臺(tái)某業(yè)務(wù)通過復(fù)用數(shù)十種能力的組合使用,建設(shè)出具有深度定制的數(shù)據(jù)系統(tǒng)。
3.4 數(shù)據(jù)智能架構(gòu)
如上文中3.3 表述已經(jīng)很大程度上解決業(yè)務(wù)接入效率的問題并且在資源的使用效率上實(shí)現(xiàn)根據(jù)流量的擴(kuò)縮容實(shí)現(xiàn)的資源極大程度的節(jié)省,業(yè)務(wù)的app的數(shù)量已經(jīng)發(fā)展到上千個(gè),業(yè)務(wù)對(duì)于效率、成本、服務(wù)質(zhì)量提出來更高的要求。至此已經(jīng)構(gòu)建出,從業(yè)務(wù)層、邏輯層、服務(wù)層、控制層的四層架構(gòu),實(shí)現(xiàn)離線計(jì)算系統(tǒng)從指令式計(jì)算系統(tǒng)到聲明式計(jì)算系統(tǒng)的徹底轉(zhuǎn)變。
3.4.1 業(yè)務(wù)特點(diǎn)
- 效率業(yè)務(wù)的迭代開發(fā)很多都是針對(duì)少數(shù)幾個(gè)字段,但是當(dāng)前業(yè)務(wù)同學(xué)仍然需要了解服務(wù)全拓?fù)洳拍荛_發(fā)。
- 隨著業(yè)務(wù)復(fù)雜深耕業(yè)務(wù)的開發(fā)迭代業(yè)務(wù)開發(fā)者出現(xiàn)多語言開發(fā)情況來提高服務(wù)的開發(fā)和執(zhí)行效率。
- 業(yè)務(wù)如何實(shí)現(xiàn)新類目的快速接入、在不了解全面的情況下快速迭代。
- 計(jì)算引擎執(zhí)行效率更高,用更少的資源計(jì)算跑更多的服務(wù)資源。
- 業(yè)務(wù)問題能不能快速定位&發(fā)現(xiàn)以及問題的自動(dòng)處理。
3.4.2 核心思路
從設(shè)計(jì)思路來看當(dāng)前系統(tǒng)架構(gòu)是上一代架構(gòu)的拓展:
- 數(shù)據(jù)管理:出了原始服務(wù)管理外,引入數(shù)據(jù)全面管理,為列計(jì)算奠定基礎(chǔ)。
- 編排能力:將原來業(yè)務(wù)手動(dòng)編排的函數(shù)能力擴(kuò)展成為需求聲明式自動(dòng)編排的能力。
- 服務(wù)處理:極致高效的服務(wù)處理能力,支持多種不同業(yè)務(wù)開發(fā)者的高效開發(fā)效率,將整體的計(jì)算從行計(jì)算轉(zhuǎn)向列計(jì)算,提高整體的計(jì)算復(fù)用。
- 控制能力:將原來自動(dòng)伸縮的能力擴(kuò)展成為智能控制能力,做到問題的自動(dòng)識(shí)別、自動(dòng)分發(fā)、自動(dòng)分析 和 自動(dòng)處理。
整體架構(gòu)的設(shè)計(jì)核心理念大致是多層抽象、分層復(fù)用。
3.4.3 核心設(shè)計(jì)
當(dāng)前階段的核心設(shè)計(jì)已經(jīng)呈現(xiàn)出完整的四層架構(gòu)的抽象能力:
應(yīng)用層:業(yè)務(wù)直接可見的相關(guān)服務(wù),包括業(yè)務(wù)從開始數(shù)據(jù)接入到服務(wù)運(yùn)行的全周期各階段各種應(yīng)用。
邏輯層:也可以稱之為編排層,負(fù)責(zé)將原始的業(yè)務(wù)需求表達(dá)轉(zhuǎn)化成為線上真實(shí)運(yùn)行的服務(wù), 業(yè)務(wù)通過Codeless 平臺(tái)化選擇勾選自己的功能集合,以及對(duì)應(yīng)數(shù)據(jù)映射關(guān)系進(jìn)行提交,將用戶提供的功能 & 數(shù)據(jù)的綁定關(guān)系轉(zhuǎn)化為業(yè)務(wù)的自定義的功能 以及映射關(guān)系。
服務(wù)層:計(jì)算系統(tǒng)的核心,業(yè)務(wù)實(shí)際計(jì)算運(yùn)行在這層,主要包含計(jì)算引擎 和服務(wù)架構(gòu)兩部分。向上承接邏輯層的編排結(jié)果運(yùn)行服務(wù),向下提供基礎(chǔ)信號(hào)作為控制層的輸入。
控制層:包含智能調(diào)度和智能控制兩部分:智能控制主要是通過自動(dòng)接受業(yè)務(wù)指標(biāo)數(shù)據(jù)進(jìn)行智能控制保證服務(wù)穩(wěn)定,而智能調(diào)度是除了根據(jù)數(shù)據(jù)流量進(jìn)行進(jìn)行自動(dòng)伸縮以外還可以根據(jù)業(yè)務(wù)服務(wù)關(guān)系進(jìn)行流量復(fù)用,減少業(yè)務(wù)的重復(fù)計(jì)算。
下面我們針對(duì)部分核心系統(tǒng)(如上圖藍(lán)色部分)的設(shè)計(jì)作展開說明。
需求表達(dá)邏輯
需求邏輯的表達(dá)的核心就是如何把用戶原始的功能需求轉(zhuǎn)化成真是線上服務(wù)的算子、配置、關(guān)系的表達(dá)。用戶最原始的輸入包含兩部分:
業(yè)務(wù)數(shù)據(jù):業(yè)務(wù)數(shù)據(jù)需要功能的最小單位進(jìn)行切割,后續(xù)算子進(jìn)行配置轉(zhuǎn)化以及服務(wù)綁定的列式計(jì)算。這里說的有點(diǎn)繞口,其實(shí)本質(zhì)上就是把業(yè)務(wù)數(shù)據(jù)的原始Proto或者數(shù)據(jù)Schema注冊(cè)一下就可以。
功能集合:功能集合既可以用戶直接使用的系統(tǒng)提供的默認(rèn)模版的功能集合 也可以是用戶通過平臺(tái)自定義的集合,值的注意的是每個(gè)功能都都有其指定的傳入?yún)?shù),比如圖片計(jì)算,需要傳入圖片URL,向量計(jì)算需要傳入原始數(shù)據(jù) & 向量參數(shù)等等。功能完成后也會(huì)有對(duì)應(yīng)的輸出結(jié)果業(yè)務(wù)可以指定。
獲取完成用戶的原始輸入后,架構(gòu)通過兩層邏輯映射的方式,將原始用戶需求轉(zhuǎn)化成為線上服務(wù)部署信息:
需求表達(dá)服務(wù):用戶的原始需求轉(zhuǎn)化為功能模版的組合。這個(gè)階段會(huì)根據(jù)用戶配置,將原始算子和數(shù)據(jù)進(jìn)行綁定,原始用戶抽象的需求實(shí)例化成帶數(shù)據(jù)的算子集合。
需求編排服務(wù):通過業(yè)務(wù)算子的本身的依賴關(guān)系和數(shù)據(jù)依賴的血緣關(guān)系進(jìn)行表達(dá)組合,將帶數(shù)據(jù)的算子構(gòu)建出N個(gè)有向無環(huán)圖。
整體需求表達(dá)都可以通過Codeless方式表達(dá),通過描述功能集合??數(shù)據(jù)集合描述方式,加之兩層邏輯映射的轉(zhuǎn)化,這樣就可以將原始用戶聲明式需求直接轉(zhuǎn)化線上服務(wù)關(guān)系和系統(tǒng)配置,并且服務(wù)的算子的拓?fù)潢P(guān)系完全可以通過業(yè)務(wù)的數(shù)據(jù)關(guān)系表達(dá)自動(dòng)化推導(dǎo)出來, 實(shí)現(xiàn)了95%以上的功能可以完全自動(dòng)化配置實(shí)現(xiàn),當(dāng)然有個(gè)別服務(wù)無法低成本轉(zhuǎn)化表達(dá)的,也提供了人工接口。
計(jì)算引擎實(shí)現(xiàn)
計(jì)算引擎層的核心組件大致分成兩部分,圖計(jì)算引擎 & 多語言算子的執(zhí)行引擎 。
圖計(jì)算引擎:主要控制的業(yè)務(wù)拓?fù)涞谋磉_(dá)關(guān)系,通過有向無環(huán)圖來表達(dá)。
算子執(zhí)行引擎:主要控制業(yè)務(wù)真實(shí)業(yè)務(wù)函數(shù)的執(zhí)行,不同語言有不同的函數(shù)實(shí)現(xiàn),例如Python、GoLang、C/C++都有自己的執(zhí)行引擎。
下面針對(duì)兩部分進(jìn)行仔細(xì)說明
線程管理:每個(gè)業(yè)務(wù)算子默認(rèn)都是多線程的分發(fā)模式(如果業(yè)務(wù)算子只支持單線程,可以把線程數(shù)設(shè)置成1)。
分發(fā)模式:數(shù)據(jù)消費(fèi)分發(fā)模式默認(rèn)是輪詢分發(fā),固定KEY分發(fā)(實(shí)現(xiàn)保序)以及按消費(fèi)能力分發(fā)。
數(shù)據(jù)壓縮:這個(gè)默認(rèn)支持常見數(shù)據(jù)壓縮方法,是可選的吞吐優(yōu)化手段,支持LZ4、Gzip、Snappy等常見壓縮算法。
- 圖計(jì)算引擎實(shí)現(xiàn):實(shí)現(xiàn)的核心功能就是實(shí)現(xiàn)支持表達(dá)有向無環(huán)圖的框架,使用C++實(shí)現(xiàn)的,圖下圖部分中,藍(lán)色部分就是有向無環(huán)圖的框架實(shí)現(xiàn),當(dāng)然我們這個(gè)框架的底層實(shí)現(xiàn)支持了多種數(shù)據(jù)的表達(dá):
-
本地隊(duì)列表達(dá):如圖左下角部分表達(dá)的就是一個(gè)簡單的拓?fù)浔磉_(dá),拓?fù)潢P(guān)系是通過本地的無鎖隊(duì)列進(jìn)行串聯(lián)的,每個(gè)隊(duì)列下面掛載一個(gè)業(yè)務(wù)算子,業(yè)務(wù)算子處理完成數(shù)據(jù)后,算子拓?fù)渑渲霉芾矸职l(fā)到下游的本地隊(duì)列中,如果是最后一個(gè)算子,數(shù)據(jù)結(jié)果全部處理完成后輸出到遠(yuǎn)程隊(duì)列Producer中。左側(cè)這邊是框架內(nèi)部的通用功能:
-
遠(yuǎn)程隊(duì)列表達(dá):每個(gè)藍(lán)色大框表示一個(gè)具體實(shí)例,實(shí)例之間使用遠(yuǎn)程隊(duì)列交互,如果每個(gè)實(shí)例里面只有一個(gè)業(yè)務(wù)算子,這種的交互方式類似于遠(yuǎn)程隊(duì)列的表達(dá)方式。
-
混合方式表達(dá):更多使用方式是混合使用,一個(gè)巨型拓?fù)鋾?huì)拆分成多個(gè)子拓?fù)洌總€(gè)子拓?fù)涫褂帽镜仃?duì)列的方式進(jìn)行表達(dá),而子拓?fù)渲g使用遠(yuǎn)程隊(duì)列的方式進(jìn)行表達(dá)。
-
多語言引擎執(zhí)行層:語言執(zhí)行層整體框架整體根據(jù)不同的語言有不同實(shí)現(xiàn)模式,大體上分成三部分:編譯型、解釋型、原生C++。
-
解釋型:最典型的就是Python實(shí)現(xiàn)方式,這種方式也是過去同學(xué)最喜歡用的開發(fā)語言之一。圖上圖最上面,左邊灰色部分是C++開發(fā)的部分,最右邊黃色部分是業(yè)務(wù)代碼,中間這部分就是C++轉(zhuǎn)Python的交互引擎調(diào)用。這種方式的本質(zhì)就C++的開發(fā)引擎使用PyBind實(shí)現(xiàn)指定接口服務(wù)解釋器,根據(jù)指定的數(shù)據(jù)序列化和反序列化方式進(jìn)行操作,在函數(shù)調(diào)用時(shí)再實(shí)時(shí)轉(zhuǎn)化為python的Dict。
編譯型:典型是Golang的使用方式。與Python的實(shí)現(xiàn)類似,左邊灰色部分是C++開發(fā)的部分,最右邊黃色部分是Golang業(yè)務(wù)代碼,中間是C++轉(zhuǎn)Golang的交互引擎。Golang的實(shí)現(xiàn)相比Python的方式有點(diǎn)復(fù)雜,本質(zhì)是通過原生CGO作為用戶接口,為了統(tǒng)一用戶接口層,其實(shí)分成兩部分:左半部分是直接跟C++交互,直接用C++實(shí)現(xiàn)負(fù)責(zé)把原生C++轉(zhuǎn)化為基礎(chǔ)的C類型的函數(shù)指針進(jìn)行調(diào)用。右半部分使用Golang實(shí)現(xiàn)負(fù)責(zé)把原生序列化好的函數(shù)反序列化成業(yè)務(wù)結(jié)構(gòu)體,然后再進(jìn)行真正調(diào)用。
原生C++:這里很多人可能覺得奇怪,C++不是也是編譯型的么,已經(jīng)有編譯型的實(shí)現(xiàn)模式何必畫蛇添足,增加這么一種實(shí)現(xiàn)模式,其實(shí)本質(zhì)不然,golang雖然是編譯型語言,底層框架的實(shí)現(xiàn)由于盡量考慮通用性,數(shù)據(jù)傳遞的過程中勢(shì)必需要進(jìn)行序列化和反序列操作,而在原生的C++的實(shí)現(xiàn)過程中我們?cè)趯?shí)現(xiàn)的過程完全摒棄所有的序列化和反序列操作,數(shù)據(jù)在本地隊(duì)列中的傳遞完全是業(yè)務(wù)的數(shù)據(jù)指針(而非序列化數(shù)據(jù)),而每個(gè)業(yè)務(wù)算子在處理數(shù)據(jù)過程中,直接根據(jù)原始的數(shù)據(jù)指針通過反射機(jī)制(實(shí)現(xiàn)方式有很多最簡單的 map)可以直接獲取對(duì)應(yīng)列的數(shù)據(jù)項(xiàng),整個(gè)過程無鎖的超高效率。這里的核心優(yōu)化思路數(shù)據(jù)鏈?zhǔn)教幚?/strong>過程。拉鏈上的每個(gè)算子,都共享同一個(gè)輸入和輸出。每個(gè)算子,其實(shí)就是一個(gè)接口相同的函數(shù),這樣就可以隨意地調(diào)整函數(shù)指針的組合,形成不同的處理鏈。比如:一個(gè)請(qǐng)求走 A 模型排序,一個(gè)請(qǐng)求要走 B 模型排序,他們可以共享前序的算子,只在最后一個(gè)算子有所不同。在鏈?zhǔn)教幚砘A(chǔ)上,算子也可以是繼承同一基類接口的派生類,或者 lambda 表達(dá)式。結(jié)合工廠模式等一些編程技巧,處理鏈的調(diào)整可以配置化、動(dòng)態(tài)化、腳本化。實(shí)測(cè)執(zhí)行業(yè)務(wù)單算子普通的純數(shù)據(jù)項(xiàng)帶分支的多節(jié)點(diǎn)的拓?fù)溆?jì)算單機(jī)(單線程/算子)可以達(dá)到數(shù)十萬的處理能力。
通過新計(jì)算引擎的實(shí)現(xiàn)從使用上完全兼容上一代計(jì)算系統(tǒng)的使用方式,將不常使用的功能做精簡,同時(shí)優(yōu)化復(fù)雜拓?fù)鋱?zhí)行方式,通過架構(gòu)層也業(yè)務(wù)層解耦,支持多語言高效執(zhí)行方式,對(duì)于老業(yè)務(wù)平遷的數(shù)據(jù)框架平均計(jì)算效率提高5~10倍,同時(shí)業(yè)務(wù)由于針對(duì)性建設(shè)業(yè)務(wù)框架業(yè)務(wù)開發(fā)效率進(jìn)一步提升。
智能控制實(shí)現(xiàn)
自動(dòng)化問題分析引擎是整個(gè)智能控制系統(tǒng)的大腦。它上游接收觀測(cè)提供的原始數(shù)據(jù),進(jìn)行自動(dòng)的分析決策后,通過系統(tǒng)提供的自愈能力處理。自動(dòng)化問題分析引擎的核心思路: 只要?dú)v史上出現(xiàn)過的問題,RD同學(xué)能找到問題和解決方案,就可以轉(zhuǎn)化為系統(tǒng)規(guī)則和后置函數(shù)梳理。那當(dāng)下一次遇到問題則無需人工干預(yù)。規(guī)則引擎的核心分析過程是2段式的:
階段1: 傳統(tǒng)配置化的規(guī)則引擎的配置(上圖中右上角黃色部分),配置多個(gè)采集指標(biāo)項(xiàng)的邏輯關(guān)系(與或交非), 這里主要是針對(duì)問題的基礎(chǔ)分析功能,判定規(guī)則是否觸發(fā)。
階段2: 基于這個(gè)基礎(chǔ)分析的結(jié)果,進(jìn)行后置Function的執(zhí)行分析,這個(gè)主要是針對(duì)復(fù)雜問題的分析補(bǔ)充, 最終執(zhí)行引擎根據(jù)這個(gè)返回結(jié)果進(jìn)行函數(shù)執(zhí)行。
下面針對(duì)問題分析引擎的執(zhí)行結(jié)果如下:
- 前提: 開發(fā)者需要配置好處理邏輯規(guī)則(以及規(guī)則依賴的數(shù)據(jù)項(xiàng),必填) & 回調(diào)函數(shù)(選填)。
- 數(shù)據(jù)解析器: 數(shù)據(jù)解析器主要承擔(dān)的數(shù)據(jù)的原始抽取的工作,一共分成如下3步:
a.配置解析: 邏輯執(zhí)行根據(jù)開發(fā)者配置的數(shù)據(jù)信息解析;
b.數(shù)據(jù)抽取: 根據(jù)解析出來的配置通過數(shù)據(jù)接口進(jìn)行獲取,可以從統(tǒng)一接口根據(jù)配置的信息從不同的介質(zhì)充抽取所需求的信息;
c.數(shù)據(jù)歸一化: 將不同介質(zhì)的原始數(shù)據(jù)歸一化成為統(tǒng)一的數(shù)據(jù)格式供規(guī)則管理器使用。
- 規(guī)則管理器: 規(guī)則管理器主要承擔(dān)核心的邏輯分析工作,一共分成如下幾步:
a.規(guī)則解析: 根據(jù)開發(fā)者配置的規(guī)則邏輯,將原始配置信息,解釋成原始的規(guī)則樹。
b.執(zhí)行計(jì)算: 根據(jù)數(shù)據(jù)解析器提供的數(shù)據(jù)結(jié)果和配置的函數(shù)規(guī)則分別執(zhí)行計(jì)算。執(zhí)行計(jì)算過程中最重要的就是基礎(chǔ)分析器,整體提供了5大基礎(chǔ)能力,數(shù)十種常見的邏輯計(jì)算來輔助規(guī)則配置。
c.規(guī)則邏輯運(yùn)算: 根據(jù)上層解析出來的規(guī)則樹 和 每個(gè)數(shù)據(jù)項(xiàng)執(zhí)行完成的計(jì)算結(jié)果進(jìn)行邏輯運(yùn)算,并根據(jù)執(zhí)行的結(jié)果確定是否進(jìn)行高級(jí)數(shù)據(jù)分析器,如果判斷結(jié)果為真則根據(jù)所配置的后置函數(shù)進(jìn)行處理。
- 高級(jí)數(shù)據(jù)分析器: 如圖所示有兩種模式,對(duì)于簡單基礎(chǔ)分析可以判斷結(jié)果的,直接給默認(rèn)的處理函數(shù)進(jìn)行數(shù)據(jù)拓傳;對(duì)于簡單邏輯規(guī)則無法準(zhǔn)確表達(dá)的,開發(fā)者可以自定義后置分析函數(shù), 函數(shù)會(huì)將原始數(shù)據(jù)和基礎(chǔ)計(jì)算的計(jì)算結(jié)果作為參數(shù)傳出來,開發(fā)者只需要通過處理后的數(shù)據(jù)描述清楚分析邏輯即可。
- 動(dòng)作執(zhí)行器: 就是這個(gè)分析器的真正的執(zhí)行引擎,根據(jù)規(guī)則運(yùn)算的結(jié)果中包含的參數(shù)進(jìn)行動(dòng)態(tài)調(diào)整。
通過智能控制系統(tǒng)的建設(shè),月級(jí)別分析處理上萬的異常問題,自動(dòng)恢復(fù)的比例占總數(shù)的95%以上,絕大多數(shù)的問題幾分鐘內(nèi)完成自動(dòng)恢復(fù), 核心故障同比減少60% (由于預(yù)處理防止普通問題惡化成嚴(yán)重問題)。
GEEK TALK
04
結(jié)論以及展望
本文全篇以離線計(jì)算系統(tǒng)的發(fā)展為主線,貫穿全文講解遇到的問題以及解決方案。尤其是當(dāng)前新一代架構(gòu)核心就是以數(shù)據(jù)+功能為核心的聲明式的設(shè)計(jì),配合高效計(jì)算引擎、配合智能化的設(shè)計(jì),把整體的離線計(jì)算系統(tǒng)的高度做了進(jìn)一步提升。設(shè)計(jì)中其實(shí)還是雖然解決了過去的很多問題,但是仍然有不完善的地方,當(dāng)然當(dāng)前的效果還遠(yuǎn)沒有達(dá)到最終的理想狀態(tài),部分系統(tǒng)功能有待持續(xù)性的打磨升級(jí)。