一、數據服務中臺建設背景
1、數據獲取過程中的痛點
在分享數據服務中臺建設之前,想從兩個案例開始,從中可以感受傳統數據獲取過程中的一些痛點。
案例一:數據需求方A,需要獲取每日up主的收入進行數據分析。首先,A需要向數據產品提取數需求,數據產品會與其溝通指標口徑,如up主的范圍,收入定義,還有沒有其他要下鉆的維度等等;口徑定義清楚之后,數據產品把需求提給對應的數據分析師,分析師拿到需求和口徑定義后,找數據源、手工SQL邏輯,從而拉取到對應的數據,最后提供給A。
案例二:數據需求方B,需要獲取up主的收入數據,用于線上系統的展示。同樣,也是需要提需求給數據產品,數據產品也是需要與其一起定義指標口徑,確定好口徑之后把需求提給數倉同學。數倉同學拿到需求及口徑定義之后進行手工建模;建模完成后,與對應的業務系統開發進行溝通,因為對于數據量大小、性能要求、取數方式等不同,數據的出倉選型方案大不相同,所以需要與數據系統開發進行多次有效的溝通才能夠確定存儲選型。數據出倉完成后,系統開發需要手工編寫API,經過聯調測試發布到線上。
從這兩個案例中,可以總結出兩個問題:一、成本高,主要體現消費鏈路長、溝通成本高,不同需求可能會并造成模型重復建設;二、治理難,數據鏈路及血緣不清晰,上游數據發生了變更下游無法評估影響,另外,不同鏈路口徑難以保障。
上面兩個案例,也是煙囪式開發的典型場景。本身煙囪式開發會有比較多的弊端。弊端一:重復建設,包括重復計算、重復存儲,造成資源浪費,同時功能上的重復建設也會造成人力資源浪費。弊端二:交付效率低,不同的系統、不同的開發同學對接不同的數據源,數據服務質量不可控,整個對接的標準也不夠統一。
2、一站式數據服務中臺建設
基于上述痛點,經過多次沉淀與總結,最終對數據服務中臺有了一個清洗的定位,即能夠一站式地完成數據的統一定義、統一生產和統一消費。
- 統一定義 即:通過建立數據標準及指標體系,統一業務對數據的認知與理解,實現數據的標準管理
- 統一生產 即:通過自動化、半自動化的方法,統一數據的加工生產過程,讓數據的血緣關系更加清晰,提升數據生產的效率,避免數據重復建設。
- 統一消費 即:通過建立通用的數據服務網關,實現數據查詢出口統一、保障公司通用數據產品指標數據準確性與一致性。
二、數據服務中臺框架
下圖展示了B站數據服務中臺的整體框架。可以看到整個中臺是架構于數倉之上的,自下而上分為多個層次,包括數據構建層、數據查詢層、服務接口層、服務網關,以及基于整個服務體系構建的產品體系,包括指標管理、模型管理、自助分析等等。
1、服務框架
中臺中,我們把用戶定義為兩大類角色,一類是數據生產者,另一類是消費者。數據構建層面向數據生產者,它的核心能力包括模型的定義、模型加速以及API的構建。
數據構建層:在維度建模思想中,數倉一般是分層分主題建設,可以快速地滿足不同的業務場景的數據分析需求。那么在數據消費過程中,就需要多表關聯形成分析視圖進行數據分析。在平臺上可以快速地通過自動化、半自動化方式構建出表與表之間的關系,生成一個邏輯模型,這個過程是數據模型的邏輯構建。我們知道,數倉中數據一般存儲于冷引擎,對于線上系統的使用會有比較高的數據延遲,不具有可用性,那么平臺上也實現了模型的自動的加速過程,讓數據從冷引擎加速到熱引擎,提升數據消費效率。構建層另外一塊能力是API構建。API構建,主要是定義API 的請求參數、返回參數、數據源及數據的計算方式等等。單個的 API 就構成了一個標準的數據單位,經測試聯調完成之后,即可發布到 API 的市場,供不同業務申請使用。
數據查詢層:通過接口獲取用戶的請求參數,查詢層經過解析、調度、翻譯及計算后返回數據結果。查詢層主要提供兩種計算能力,原子計算及二次計算(復合計算)。原子計算主要處理的是格式相對單一,指標維度統一,引擎固定的場景,如些正查、反查、范圍查等等。二次計算是在原子計算的基礎上,采用一定的編排算法,去對于結果集進行二次加工。
服務接口層:接口形式分為同步接口和異步接口。請求方式包括DSL接口、模板接口、公共接口以及UDF接口等。同步接口主要是針對線上應用的一些查詢場景,要求響應速度快,數據結果集相對較小,可直接快速地獲取到數據并應用于系統。異步接口主要是針對于離線分析或者大數據量的文件下載的場景,對于響應速度要求不高,但是對于返回的數據量可能會要求比較大。
服務網關層:是提供給外部訪問我們內部服務的一個統一入口,在數據服務中網關具備的核心能力主要是降級(如數據未就緒降級)、限流(流量峰值控制,保護服務穩定)、鑒權(屏蔽非法流量,保障數據安全)、緩存(熱點數據,提升性能)。
2、核心流程
主要是從兩個核心角色看數據流轉方式:數據開發和業務開發,數據開發即數據生產者,業務開發及數據消費者。數據開發在數據生產過程主要經歷四個步驟:口徑的定義、數據的構建、數據加速和API發布。
第一步:首先對指標進行定義,包括指標名稱、指標領域、指標口徑等信息。
第二步:構建數據模型,在平臺上通過托拉拽的方式構建指標維度模型,以及定義模型中字段與指標維度的關系,計算方法,更新周期等技術口徑。
完成了前兩個步驟,基本實現了數倉開發同學對指標數據的定義與管理工作了。當有數據消費的需求時,則可以根據需求場景在平臺做自動數據加速。
第三步:加速數據模型,根據消費場景,選擇需求所需的指標維度信息,平臺自動實現了目標表的DDL、SQL邏輯的自動生成、調度依賴配置、告警等過程。
第四步:構建API,根據業務數據請求及返回要求,選擇數據源、定義字段的請求、返回參數屬性,主備鏈路信息等,測試完成后即可完成一個API的市場發布。
在數據消費側,當業務有數據需求時,去 API 市場里面找到數據生產者已經生產好的API,申請權限就可以使用了。如果API市場里面沒有所需要的數據,就要走另外一條流程,提一個數據開發的需求給數據開發同學,然后數據開發同學增量地去構建一個數據結果到平臺中去。當業務開發同學申請完這個API的使用權限之后,平臺會授權給他一串密鑰以及資源的標識。業務開發只需對接一次服務網關,即可重復利用。
把數據的生產與消費的開發流程解耦,數倉開發同學不用過多參與業務系統的開發過程,可以更加專注做指標的增量建設;對業務開發屏蔽了數據的加工處理過程,無需深入理解大數據知識,專注開發業務需求即可。
(1)模型構建
平臺中對于模型的構建,支持多種構建方式,包括單例、星型、雪花以及星座模型等等。當模型構建完成后,平臺支持支持的物化加速能力支持也表豐富。從性能及靈活度兩個方便,對使用場景了做了劃分。不同的使用場景,其加速方式及目標引擎有所不同。
明細加速:實現把邏輯模型中的數據從冷引擎到熱引擎的鏡像復制,極大保留了模型的原始數據的業務特性,可以更好的支持對模型中不同的維度及指標做多維分析或者范圍查詢,在熱引擎中,加速數據的查詢效率。
預計算加速:根據數據獲取需求,從邏輯模型中的明細數據進行預計算及處理,直接聚合到所需粒度的數據,并將數據寫入熱引擎中。由于數據已經預計算處理,在數據查詢時極大減少了引擎的計算,查詢效率更高,但也損失了如多維分析及維度下鉆查詢的靈活性。
不同的場景有不同的加速方式及引擎選擇的組合,針對四種類型的場景,推薦的組合如下:
在線場景:預計算+kv存儲,一般應用于C端及B端的數據需求,有著極高的服務性能要求,且線上數據不會快速的變化,靈活度要求低。
準在線場景:預計算 + tidb/mysql,一般應用于活動或者運營系統后臺,服務性能要求不會同線上場景那么高,但同時要求支持范圍查詢,有一定的查詢靈活度;對于數據量較大的查詢場景,可以選擇分布式數據庫 Tidb,其他可以選擇Mysql。
OLAP場景:明細+ ClickHouse/Iceberg,一般應用于數據分析系統,需要對數據進行多維分析,所以需要明細加速。ClickHouse 作為一款OLAP分析引擎,比較適合作為目標引擎,如果考慮到成本因素,也可以使用湖倉一體技術Iceberg,數據無需出倉既可在倉內完成數據的加速,性能雖不及ClickHouse,但也可以達到秒級的響應,特別是在使用成本及查詢語法通用性上更有優勢。
離線場景:離線數據獲取,一般訪問原始hive數據源即可。
(2)API構建
API構建方式有兩種:一種是通過模型構建,這是一種可視化的配置方式,用戶已經明確知道要對某一個模型進行數據服務化,不需要用SQL編碼,通過拖拉拽的方式就可以配置出來。另一種是基于指標維度的構建,指標維度構建是在模型構建的基礎上的一種更高級模式,用戶無需實現指定模型進行構建,可以先配置請求參數及返回參數,系統根據管理的模型元數據信息,按照一定的規則自動篩選出可以服務化的模型列表并給出推薦優先級。
數據查詢:
下面介紹數據查詢的能力,整體分為五個步驟。
步驟1:一個查詢的DSL信息如下圖圖所示。解析的過程是把DSL信息與API配置進行匹配,并得出本次數據請求需要的模型。
步驟2:任務拆分是把解析的結果拆成子任務查詢,解決異構數據源的結果獲取問題。因為一次查詢中可能會從多個模型中獲取,模型也可以在多個引擎或集群中。為保證結果的的準確獲取及查詢效率,我們采用了拆分子任務的方式進行并發數據查詢,子任務的查詢結果經過二次加工處理返回。
步驟3:結果處理器是一個內存計算器,負責把子任務的查詢結果進行拼接、排序、分頁及格式轉換等,返回統一格式的數據結果,讓下游無感知數據的處理過程。
步驟3-1:翻譯模塊是把子任務的查詢信息翻譯成對應引擎可以識別的sql語法。AST是abstract syntax tree的縮寫,也就是抽象語法樹。翻譯模塊區別于引擎對執行SQL進行語法樹解析的過程,而是逆向從構建AST開始,并最終翻譯成SQL的過程。構建AST的算法如下圖所示:
第一層AST從下面的"SELECT"開始,第一層語法樹是構建出本次查詢需要用的有效數據,包括構建模型關系、模型字段的篩選及數據范圍的篩選
第二層AST從上面的"SELECT"開始,第二層語法樹是基于第一層構建的有效數據,進行運算表達式計算,如 sum,count(distnct ..),sum(case when then end),sum()/count() 等其他一些自定義語法表達式。
通過兩次的AST構建,可以完整表達一次原子計算所需的數據獲取邏輯。根據構建的AST,系統會各個引擎的查詢特性及方言,優化查詢語法,提升查詢性能,最終轉化成可被引擎識別的查詢SQL。
步驟3-2:引擎層負責執行各個子任務的查詢SQL,系統適配了目前公司內部多種數據引擎,包括自研KV、TiDB、Mysql、ClickHouse、Iceberg等。除接入不同的引擎連接協議,在不同引擎的連接方式上也做了優化,如:mysql、tidb 由單次短連接改為連接池,減少連接的頻繁創建及銷毀帶來的開銷問題;自研KV多可用區連接,擴大在線服務可用的服務范圍;OLAP引擎如ClickHouse、Iceberg的超時自取消功能,減少服務占用及降低引擎壓力等。
三、數據服務中臺實踐方案
1、全鏈路管控
在數據服務中臺實踐中,最重要的是實現全鏈路管控,讓數據在服務化的過程中做到統一定義、統一生產、統一消費。
統一定義:口徑不易維護的原因之一是管理不統一,散落在各個地方,導致大家沒有統一的視角管理及查看口徑。我們的的解決方案是口徑統一在指標平臺管理,其中把指標的定義及模型的定義解耦。指標定義是對分析對象的業務過程進行描述,計算方法的定義約束,可在數據模型建設之前確定,一般有數據產品角色實施;模型定義是根據數據需求及指標定義進行構建生產,模型中指定了模型字段與指標的關系,決定了模型中哪些字段可以生產哪些指標,一般有數倉開發角色實施。通過把指標定義與模型定義解耦,減少了不同角色間的溝通成本,讓口徑的定義可以延續到數據生產中。
統一出口:口徑不易維護的另外的一個原因是定義與生產分離,出口不可控。我們打通了指標的定義及生產流程:模型的出倉可以自動化完成,出倉過程中的計算邏輯是基于指標平臺中的定義自動生成的,減少了人工的干預,避免定義與生產的不一致;其次,API的取數邏輯非人工定義,也是基于指標定義,自動翻譯取數邏輯及路由計算引擎,避免生產與消費過程中的不一致。通過定義與生產的打通,生產與消費的打通,數據流通過程中完全基于統一的定義,達到了最終的定義與消費的一致性。
全鏈路監控:數據從定義到生產到消費環節,有完整的監控鏈路,以此來確保口徑的持續一致性。指標一致性監控:維度建模的數倉中,同一個指標由于分析思路或者需求場景,最終生產此指標的模型可能是多個,那么就需要保障指標在不同模型間的口徑一致性。通過一致性對比或者閉環公式校驗等手段,發現指標口徑不一致,然后通過口徑變更、模型換綁等治理方法來持續保障指標口徑的一致;出倉一致性監控:出倉過程中數據集成工具保障了實時的一致性,這里需要保障的是,由于歷史數據變更導致的出倉前后數據不一致的問題;服務質量監控:從數據出口監控數據的質量情況,主要包括閾值監控,波動率監控等,發現質量問題,保障出口的最終口徑一致性。
2、降本增效
中臺的建設最終是要為企業降本增效的。過往中,不同業務線重復建設,垂直產品線煙囪式的開發,使得數據成為一個個孤島,雖能滿足單一業務場景,但是卻增加了各個業務線的合作成本。
我們的建設思路是,首先將公共、通用的部分抽離出來,形成可復用服務,讓業務可以快速完成數據鏈路的搭建,減少業務重復造輪子,降低研發成本;其次,統一服務標準,通過快速復用已建設的數據鏈路搭建的能力,讓數據從定義-->生產-->消費的整個周期縮短,提升對接效率,為數據在不同部門間流轉創造可能。
降本:
數據建設成本:通過模型、指標標準化的定義與管理,數據建設中的一個個表或者模型成為一個可以復用的標準數據資產,數據建設中只需增量建設,規避重復建設,降低數據的建設成本。
服務研發成本:服務通過標準化方式構建,下游使用無歧義,使得API復用成為可能,減少了服務研發成本,服務資源可以重復利用。
提效:
數據構建提效:數據構建時,通過元數據的管理,自動化及半自動化的構建出模型及指標,提高了數據構建效率;另外構建出的數據資產是標準化的,消除了數據格式、生產、存儲等差異性,下游消費時不用關心底層的邏輯,提高了應用的效率。
服務使用提效:標準化的API,在系統對接時可以實現一次對接溝通,多次復用,提高了API的對接效率。
3、高可用建設
服務隔離:隔離是將服務或資源分割開。服務隔離是為了在服務發生故障時,能減少傳播范圍和影響范圍,故障發生后不會發生滾雪球效應,從而保證只有出問題的服務不可用,我們根據服務的保障等級,劃分為5個服務資源組,不同資源組相互獨立,不會產生相互影響;存儲資源隔離是通過資源隔離來減少資源競爭,保障服務間的相互不影響和可用性,我們將資源隔離做到API級別,不同API間及不同等級間做隔離,充分保障資源間的相互不影響。
異地雙活:異地雙活的目的也就是容災,當某個地方服務出現了災難性故障,而服務仍然能正常提供服務。我們根據業務的部署情況,選擇距離業務較近的A、B兩地機房部署服務,正常情況下同機房的請求鏈路為主鏈路,當某地服務宕機,則會自動降級到另外一地的服務。
四、數據服務中臺成果&規劃
最后分享我們的數據服務中臺目前取得的成果,以及未來的建設規劃。
B站數據服務中臺上線一年左右,目前支持三大類數據使用場景,一種是API的使用場景,提供了API市場,包括在線、準在線、OLAP分析,以及實時的場景;第二塊是支撐數據產品建設,包括業務分析產品、平臺分析產品、主題分析產品等;第三是支持BI工具,比如自助取數、異動分析、下鉆分析、自助報表等。
API的數量目前有600個以上,在性能和穩定性方面都有著不錯的表現,數據開發周期從原來平均1周的時間,縮短到現在的1天左右。
未來我們會從五個方向去做數據服務中臺建設:
第一個是服務治理方向,根據服務等級、服務監控、數據鏈路的信息,讓服務能夠高質量、低成本、強有效地運行。
第二個方向是支持更多的場景,比如推動一些平臺類的產品接入,包括標簽平臺、AB 平臺的等能夠從服務中臺管理及使用數據。
第三是服務編排,我們希望服務能夠更加貼近于業務的需求,讓數據能夠做到即取即可用。
第四是降級容災,希望能夠做到日常的災備演練、主備功能切換演練等。
最后就是持續的降本增效,在大數據計算資源效率、存儲效率方面持續投入研發,向高效率、低成本更進一步。