- 產品
- 產品解決方案
- 行業解決方案
- 案例
- 數據資產入表
- 賦能中心
- 伙伴
- 關于
時間:2022-05-12來源:南風輕拂瀏覽數:952次
數據倉庫是一個面向主題的、集成的、隨時間變化的、信息本身相對穩定的數據集合,用于對管理決策過程的支持。
01 背景
2020年以來,半導體生產不足,這個問題困擾著全世界。互聯網企業高度依賴于網絡基礎設施和服務器設施,沒有半導體就沒有滿足個人需要的個人電子消費品,也就沒有蓬勃發展的互聯網行業。
嗶哩嗶哩作為一家以多媒體內容為核心服務的公司,亦高度依賴于企業級服務器設備,需要大量的服務器設備進行數據計算和數據存儲。芯片荒引起采購周期的延長、采購數量的被動減少,甚至導致設備一機難求。隨著大量人群了解B站、涌入B站、喜歡B站,在B站產生了大量的數據,嗶哩嗶哩對服務器數量的需求越來越高,一增一減之間,數據建設陷入了計算不夠用、存儲不夠用的窘境。
02 數據分析
面臨這種資源緊缺的困難,數據平臺部對主站數倉的數據進行了多維度、全場景的統計分析。經過分類,得出以下四類數據:
日志型數據
業務型數據
手工產出數據
元數據
手工產出數據和元數據對于大數據體系來說,數據量一般很小,對計算資源的需求也不多。數據占比更多的是日志型數據和業務型數據。
對于日志型數據,又分為客戶端日志和服務端日志,但無論哪類日志,一般來說均屬于增量類、靜態類數據,一旦產生即不會對數據本身進行再次變更。
對于業務型數據,主要來源于業務數據庫中的生產數據,即傳統的會進行DDL、DML等操作的數據,會頻繁的進行增刪改查。在數據倉庫使用時,需要計算出最新狀態,供下游使用。
03?全量分區表模式
經過對以上幾類典型數據的調研和分析,并和各個互聯網企業進行溝通和咨詢,我們發現整個互聯網行業,大量企業采用Ralph Kimall大師的維度建模方法論為指導。對于業務型數據,為了便于ETL使用、便于分析使用,基本上都做成全量分區表的模式。
對于剛剛開始建設數據倉庫的團隊,一般會永久保存,如果受限于存儲容量,會寫crontab任務定期刪除最早的歷史分區。對于數據倉庫建設成熟的團隊,一般會有專門的數據治理團隊負責數據的治理,對接數據開發同學確定數據的生命周期,并對全量分區表制定自動化策略,命中策略后自動刪除數據。
全量分區表:
表按照T-1進行創建分區,分區值一般為數據生產時的昨天,如數據在2022-02-26 01:02:03.456生產完成,則分區值為2022-02-25;每個分區存儲自數據生產當日00:00:00.000以前的全量數據,即2022-02-26 00:00:00.000以前的全量數據。
目前,嗶哩嗶哩數據平臺部已步入成熟的數據建設階段,也會有專門的數據治理團隊進行治理,把全量分區表的生命周期配置為永久或固定時間周期,在資源充足的背景下,數據倉庫開發生產數據、下游任務消費數據均簡單和成熟,業內也都是這么做的。
但是當資源緊張時,這種模式的缺點會被快速放大:
數據存儲浪費嚴重。
對于沒有變化的數據,數據在全量分區表的每一份分區中都存儲一份,會存在重復存儲問題,當數據變化率低時重復存儲比例大大增大。
數據存在丟失的問題
這與數據倉庫的基本理念不符。如果定期刪除全量分區表的最早歷史分區,在進行數據分析時,無法滿足“隨時間變化的”、“ 信息本身相對穩定的”。
數據倉庫是一個面向主題的、集成的、隨時間變化的、信息本身相對穩定的數據集合,用于對管理決策過程的支持。
針對以上場景,從技術上考量,第一種方案是上文所述的全量分區表,按照離線模式T-1同步增量數據到數據倉庫,然后T-2的全量數據并上T-1的增量數據,生產出最新的T-1全量數據,整個鏈路均為離線鏈路。具有時效低、性能高、吞吐大的特點。

SQL偽代碼如下:
insert?overwrite?table?目?標?表?partition?(分?區?=?昨?天)select??字?段?列?表from(????select??????字?段?列?表,??????row_number()?over(????????partition?by?主?鍵?列?表????????order?by??????????更?新?字?段?desc??????)?as?rn????from??????(????????select??????????字?段?列?表????????from??????????增?量?表????????where??????????分?區?=?昨?天????????union?all????????select??????????字?段?列?表????????from??????????全?量?表????????where??????????分?區?=?前?天??????)?n??)?twhere??rn?=?1第二種方案是現階段很熱的數據湖,比如Hudi,結合Flink CDC,基于Mysql的binlog實時記錄收集數據新增、更新等信息,實時更新數據到最新狀態。
在初始化時,以離線模式批量從數據庫中拉取全量數據,初始化到Hudi表中;訂閱數據庫的增量數據,增量更新到Hudi表中。數據以分鐘級的延遲和數據庫保持完全一致。

