小米數據中臺建設實踐賦能業(yè)務增長!
一、銷售數倉介紹
首先介紹下小米銷售數倉,包括發(fā)展歷程、銷售數倉定義、數據獲取使用、銷售數倉的內容和規(guī)模。
在 2019 年前,小米的中國區(qū)、國際部等業(yè)務數據團隊在進行獨立的數倉建設,這個時期是煙囪式的開發(fā)。隨著業(yè)務飛速發(fā)展,在集團技術委 ABC(AI、Big data、Cloud)策略的指導下,開始建設統(tǒng)一的銷售數倉。在 2020 年,完成了離線銷售數倉的建設,同時在籌備實時數倉的建設。2021 年,實時數倉建設完畢,隨著后續(xù)的業(yè)務和技術升級,進入了迭代優(yōu)化和數據應用階段。
小米的銷售數倉整體上就是存放整個公司銷售數據的倉庫,包括了訂單數據、物流數據、門店數據、用戶行為數據及商品數據,并按照維度建模和規(guī)范進行建設的高效數據集合。
上圖是銷售數倉的場景圖,數據主要來自于兩個部分,一是在線業(yè)務數據,主要是訂單系統(tǒng)、商品中心(小米的所有商品進行管理的地方)、門店系統(tǒng)(線下門店進行管理的地方)、售后系統(tǒng)和進銷存系統(tǒng)。同時也有一些日志采集數據,經過銷售數倉的處理,劃分為不同的主題進行建設。銷售數倉整體會進行元數據管理,目標是做到全域的元數據管理。最上層是數據應用層,包括集團數據看板、三區(qū)運營的看板、實時大屏、大促戰(zhàn)報和數據挖掘。
銷售數倉數據的獲取主要通過以下三種方式:
- 用戶通過數據地圖進行查詢,數據地圖中會顯示集群、存儲介質、表詳情、血緣等。
- 通過數據工場,可以進行數據查詢以及任務的開發(fā)部署等。
- 通過數據百科,對數據指標進行管理錄入和使用。
數倉的使用形式有多種,包括傳統(tǒng)的離線 Hive、數據湖 Iceberg、實時消息隊列 Talos、OLAP 引擎、即時查詢等。
銷售數倉的目標是為公司提供準確好用的銷售數據。在區(qū)域方面,包含全球的業(yè)務;在品類方面,包含手機、筆記本、大家電、生態(tài)鏈等;在渠道方面,包含小米網、商城、米家、三方平臺等。我們的日單量在千萬級別,每天會處理上億條日志數據。
二、數倉建設理論
在進行數倉建設時,首先是梳理業(yè)務,找到核心業(yè)務邏輯,對業(yè)務過程進行認識和理解,并在數據庫中找到相關的數據表。在此基礎上,站在更高維度對業(yè)務流和數據流進行匯總和分類,劃分好主題域,便于后續(xù)的管理。然后進行事實表和維表的梳理,借助數據百科進行指標梳理,以具體的業(yè)務為核心,指標與維度同等重要。接下來對數倉進行建模,按照維度建模方式組織數據,在這個過程中需要注意分層和規(guī)范。最后就是物理實現,這個環(huán)節(jié)重點關注的是開發(fā)規(guī)范、交付物、質量等
接下來介紹數倉分層方式。數倉分層最底層是 ODS 層,它是貼源數據,與業(yè)務數據保持一致。在 ODS 之上是 DW 層,DW 層可以細分為兩層。一層是 DWD 基礎數據,主要做清洗和規(guī)范化,不對數倉團隊外部開放使用。另一層是 DWM 層通用數據。基于 DWD 的數據做關聯和聚合,會將核心的邏輯實現放在這一層,用于提升公共數據的復用性,可以開放給外部團隊使用。數倉中還有 DIM 層(維度層),DM 層(寬表層),ADS 層(應用數據層),以及 TMP 層(存放臨時表)
在數倉建模過程中,需要遵循以下一些基本的建模原則:高內聚低耦合,公共邏輯下層,成本與性能平衡、一致性、數據可回滾。
1. 高內聚低耦合
將業(yè)務相近的數據設計為一個邏輯模型或者物理模型。例如訂單有很多來源,包括小米商城、小米網、有品商城以及三方數據等。在 DW 層會整合為同一個訂單表,同時會對一些缺失字段進行默認處理,保證所有來源的數據最終在 DW 層是統(tǒng)一的,從而實現高內聚。訂單和物流被劃定為不同的主題,以減少其耦合度。
2. 公共邏輯下沉
前面介紹數倉分層時,指出公共邏輯要盡量放在 DWM 層處理,對下游使用方盡量屏蔽復雜的業(yè)務邏輯,從而做到口徑統(tǒng)一。例如在訂單處理過程中,會有很多無效的訂單,識別無效訂單的核心邏輯在 DWM 層,這樣下游業(yè)務方就可以直接使用。
3. 成本與性能平衡
一定的數據冗余,雖然可能帶來成本增加,但查詢性能可以得到提高。例如在區(qū)域維表設計中,針對國家、省份、城市、區(qū)縣,通過一個區(qū)域層級字段將其分類,雖然數據是冗余的,但用戶使用起來會比較方便,并且查詢更快速。
4. 一致性
在數倉建模過程中,要保證字段含義和命名規(guī)范是統(tǒng)一的,這樣可以降低理解和使用的成本。
5. 數據可回滾
要保證數據可回滾,在不同時間去執(zhí)行數倉的調度,針對歷史數據計算出的結果是一致的。
那我們是如何進行指標管理呢?在小米內部會通過 OSM 模型,根據公司的目標和策略,通過數倉中的度量值進行考核。
例如 2023 年的目標是手機出貨量要達到 X 萬臺,相關策略是要設計好產品,提高用戶購買;同時嚴控質量,減少質量問題帶來的影響。基于目標和策略,在銷售數倉中通過兩個度量值來衡量,一是手機妥投數量,這個數值要盡可能高;二是手機售后退貨數量,反饋質量情況。
指標生產是基于 Hive 離線數據、MySQL 在線數據、分析數據進行建模,建立語義模型,再進行審核認證,發(fā)布到集團指標庫,與數據百科進行聯動。在指標消費側,用戶可以通過數據百科進行查詢指標口徑詳情、上游血緣、維度等,數據百科與公司的 OA 工具進行聯通,提高指標易用性和使用效率。
三、銷售數倉架構介紹
小米的銷售數倉采用的是 Lambda 架構。銷售數據是集團數倉中的核心之一,內部關注度高。如果是流處理,部分情況下無法達到百分之百的準確性,因此需要通過批處理,去保證 T+1 數據的準確性。在批處理層使用 Spark 加 Hive 去處理離線數據。在流式處理層,使用 Flink 加消息隊列 Talos。在 DW 和 DM 層,會通過 Hologres 進行維表的加速查詢。最終再把這兩部分數據進行聯合,提供給下游業(yè)務方使用。
我們在處理銷售實時數據中,會遇到各樣的問題,這里介紹下實時數據流狀態(tài)過期問題的解決方法。在實時數據中,銷售訂單主要分兩部分。第一部分是訂單事實表,第二部分是訂單明細事實表。訂單中所有的狀態(tài)變更都體現在訂單事實表,而訂單明細數據在第一次創(chuàng)建之后,就不會再發(fā)生變化。大家都知道,實時計算消息隊列的保存時間是有限制的,通常會設置一個時間周期。Flink 也有計算狀態(tài)的保存時間,在一定時間周期后計算狀態(tài)會過期,需要注意的是,由于訂單明細不再變化,如果一些訂單主表的兩次狀態(tài)變化時間大于狀態(tài)過期時間,這時候銷售相關指標是失準的。
實踐中是通過引入一個離線流,在訂單和訂單明細上各自去識別這部分過期數據,通過一個離線數據的消息隊列,與原始的實時數據流進行合并,去重后下發(fā)到下游進行處理,大幅度提高同類場景下數據準確性。
但是這樣會引發(fā)另外一個問題,即批處理思維方式帶來的物流指標異常。
以物流場景為例,一些國際業(yè)務在商品出貨后,由于距離較遠或者報關審批等流程,會導致部分貨物可能三個月后才發(fā)生一個狀態(tài)變更。物流主表記錄物流狀態(tài)的變更,物流明細表以及離線的補充物流明細表會進行合并操作,之后對這兩部分進行去重,去重后的結果再與物流主表進行關聯,然后下發(fā)進行其他的處理邏輯。這是一個典型的離線處理思維。上述處理方法忽略了一個重要的環(huán)節(jié),即 Flink 中算子 state 的保存機制。
在補離線流的時候,由于補充離線任務本身也需要調度時間,導致數據可能無法及時精準的補進去,為了準確的補充離線數據,會多補充一部分數據。在 RANK 算子下發(fā)時,多補的這一部分數據,會導致實時流中的明細數據不過期,即離線數據流跟實時數據流進行合并和排序操作會使實時數據中的原始流過期時間進一步延長,不會下發(fā)對應的明細數據到 join 算子。實際解決是通過利用 Flink 中的處理時間,按照物理明細表的業(yè)務聯合主鍵下發(fā)最后一條數據,主要的解決思路就是深入理解實時計算過程,避免受離線開發(fā)思維影響。
接下來介紹一下基于 Iceberg 的存儲批流一體方案。
主要是將離線處理中的 Hive 和實時處理中的 Talos 全部換成 Iceberg 去處理。選擇 Iceberg 的原因是其對結構化和非結構化數據都有很好的支持。小米有一些非結構化的三方數據以及一些跟谷歌合作的 BQ 埋點日志,這些數據比較復雜,把這些數據存儲在 Iceberg 中會比較方便。Iceberg 支持事務寫,在其變更過程中,不影響下游業(yè)務讀取數據,這方面 Hive 是做不到的。另外小米計算平臺團隊通過 merge into 語法,實現了對 Iceberg 數據的高效修正,使得離線和實時可以高效地相互融合。
但這個方案也存在不足之處,由于 Iceberg 的事務提交依賴 Commit,但是在實時寫入中每次 Commit 的速度會依賴 Checkpoint 設置的時長,所以無法做到秒級別的實時。
四、數倉能力層
下面介紹銷售數倉能力層,即數倉經過一定的建設和升級,逐漸沉淀下來的一些公共能力。
首先是統(tǒng)一的數據架構。準實時數據需求是基于 Iceberg 的分鐘級流批一體處理方案;在實時方面,是基于 Flink + Talos 的秒級處理方案及離線批處理方案。
數倉規(guī)范在數倉能力層中舉足輕重。日常工作中非常重視具體的開發(fā)過程和規(guī)范,尤其是對一些新同學,規(guī)范是必要且實用的。通過數倉開發(fā)和質量規(guī)范,會統(tǒng)一表命名方式、字段命名方式、數倉分層等,配置 DQC 相關的完整性校驗、一致性校驗、空值率校驗。
數據安全是數倉能力建設的一個重要方面。一是通過合規(guī)管控,所有的數據生產環(huán)節(jié)都嚴格遵守國家的法律法規(guī)。在公司內部有質量部、隱私委以及法務部會對所有環(huán)節(jié)進行監(jiān)控。二是會進行安全分類,即按照數據的敏感度和重要性將數據進行分類。三是在權限控制方面,會嚴格規(guī)范數據流程,在每個部門都會有對應的安全負責人來負責最終的安全校驗。在審批過程中,會遵循權限最小的原則。核心研發(fā)人員和使用人員,簽署數據保密協(xié)議。四是集群隔離,小米是一個國際化公司。在國外會將機房部署在當地,并且機房之間的數據明細是不允許傳輸的。對一些匯總的指標,經過安全負責人的審批之后,可以傳回國內進行分析。在歐洲的數據業(yè)務,會嚴格遵守歐盟的 GDPR 條例。針對海外數據,會成立國際數據運營中心,本地開發(fā)部署和運維。
數倉能力建設的一個重要環(huán)節(jié)就是指標應用。具體的指標應用是數據百科,如下圖右側所示,數據百科中包含全部數據口徑的描述、基礎信息、維度的拆解和相關指標。在指標口徑上會嚴格指定權限審批的負責人,明確整個指標的詳情。下游可以通過數據百科,快速了解相關指標。部分指標會和集團數據看板進行聯動,提供給集團的管理者使用。
五、總結與展望
最后進行一下總結和展望。
經過幾年的建設和應用,我們已經基本建成了離線銷售數倉,公司的運營和管理層都在深度且廣泛的使用銷售數倉數據。團隊內部沉淀了數據架構和數倉能力規(guī)范,會不斷與業(yè)界進行交流學習,探索最佳實踐案例。
銷售數倉未來的兩個趨勢,一是數據的價值化,二是指標的實時化。由于目前公司處于快速發(fā)展的過程中,數據部門和業(yè)務需要更緊密地結合,充分挖掘數據的價值,真正將數據的價值體現出來,去賦能業(yè)務,為公司帶來業(yè)績的增長。目前實時化是一個大的趨勢,數據以及業(yè)務的變化,都需要及時體現出來,做到高實時性。
六、問答環(huán)節(jié)
Q1:支付訂單完成訂單之后,可能會發(fā)生周期性退款的問題,正常的 DWD 模型或 DWS 模型通常會存在多分區(qū)表,針對這種類似于多狀態(tài)不斷更新的表,例如有一段退款之后就會發(fā)生歷史回溯修改 DWS 模型,小米是如何解決的?
A1:我們是通過離線的方式去對數據準確性進行修正。在離線里面會跑全量數據,即每次跑的時候是從 ODS 層采集到 DW 層的處理,以及 DM 層,每個分區(qū)里面都是全量數據。這一塊計算會比較重,用來解決狀態(tài)經常變化的問題。
Q2:數據權限一般存儲在哪一層?
A2:我們會有一個平臺部門去負責整體的數據權限,我們在每一層,從ODS到DWD、DWM都會有權限管控。
Q3:物流這塊引入 Kudu 或者 Doris 可以嗎?
A3:目前在部門內部 Kudu 是將要被替換的狀態(tài)。因為 Kudu 是一個相對小眾的產品,運維成本會比較高。我們正在用阿里的 Hologres 去替代 OLAP 引擎,包括Kudu 和 Doris。
目前在我們的離線和實時數據生產中,會使用Doris去加速結果表,我們會把一些中間結果或者最終的匯總數據存到 Doris 里面(主要是匯總數據),之后利用 Doris 的 OLAP 能力去對查詢進行加速。
Q4:DWM 是跨域的寬表嗎?DWD 和 DWM 到底哪個是明細層?
A4:我們將 DWD 和 DWM 統(tǒng)稱為 DW,都是明細層。DWD 主要是進行規(guī)范化,把可能不同的異構數據統(tǒng)一到 DWD 來。在這個過程中除了 ETL、規(guī)劃化、標準化之外,不會進行特別復雜的操作。在 DWM 層我們會加工一些公共的復雜的邏輯。DWM 層也是明細數據,是把多個 DWD 表做關聯,生成的明細寬表。
Q5:DM 層以下的分層會提供給用戶訪問嗎?
A5:我們的 ODS、DWD 以及 TMP 層是不提供外部訪問的,其它層基本都可以對外部提供讀權限。DW 層例如 DWM 是可以提供給外部訪問的。因為 DWM 已經進行了邏輯的封裝,用戶使用 DWM 通過簡單的計算就能得到我們在 DM 中最終得出的指標。
Q6:維度指標是單獨分開存儲的嗎?
A6:不是,我們是存在一塊的。