概述
上一篇文章主要介紹了數據中台的原理知識,現在開始介紹數據中台的實現篇章,主要從3個方面來說明,第一個是元數據的管理,第二個是指標的規范的管理,第三個是數據模型的建立。
元數據
在原理篇中,我提到數據中台的構建,需要確保全局指標的業務口徑一致,要把原先口徑不一致的、重復的指標進行梳理,整合成一個統一的指標字典。而這項工作的前提,是要搞清楚這些指標的業務口徑、數據來源和計算邏輯。而這些數據呢都是元數據。你可以認為,如果沒有這些元數據,就沒法去梳理指標,更談不上構建一個統一的指標體系。當你看到一個數 700W,如果你不知道這個數對應的指標是每日日活,就沒辦法理解這個數據的業務含義,也就無法去整合這些數據。所以你必須要掌握元數據的管理,才能構建一個數據中台。
那么問題來了:元數據中心應該包括哪些元數據呢? 什么樣的數據是元數據?
元數據分類
結合我的實踐經驗,我把元數據划為三類:數據字典、數據血緣和數據特征。我們還是通過一個例子來理解這三類元數據。
在這個圖中,dwd_trd_order_df 是一張訂單交易明細數據,任務 flow_dws_trd_sku_1d 讀取這張表,按照 sku 粒度,計算每日 sku 的交易金額和訂單數量,輸出輕度匯總表 dws_trd_sku_1d。數據字典描述的是數據的結構信息,我們以 dws_trd_sku_1d 為例,數據字典包括:
數據血緣是指一個表是直接通過哪些表加工而來,在上面的例子中,dws_trd_sku_1d 是通過 dwd_trd_order_df 的數據計算而來,所以,dwd_trd_order_df 是 dws_trd_sku_1d 的上游表。數據血緣一般會幫我們做影響分析和故障溯源。比如說有一天,你的老板看到某個指標的數據違反常識,讓你去排查這個指標計算是否正確,你首先需要找到這個指標所在的表,然后順着這個表的上游表逐個去排查校驗數據,才能找到異常數據的根源。而數據特征主要是指數據的屬性信息,我們以 dws_trd_sku_1d 為例:
通過這個例子,你了解了元數據了嗎? 不過元數據的種類非常多,為了管理這些元數據,你必須要構建一個元數據中心。那么接下來,我們就來看看如何搭建一個元數據中心,打通企業的元數據。
業界元數據中心產品
我做系統設計這么些年,一直有一個習慣,是先看看業界的產品都是怎么設計的,避免關門造車。業界的比較有影響力的產品:
開源的有 Netflix 的 Metacat、Apache Atlas;
商業化的產品有 Cloudera Navigator。
我今天重點想帶你了解 Metacat 和 Atlas 這兩款產品,一個擅長於管理數據字典,一個擅長於管理數據血緣,通過了解這兩款產品,你更能深入的理解元數據中心應該如何設計。
Metacat 多數據源集成型架構設計關於Metacat,你可以在 GitHub 上找到相關介紹,所以關於這個項目的背景和功能特性,我就不再多講,我只想強調一個點,就是它多數據源的可擴展架構設計,因為這個點對於數據字典的管理,真的太重要!
在一般的公司中,數據源類型非常多是很常見的現象,包括 Hive、MySQL、Oracle、Greenplum 等等。支持不同數據源,建立一個可擴展的、統一的元數據層是非常重要的,否則你的元數據是缺失的。從上面 Metacat 的架構圖中,你可以看到,Metacat 的設計非常巧妙,它並沒有單獨再保存一份元數據,而是采取直連數據源拉的方式,一方面它不存在保存兩份元數據一致性的問題,另一方面,這種架構設計很輕量化,每個數據源只要實現一個連接實現類即可,擴展成本很低,我把這種設計叫做集成型設計。我認為這種設計方式對於希望構建元數據中心的企業,是非常有借鑒意義的。
Apache Atlas 實時數據血緣采集同樣,關於Apache Atlas的背景和功能,我也不多說,只是想強調 Atlas 實時數據血緣采集的架構設計,因為它為解決血緣采集的准確性和時效性難題提供了很多的解決思路。血緣采集,一般可以通過三種方式:
通過靜態解析 SQL,獲得輸入表和輸出表;
通過實時抓取正在執行的 SQL,解析執行計划,獲取輸入表和輸出表;
通過任務日志解析的方式,獲取執行后的 SQL 輸入表和輸出表。
第一種方式,面臨准確性的問題,因為任務沒有執行,這個 SQL 對不對都是一個問題。第三種方式,血緣雖然是執行后產生的,可以確保是准確的,但是時效性比較差,通常要分析大量的任務日志數據。所以第二種方式,我認為是比較理想的實現方式,而 Atlas 就是這種實現。
對於 Hive 計算引擎,Atlas 通過 Hook 方式,實時地捕捉任務執行計划,獲取輸入表和輸出表,推送給 Kafka,由一個 Ingest 模塊負責將血緣寫入 JanusGraph 圖數據庫中。然后通過 API 的方式,基於圖查詢引擎,獲取血緣關系。對於 Spark,Atlas 提供了 Listener 的實現方式,此外 Sqoop、Flink 也有對應的實現方式。這兩款產品在設計網易元數據中心時,給了很多靈感,下面我就帶你了解一下其他元數據中心的設計,以便你掌握一個元數據中心在設計時應該考慮哪些點。
我設定了元數據中心必須實現的 5 個關鍵目標:
其一,多業務線、多租戶支持。電商、音樂都是不同的業務線,同一個業務線內,也分為算法、數倉、風控等多個租戶,所以元數據中心必須支持多業務線、多租戶。
其二,多數據源的支持。元數據中心必須要能夠支持不同類型的數據源(比如 MySQL、Hive、Kudu 等),同時還要支持相同數據源的多個集群。為了規范化管理,還需要考慮將半結構化的 KV 也納入元數據中心的管理(比如 Kafka、Redis、HBase 等)。這些系統本身並沒有表結構元數據,所以需要能夠在元數據中心里定義 Kafka 每個 Topic 的每條記錄 JSON 中的格式,每個字段代表什么含義。
其三,數據血緣。元數據中心需要支持數據血緣的實時采集和高性能的查詢。同時,還必須支持字段級別的血緣。什么是字段級別的血緣,我們來舉個例子。
1 insert overwrite table t2 select classid, count(userid) from t1 groupby classid;
t2 表是由 t1 表的數據計算來的,所以 t2 和 t1 是表血緣上下游關系,t2 的 classid 字段是由 t1 的 classid 字段產生的,count 字段是由 userid 經過按照 classid 字段聚合計算得到的,所以 t2 表的 classid 與 t1 的 classid 存在字段血緣,t2 表的 count 分別與 t1 表的 classid 和 userid 存在血緣關系。
字段血緣在做溯源的時候非常有用,因為大數據加工鏈路的下游是集市層,為了方便使用者使用,一般都是一些很寬的表(列很多的表,避免 Join 帶來的性能損耗),這個表的上游可能是有幾十個表產生的,如果不通過字段血緣限定溯源范圍,就會導致搜索范圍變得很大,無法快速地精准定位到有問題的表。另外,數據血緣還必須要支持生命周期管理,已經下線的任務應該立即清理血緣,血緣要保留一段時間,如果沒有繼續被調度,過期的血緣關系應該予以清理。
其四,與大數據平台集成。元數據中心需要與 Ranger 集成,實現基於 tag 的權限管理方式。在元數據中心中可以為表定義一組標簽,Ranger 可以基於這個標簽,對擁有某一個標簽的一組表按照相同的權限授權。這種方式大幅提高了權限管理的效率。比如,對於會員、交易、毛利、成本,可以設定表的敏感等級,然后根據敏感等級,設定不同的人有權限查看。另外,元數據中心作為基礎元數據服務,包括自助取數分析系統,數據傳輸系統,數據服務,都應該基於元數據中心提供的統一接口獲取元數據。
其五,數據標簽。元數據中心必須要支持對表和表中的字段打標簽,通過豐富的不同類型的標簽,可以完善數據中台數據的特征,比如指標可以作為一種類型的標簽打在表上,主題域、分層信息都可以作為不同類型的標簽關聯到表。
基於這 5 個因素的考慮,我們設計了元數據中心。
這個圖按照功能模塊分為數據血緣、數據字典和數據特征。數據血緣由采集端、消息中間件、消費端以及血緣清理模塊組成,基於 Hive Hook,Spark Listener,Flink Hook ,可以獲取任務執行時輸入表和輸出表,推送給統一的消息中間件(Kafka),然后消費端負責將血緣關系沉淀到圖數據庫中。圖數據庫選擇 Neo4j,主要考慮是性能快、部署輕量化、依賴模塊少,當然,開源的 Neo4j 沒有高可用方案,並且不支持水平擴展,但是因為單個業務活躍的表規模基本也就在幾萬的規模,所以單機也夠用,高可用可以通過雙寫的方式實現。血緣還有一個清理的模塊,主要負責定時清理過期的血緣,一般我們把血緣的生命周期設置為 7 天。數據字典部分,我們參考了 Metacat 實現,我們由一個統一的 Connector Mananger 負責管理到各個數據源的連接。對於 Hive、MySQL,元數據中心並不會保存系統元數據,而是直接連數據源實時獲取。對於 Kafka、HBase、Redis 等 KV,我們在元數據中心里內置了一個元數據管理模塊,可以在這個模塊中定義 Value 的 schema 信息。數據特征主要是標簽的管理以及數據的訪問熱度信息。元數據中心內置了不同類型的標簽,同時允許用戶自定義擴展標簽類型。指標、分層信息、主題域信息都是以標簽的形式存儲在元數據中心的系統庫里,同時元數據中心允許用戶基於標簽類型和標簽搜索表和字段。元數據中心統一對外提供了 API 訪問接口,數據傳輸、數據地圖、數據服務等其他的子系統都可以通過 API 接口獲取元數據。另外 Ranger 可以基於元數據中心提供的 API 接口,獲取標簽對應的表,然后根據標簽更新表對應的權限,實現基於標簽的權限控制。元數據中心構建好以后,你肯定會問,這個元數據中心沒有界面嗎?它長什么樣子?用戶咋使用這個元數據中心? 別急,我們接着往下看。
數據地圖:元數據中心的界面
數據地圖是基於元數據中心構建的一站式企業數據資產目錄,可以看作是元數據中心的界面。數據開發、分析師、數據運營、算法工程師可以在數據地圖上完成數據的檢索,解決了“不知道有哪些數據?”“到哪里找數據?”“如何准確的理解數據”的難題。
數據地圖提供了多維度的檢索功能,使用者可以按照表名、列名、注釋、主題域、分層、指標進行檢索,結果按照匹配相關度進行排序。考慮到數據中台中有一些表是數倉維護的表,有一些表數倉已經不再維護,在結果排序的時候,增加了數倉維護的表優先展示的規則。同時數據地圖還提供了按照主題域、業務過程導覽,可以幫助使用者快速了解當前有哪些表可以使用。
當使用者定位到某一個表打開時,會進入詳情頁,詳情頁中會展示表的基礎信息,字段信息、分區信息、產出信息以及數據血緣。數據血緣可以幫助使用者了解這個表的來源和去向,這個表可能影響的下游應用和報表,這個表的數據來源。
數據地圖同時還提供了數據預覽的功能,考慮到安全性因素,只允許預覽 10 條數據,用於判斷數據是否符合使用者的預期。數據地圖提供的收藏功能, 方便使用者快速找到自己經常使用的表。當數據開發、分析師、數據運營找到自己需要的表時,在數據地圖上可以直接發起申請對該表的權限申請。數據地圖對於提高數據發現的效率,實現非技術人員自助取數有重要作用。經過我的實踐,數據地圖是數據中台中使用頻率最高的一個工具產品,在網易,每天都有 500 以上人在使用數據地圖查找數據。
數據指標規范
元數據在指標管理、模型設計、數據質量和成本治理四個領域都發揮着作用,而這些領域構成了數據中台 OneData 數據體系。從今天開始,我將帶你逐一了解元數據在上述領域的應用,首先是指標管理。指標是一種特定類型的元數據,公司的運營會圍繞它進行工作,可以說,它是業務和數據的交匯點。指標數據能不能用,會影響他們的日常工作。來看一件我身邊發生的事兒。在電商業務中,新用戶銷售額是考核市場活動拉新效果的重要指標。馬漂亮(化名)是市場部門的數據分析師,某一天,她要給 CEO 提供一份數據報告,報告中有一項指標是“新用戶銷售額”。孫美麗(化名)是會員中心的運營,她每天都會給 CEO 提供每日的新用戶銷售額數據。結果有一天,CEO 看了這兩份報告后發現,同一日的新用戶銷售額數值相差很大,他判斷數據出了問題,責令兩個部門的負責人進行排查。排查后發現,市場部門對新用戶口徑的定義和會員中心不一樣:
市場部門認定新用戶是首次下單並完成支付的用戶;
會員中心認定新用戶是當日新注冊用戶。
也就是說,市場部門認定的新用戶中,可能有之前注冊但是沒有下過單的客戶;而會員中心只包括當日注冊並完成下單支付的用戶。其實,在日常工作中還有很多類似的問題。造成上述問題的根源是因為指標口徑不一致,而你要構建全局一致的指標口徑,輸出企業的指標字典。
指標混亂現狀
同名不同徑,同徑不同名。口徑不清晰,口徑有錯誤。命名難理解,計算不易懂。來源不清晰,同部不同徑。
第一,相同指標名稱,口徑定義不同。我開篇說的就是這個問題,不同的部門對相同的“新用戶銷售額”,因為口徑定義的差別,導致指標數值的不一致。而這種情況是指標管理中最容易出現的情況。口徑不一致,數據也就沒辦法橫向對比,失去了數據輔助商業決策的意義。
第二,相同口徑,指標名稱不一樣。這種情況與上面相反,比如發放優惠券是電商常見的促銷手段,現在你有兩個數據產品:一個是經營大腦,主要展示的是企業日常經營活動健康度的核心指標,它有一個指標叫“優惠券抵扣金額”;一個是市場 360,主要是展示市場活動效果衡量的指標,它也有一個指標叫“優惠券消耗金額”。其實,兩者的口徑定義並沒有區別,但是指標名稱不同,這會讓使用指標的人疑惑,是不是同一個指標,計算邏輯是否一致?數據是否可以橫向對比?
第三,不同限定詞,描述相同事實過程的兩個指標,相同事實部分口徑不一致。
第四,指標口徑描述不清晰。在梳理過程中,我們還發現,有些報表上的指標口徑描述的比較籠統。比如“關單金額”,口徑描述“關閉訂單的金額”。不同人的理解可能不一樣,有的人會認為是支付成功后關閉訂單;也有可能是支付完成前,取消訂單。描述不清晰,就會讓人們對數據的理解產生歧義。
第五,指標口徑描述錯誤。在流量分析數據產品中,有“7 日 uv”這個指標,口徑的定義是 7 日內日均 uv。根據口徑描述的計算邏輯,應該是最近 7 日,每日 uv 相加除以 7 取平均值。顯然,這個定義在業務場景中是有問題的,正確的 7 日 uv 的口徑定義應該是 7 日內有登錄過,去重的用戶數。
第六,指標命名難於理解。我們在梳理促銷業務過程的指標時,有一個數據產品的指標名稱是“ROI”,口徑定義優惠券銷售額 / 優惠券成本。ROI 其實是投資回報率的簡稱,在電商業務場景中,除了優惠劵,商品降價促銷都可以計算 ROI,所以比較好的命名應該是(商品|類目|通用)優惠劵 ROI。所以,指標命名不規范的話,從指標名稱中很難看出指標描述的業務過程。
最后,指標數據來源和計算邏輯不清晰。如果指標數據來源不清楚,一旦這個指標數據異常,就很難去做溯源。另外,有些指標的計算邏輯比較復雜,僅僅憑借業務口徑一段描述,使用指標的人還是無法理解這個指標的計算邏輯,這個時候就需要有一些偽碼或者 SQL 描述。
如何規范化定義指標
那么如果你面臨這些問題,該如何規范化定義指標呢?我提供給你一些經驗,希望你能從中學習到如何高效、規范化的管理指標。
為了提高指標管理的效率,你需要按照業務線、主題域和業務過程三級目錄方式管理指標(業務線是頂級目錄)。電商、游戲、音樂、傳媒、教育都是不同的業務線。在業務線之下,是主題域,指標中的主題域與數倉中的概念是一致的,划分標准最好是跟數倉保持一致(數倉主題域的划分,我會在 06 講詳細講述)。在主題域下面還有細分的業務過程,比如對於交易域,細分的業務過程有加入購物車、下單、支付。
其次,拆分原子指標和派生指標。為了解決前面提到的,“黑卡購買用戶數”和“非會員購買用戶數”,這兩個指標對購買用戶數口徑定義不一致的問題,我們需要引入原子指標和派生指標的管理方式。那么什么是原子指標,什么是派生指標呢?統計周期、統計粒度、業務限定、原子指標,組成派生指標,所以原子指標可以定義為不能夠按照上述規則進一步拆分的指標。
在例子中,你可以這樣理解:購買用戶數是原子指標,原子指標的口徑定義是“計算周期內去重的,下單並且支付成功的用戶數量,包括關單”;黑卡會員和非會員都可以認定為業務限定詞;統計粒度是商品粒度的;統計周期是 30 天。
這樣 30 天內,商品維度的黑卡會員購買用戶數和 30 天內商品維度的非會員購買用戶數就作為兩個派生指標存在,但是他們繼承自同一個原子指標。
除此之外,還需要指標命名規范。指標命名規范要遵循兩個基本的原則:易懂,就是看到指標的名稱,就可以基本判斷這個指標歸屬於哪個業務過程;統一,就是要確保派生指標和它繼承的原子指標命名是一致的。除此之外,指標應該有指標名稱和指標標識(或者叫英文名)。
對於原子指標,指標名稱適合用“動作 + 度量”的命名方式(比如注冊用戶數、購買用戶數),標識的命名用英文簡寫或者漢語拼音縮寫比較好。對於派生指標,指標名稱應該嚴格遵循“時間周期 + 統計粒度 + 修飾詞 + 原子指標”的命名方式,標識命名要用“修飾詞 _ 原子指標 _ 時間周期”的方式。
第四,關聯的應用和可分析維度。對於使用指標的人(運營、分析師)了解了這個指標的口徑定義之后,下一步就是要看指標的數值。所以,在全局的指標字典中,還應該有指標被哪些應用使用,這樣方便去對應的數據產品或者報表上查看指標的數值。除此之外,還應該有指標的可分析維度,方便分析師從不同的維度分析指標的變化趨勢。
最后一個是分等級管理。那這么多指標,數據中台管的過來么?是的,確實管不過來,因為不僅僅是數據中台會產出一些公共核心指標,業務部門也會創建一些專屬業務部門內的指標。那面對這么多指標,如何管理呢?以我的經驗,你可以按照以下原則區分等級,來管理指標。一級指標:數據中台直接產出,核心指標(提供給公司高層看的)、原子指標以及跨部門的派生指標。二級指標:基於中台提供的原子指標,業務部門創建的派生指標。不同等級的指標意味着管理方式不同:一級指標,要確保指標按時、保證質量產出,指標創建由中台負責;二級指標,允許業務方自己創建,中台不承諾指標的產出時間和質量。現在你了解如何管理指標了嗎? 我建議你在學完這部分知識以后,結合自己所在的業務,找一些指標,試着按照上面的方法實踐一下,這樣掌握得會加更深刻。
指標系統
在了解如何管理指標之后,我們還需要一款好用的工具,幫助我們落實管理方法。我觀察到,很多公司喜歡用 Excel 管理指標,覺得 Excel 上手容易,編輯比較方便。在我看來,Excel 並不是一個適合指標管理的工具,有這樣幾個原因:難於共享;缺少權限控制;無法動態更新;指標無法跟數倉的模型動態關聯。所以,我們需要一個面向指標的管理系統。
指標系統是基於元數據中心構建的一個指標管理工具,它從元數據中心自動同步數倉的主題域和業務過程,按照規范化定義創建指標。新創建的指標同時會以特定類型的標簽,下沉到元數據中心對應的表和字段上,這樣在數據地圖上就可以搜索到表關聯的指標。
既然指標系統能夠實現指標的規范化定義,幫你解決“如何系統化、規范化定義指標”的問題,那接下來我們的重點就是如何基於指標系統構建全局的指標字典,因為這是指標治理的最終結果。
基於指標系統構建全局的指標字典指標治理的最終結果,就是要形成一個全局業務口徑一致的指標字典。讓使用指標的人,可以通過指標字典,快速了解指標的業務含義和計算過程,不會對指標口徑產生歧義。數據中台團隊必須要有一個專門負責指標管理的人或者小組(一般不超過 3 個人),最好是數據產品經理來負責,如果你的公司沒有這個職位,也可以讓分析師承擔(前提是分析師必須屬於中台團隊)。
構建全局的指標字典分為兩個場景:一個是面對一個新的指標需求,如何基於指標系統完成指標開發流程;另外一個是面對已經存在的,混亂的指標現狀,如何進行全局梳理。
我們先看第一個場景。
這個圖詳細地描述了新建指標的流程,流程中參與的各個角色。我在這里想強調幾點:
指標需求評審,需要需求方、數據開發、應用開發都參加。評審首先要確認這是不是一個新的指標,並明確它是原子指標還是派生指標。評審的目的就是要大家達成一致。
評審的結果一種是不需要開發,是一個已經存在的指標,直接可以通過設計邏輯模型(具體我會在數據服務章節講),發布接口,獲取數據。第二種就是需要開發。前者交付時間短,后者需要排期,交付時間長。
上面我提到指標有一級和二級之分,這個流程適用於一級指標,對於二級指標,可以不需要評審,當然開發也是由業務方開發和發布上線。
接下來,我們來看第二個場景。除了新建指標的流程,對於很多公司,已經有一定的大數據業務,但是還不能算是一個中台,那這部分公司該如何進行一次全局的指標梳理呢?我認為應該有以下幾個步驟:成立以數據產品或者分析師為核心的 1~3 人的工作小組,專門負責指標的全局梳理;制定指標梳理計划,明確指標梳理目標,覆蓋多少個業務線,與業務方共同制定時間計划;對於每一個業務線,需要對還在使用的數據報表、數據產品進行盤點,這里順便可以把沒用的報表和數據產品應該下線;對於每一個報表和數據產品中涉及的指標,按照以下格式進行收集;
對於收集的指標,明確業務口徑,對於口徑相同的,應該去除重復,關聯的應用應該合並,此時以我的經驗,可以過濾掉相當一部分;根據指標業務口徑,明確指標所屬的主題域、業務過程;區分指標類型,對於派生指標,要明確指標的統計粒度、修飾詞、時間周期以及關聯的原子指標;按照指標系統對指標的規范化定義,把整理好的指標錄入指標系統。通過全局的梳理和新建指標流程的管控,你就可以構建一個全局一致的指標字典了。
數據模型
我帶你了解了數據中台如何管理指標,如果我們把指標比喻成一棵樹上的果實,那模型就是這棵大樹的軀干,想讓果實結得好,必須讓樹干變得粗壯。
先來看一幕真實的場景。大多數公司的分析師會結合業務做一些數據分析(需要用到大量的數據),通過報表的方式服務於業務部門的運營。但是在數據中台構建之前,分析師經常發現自己沒有可以復用的數據,不得不使用原始數據進行清洗、加工、計算指標。由於他們大多是非技術專業出身,寫的 SQL 質量比較差,我甚至見過 5 層以上的嵌套。這種 SQL 對資源消耗非常大,會造成隊列阻塞,影響其他數倉任務,會引起數據開發的不滿。數據開發會要求收回分析師的原始數據讀取權限,分析師又會抱怨數倉數據不完善,要啥沒啥,一個需求經常要等一周甚至半個月。分析師與數據開發的矛盾從此開始。這個矛盾的根源在於數據模型無法復用,數據開發是煙囪式的,每次遇到新的需求,都從原始數據重新計算,自然耗時。而要解決這個矛盾,就要搞清楚我們的數據模型應該設計成什么樣子。
什么才是一個好的數據模型設計?
來看一組數據,這兩個表格是基於元數據中心提供的血緣信息,分別對大數據平台上運行的任務和分析查詢(Ad-hoc)進行的統計。
下圖是數倉分層架構圖,方便你回憶數據模型分層的設計架構:
我們首先來看表 1。表 1 中有 2547 張未識別分層的表,占總表 6049 的 40%,它們基本沒辦法復用。 重點是在已識別分層的讀表任務中,ODS:DWD:DWS:ADS 的讀取任務分別是 1072:545:187:433,直接讀取 ODS 層任務占這四層任務總和的 47.9%,這說明有大量任務都是基於原始數據加工,中間模型復用性很差。我們再來看看表 2,在已識別的分層的查詢中,ODS:DWD:DWS:ADS 的命中的查詢分別是 892:1008:152:305,有 37.8% 的查詢直接命中 ODS 層原始數據,說明 DWD、DWS、ADS 層數據建設缺失嚴重。尤其是 ADS 和 DWS,查詢越底層的表,就會導致查詢掃描的數據量會越大,查詢時間會越長,查詢的資源消耗也越大,使用數據的人滿意度會低。最后,我們進一步對 ODS 層被讀取的 704 張表進行分解,發現有 382 張表的下游產出是 DWS,ADS,尤其是 ADS 達到了 323 張表,占 ODS 層表的比例 45.8%,說明有大量 ODS 層表被進行物理深加工。通過上面的分析,我們似乎已經找到了一個理想的數倉模型設計應該具備的因素,那就是“數據模型可復用,完善且規范”。
如何衡量完善度
DWD 層完善度:衡量 DWD 層是否完善,最好看 ODS 層有多少表被 DWS/ADS/DM 層引用。因為 DWD 以上的層引用的越多,就說明越多的任務是基於原始數據進行深度聚合計算的,明細數據沒有積累,無法被復用,數據清洗、格式化、集成存在重復開發。因此,我提出用跨層引用率指標衡量 DWD 的完善度。跨層引用率:ODS 層直接被 DWS/ADS/DM 層引用的表,占所有 ODS 層表(僅統計活躍表)比例。跨層引用率越低越好,在數據中台模型設計規范中,我們要求不允許出現跨層引用,ODS 層數據只能被 DWD 引用。
DWS/ADS/DM 層完善度:考核匯總數據的完善度,我認為主要看匯總數據能直接滿足多少查詢需求(也就是用匯總層數據的查詢比例衡量)。如果匯總數據無法滿足需求,使用數據的人就必須使用明細數據,甚至是原始數據。匯總數據查詢比例:DWS/ADS/DM 層的查詢占所有查詢的比例。你要明確的是,這個跟跨層引用率不同,匯總查詢比例不可能做到 100%,但值越高,說明上層的數據建設越完善,對於使用數據的人來說,查詢速度和成本會減少,用起來會更爽。
如何衡量復用度
數據中台模型設計的核心是追求模型的復用和共享,通過元數據中心的數據血緣圖,我們可以看到,一個比較差的模型設計,自下而上是一條線。而一個理想的模型設計,它應該是交織的發散型結構。
我提出用模型引用系數作為指標,衡量數據中台模型設計的復用度。引用系數越高,說明數倉的復用性越好。模型引用系數:一個模型被讀取,直接產出下游模型的平均數量。比如一張 DWD 層表被 5 張 DWS 層表引用,這張 DWD 層表的引用系數就是 5,如果把所有 DWD 層表(有下游表的)引用系數取平均值,則為 DWD 層表平均模型引用系數,一般低於 2 比較差,3 以上相對比較好(經驗值)。
如何衡量規范度
表 1 中,超過 40% 的表都沒有分層信息,在模型設計層面,這顯然是不規范的。除了看這個表有沒有分層,還要看它有沒有歸屬到主題域(例如交易域)如果沒有歸屬主題域,就很難找到這張表,也無法復用。其次,你要看表的命名。拿 stock 這個命名為例,當你看到這個表時,知道它是哪個主題域、業務過程?是全量數據的表,還是每天的增量數據?總的來說,通過這個表名獲取的信息太有限了。一個規范的表命名應該包括主題域、分層、表是全量快照,還是增量等信息。除此之外,如果在表 A 中用戶 ID 的命名是 UserID,在表 B 中用戶 ID 命名是 ID,就會對使用者造成困擾,這到底是不是一個東西。所以我們要求相同的字段在不同的模型中,它的命名必須是一致的。
講了這么多,你要如何吸收經驗呢?在這里,我給你幾點建議。
你可以拿着這些指標去評估一下,自己的數倉現狀如何。
然后制訂一些針對性的改進計划,比如把這些不規范命名的表消滅掉,把主題域覆蓋的表比例提高到 90% 以上。
在嘗試完一段時間的模型重構和優化后,再拿着這些指標去測一測是不是真的變好了。我見過很多數據開發在向上級匯報工作時,喜歡用重構了多少模型說明工作成果,很多老大會想,這些重構到底對數據建設有多少幫助?有沒有一些量化的指標可以衡量?我想有上面的知識,你可以應對這個問題了。
現在你知道什么是好的數倉設計了,可目前已經存在了大量煙囪式開發,具體怎么做才能讓它變成一個數據中台呢?
如何從煙囪式的小數倉到共享的數據中台
建設數據中台本質就是構建企業的公共數據層,把原先分散的、煙囪式的、雜亂的小數倉,合並成一個可共享、可復用的數據中台。結合我的實踐經驗,我給你幾點建議。
第一,接管 ODS 層,控制源頭。ODS 是業務數據進入數據中台的第一站,是所有數據加工的源頭,控制住源頭,才能從根本上防止一個重復的數據體系的出現。數據中台團隊必須明確職責,全面接管 ODS 層數據,從業務系統的源數據庫權限入手,確保數據從業務系統產生后進入數據倉庫時,只能在數據中台保持一份。這個可以跟業務系統數據庫管理者達成一致,只有中台團隊的賬號才能同步數據。ODS 層表的數據必須和數據源的表結構、表記錄數一致,高度無損,對於 ODS 層表的命名采用 ODS_ 業務系統數據庫名 _ 業務系統數據庫表名方式,比如 ods_warehous_stock,warehous 是業務系統數據庫名,stock 是該庫下面的表名。
第二,划分主題域,構建總線矩陣。主題域是業務過程的抽象集合。可能這么講,稍微有點兒抽象,但其實業務過程就是企業經營過程中一個個不可拆分的行為事件,比如倉儲管理里面有入庫、出庫、發貨、簽收,都是業務過程,抽象出來的主題域就是倉儲域。
主題域划分要盡量涵蓋所有業務需求,保持相對穩定性,還具備一定的擴展性(新加入一個主題域,不影響已經划分的主題域的表)。主題域划分好以后,就要開始構建總線矩陣,明確每個主題域下的業務過程有哪些分析維度,舉個例子:
第三,構建一致性維度。售后團隊的投訴工單數量有針對地區的分析維度,而配送團隊的配送延遲也有針對地區的分析維度,你想分析因為配送延遲導致的投訴增加,但是兩個地區的分析維度包含內容不一致,最終會導致一些地區沒辦法分析。所以我們構建全局一致性的維表,確保維表只存一份。維度統一的最大的難題在於維度屬性(如果維度是商品,那么商品類別、商品品牌、商品尺寸等商品的屬性,我們稱為維度屬性)的整合。是不是所有維度屬性都要整合到一個大的維表中,也不見得,我給你幾個建議。
公共維度屬性與特有維度屬性拆成兩個維表。在自營平台中,通常也會有一些第三方的商家入駐,但是數量很少。大部分商品其實都沒有店鋪的屬性,這種情況,就不建議將店鋪和商品的其他維度屬性,比如商品類別、品牌設計成一個維表。
產出時間相差較大的維度屬性拆分單獨的維表,比如有些維度屬性產出時間在凌晨 2 點,有些維度屬性產出時間在凌晨 6 點,那 2 點和 6 點的就可以拆成兩個維表,確保核心維表盡早產出。
出於維表穩定性產出的考慮,你可以將更新頻繁的和變化緩慢的進行拆分,訪問頻繁的和訪問較少的維表進行拆分。對於維表的規范化命名,建議你用“DIM_ 主題域 _ 描述 _ 分表規則”方式。分表你可以這樣理解:一個表存儲幾千億行記錄實在是太大了,所以需要把一個表切割成很多小的分區,每天或者每周,隨着任務被調度,會生成一個分區。我提供給你一個常見的分區規則(這個規則你在用的時候,查閱就可以了)。
第四,事實表整合。我覺得事實表整合遵循的最基本的一個原則是,統計粒度必須保持一致,不同統計粒度的數據不能出現在同一個事實表中。來看一個例子:
在數據中台構建前,供應鏈部門、倉儲部門和市場部門都有一些重復的事實表,我們需要將這些重復的內容進行去除,按照交易域和倉儲域,主題域的方式進行整合。
對於倉儲部門和供應鏈部門都有的庫存明細表,因為倉儲部門的統計粒度是商品加倉庫,而供應鏈部門的只有商品,所以原則上兩個表是不能合並,而是應該獨立存在。
對於市場部門和供應鏈部門的兩張下單明細表,因為統計粒度都是訂單級別,都歸屬於交易域下的下單業務過程,所以可以合並為一張事實表。除此之外,還應該考慮將不全的數據補齊。對於 ODS 層直接被引用產出 DWS/ADS/DM 層的任務,通過血緣,找到任務清單,逐個進行拆解。沒有 ODS 對應的 DWD 的,應該生成 DWD 表,對於已經存在的,應該遷移任務,使用 DWD 層表。
DWD/DWS/ADS/DM 的命名規則適合采用“[層次][主題][子主題][內容描述][分表規則]”的命名方式。
第五,模型開發。模型設計完成后,就進入模型開發階段,我想提幾個你需要注意的點:
所有任務都必須嚴格配置任務依賴,如果沒有配置任務依賴,會導致前一個任務沒有正常產出數據的情況下,后一個任務被調度起來,基於錯誤的數據空跑,浪費資源,同時增加了排查故障的復雜度;
任務中創建的臨時表,在任務結束前應該刪除,如果不刪除,會發現有大量的臨時表存在,占用空間;
任務名稱最好跟表名一致,方便查找和關聯;
生命周期的管理,對於 ODS 和 DWD,一般盡可能保留所有歷史數據,對於DWS/ADS/DM 需要設置生命周期,7~30 天不等;
DWD 層表宜采用壓縮的方式存儲,可用 lzo 壓縮。
第六,應用遷移。最后一步就是應用的遷移,這個過程的核心是要注意數據的比對,確保數據的完全一致,然后進行應用遷移,刪除老的數據表。總的來說,建設數據中台不是一口氣就能吃成一個胖子,它的建設往往是滾雪球的方式,隨着一個個應用的遷移,中台的數據也越來越豐滿,發揮的價值也越來越大。
總結
以后關於數據中台系列的總結大部分來自Geek Time的課件,大家可以自行關鍵字搜索。