具有時效高、性能中、吞吐中的特點。經過基準性能測試,日新增、變更低于1000萬條的數據,使用Hudi+Flink CDC可以較好的實現數據的合并,生產出數據的準實時數據。對于數據的歷史所有變更的全版本存儲功能現有社區功能還需要繼續完善。
從業務上考量,第三種方案是數據倉庫模型設計上拉鏈表的概念,通過記錄歷史所有數據的狀態和數據的生命周期,保留所有的數據快照。從語義上和技術實現上來看,這和第一種方案的全量分區表可以保證完全一致,數據可以做全等校驗和檢測,下游用戶遷移時,可以無縫進行遷移,縮短全量分區表的生命周期時,下游用戶無感知。

04 基于拉鏈表的全量表優化方案
基于以上幾種方案,數據團隊和技術團隊經過多次的溝通和討論,推進第二種方案Hudi + Flink CDC和第三種方案拉鏈表支持研發。
Hudi+Flink CDC用于支持新型準實時需求類需求,對于時效性要求高的需求,比如需要分鐘級的延遲,以Hudi+Flink CDC進行支持。
拉鏈表方案做存量全量分區表的無縫遷移,和支持離線T-1類的時效性要求較低的需求,以及需要歷史所有變更的全版本下的支持。
拉鏈表:針對數據倉庫設計中表存儲數據的方式而定義的一種存儲規范,顧名思義,所謂拉鏈,就是記錄歷史。記錄一個事物從開始,一直到當前狀態的所有變化的信息。
假設我們有一份用戶表,里面有兩個字段,第一個是用戶ID,每個用戶唯一且不變,第二個字段是用戶昵稱,用戶可以自己任意更新自己的昵稱。
經過對數據重復率和數據覆蓋率測試,對比一年前的用戶數據和最新的用戶數據,重復率為9990?(萬分之)。即一年前的數據經過一年后,僅有10?進行了變更。對于這種重復率的數據,我們可以對全量分區表拉鏈表化。
基于本項目對一份數據進行了拉鏈化測試,之前數據量1.20PB,拉鏈化后降低到5.06TB,優化率99.578%;每日產出任務的IO資源消耗由6.11TB+7.60GB降低到5.06TB+7.60GB,IO和計算資源的優化率均為17.16%。
拉鏈表生產的數據樣例如下:

生產此拉鏈表的SQL為:
INSERT?OVERWRITE?TABLE?拉鏈表SELECT??n1.id,??n1.昵稱,??n1.start_date,??CASE????WHEN?n1.end_date?=?'9999-12-31'????AND?n2.id?IS?NOT?NULL?THEN?'業務日期-1'????ELSE?n1.end_date??END?AS?end_dateFROM?拉鏈表?n1LEFT?OUTER?JOIN???(SELECT?id?FROM?用戶表??WHERE?昨日新注冊?OR?昨日變更昵稱)?n2?ON?n1.id?=?n2.idUNION?ALLSELECT?id,?昵稱,?'業務日期'?as?start_date,?'9999-12-31'?as?end_dateFROM?用戶表WHERE?昨日新注冊?OR?昨日變更昵稱關于這個sql:

經過上述加工,可以生產出一份反應歷史數據變化的拉鏈表數據。雖說大大降低了存儲,但是有沒有方案不增加增量數據的讀取次數,且不增加任務數?通過對拉鏈表的生產邏輯進行了深入分析,僅僅靠SQL是無法達到目的的,需要開發一個通用型的技術方案,下面講述一下我們的思路,由于大數據系統最早以MapReduce發展起來的,本文所述的技術方案以MapReduce為基本框架,歡迎大家一起交流。
整個MapReduce的數據流如下:

上述MR生產拉鏈表數據時,相對于傳統的拉鏈表生產SQL,僅需要一個任務、讀取一次拉鏈表、讀取一次增量數據,且不需要單獨增加一步排序的步驟。在節省存儲資源的同時,又能節省計算資源。
05 總結
對全量分區表進行拉鏈化,優化的技術方案不僅能降低存儲,而且還能降低一定的計算資源。
后續我們會和大家聊聊如何進行拉鏈表的冪等化,如何高效地對數據進行覆蓋率和重復率測試,預估全量分區表拉鏈化的收益以及有選擇性地優化全量分區表等內容。