作者介紹
@車云祥
大宇無限 資料產品負責人
主要負責全公司底層資料治理,構建統一指標體系;
主導 BI 系統、用戶畫像系統、廣告投放平臺、廣告流量優化等設計作業;
推動 Snaptube、LarkPlayer、Zapee 等明星產品與資料緊密結合,實作高效運轉;通過對業務需求深度梳理、資料方案高質量設計、資料分析洞察與優化、營銷策略倍訓輸出的不斷實踐,幫助公司實作資料驅動業務增長;
“資料人創作者聯盟”成員,
01 數倉架構演變
20世紀70年代,MIT(麻省理工)的研究員致力于研究一種優化的技術架構,該架構試圖將業務處理系統和分析系統分開,即將業務處理和分析處理分為不同層次,針對各自的特點采取不同的架構設計原則,MIT的研究員認為這兩種資訊處理的方式具有顯著差別,以至于必須采取完全不同的架構和設計方法,但受限于當時的資訊處理能力,這個研究僅僅停留在理論層面,
1991年,比爾·恩門(Bill Inmon)出版了他的第一本關于資料倉庫的書《Building the Data Warehouse》,標志著資料倉庫概念的確立,該書定義了資料倉庫非常具體的原則,這些原則到現在仍然是指導資料倉庫建設的最基本原則,比爾·恩門(Bill Inmon)主張自上而下的建設企業級資料倉庫EDW (Enterprise Data Warehouse),這個程序中資訊存盤符合第三范式,結構如下:

由于企業級資料倉庫的設計、實施很困難,很重要的原因是因為其資料模型設計,在企業級資料倉庫中,Inmon推薦采用3范式進行資料建模,從而無法支持決策支持(DSS -Decision Suport System )系統的性能和資料易訪問性的要求,即:資料存盤方式嚴格按照范式建模方式,導致資料分析效率低下,很多公司按照這種方式構建資料倉庫遭到失敗,
同時期,拉爾夫·金博爾(Ralph Kimball)提出自下而上的建立資料倉庫,整個程序中資訊存盤采用維度建模而非三范式,思路如下:

維度建模方式沒有采用三范式方式設計存盤資料,適用于資料分析場景,以上設計方式構建資料倉庫實施難度大大降低,并且能夠滿足公司內部部分業務部門的迫切需求,在初期獲得了較大成功,但是很快,他們也發現自己陷入了某種困境:隨著資料集市的不斷增多,這種架構的缺陷也逐步顯現,公司內部獨立建設的資料集市由于遵循不同的標準和建設原則,以致多個資料集市的資料混亂和不一致,解決以上問題,還需回歸到范式建模,
1998年,Bill Inmon提出了新的BI架構CIF(Corporation information factory),CIF的核心是將數倉架構劃分為不同的層次以滿足不同場景的需求,比如常見的ODS、DW、DM等,每層根據實際場景采用不同的建設方案,現在CIF已經成為建設資料倉庫的框架指南,
隨著時代的發展,到今天資料倉庫建設理論也是基于CIF架構建設方案演化而來,同時資料倉庫的概念越來越精確,資料倉庫定義如下:
資料倉庫,Data Warehouse,可簡寫為DW或DWH,資料倉庫是面向主題的、集成的(非簡單的資料堆積)、相對穩定的、反應歷史變化的資料集合,數倉中的資料是有組織有結構的存盤資料集合,用于對管理決策程序的支持,

01 傳統離線大資料架構
21世紀初隨著互聯網時代的到來,資料量暴增,大資料時代到來,Hadoop生態群及衍生技術慢慢走向“舞臺”,Hadoop是以HDFS為核心存盤,以MapReduce(簡稱MR)為基本計算模型的批量資料處理基礎設施,圍繞HDFS和MR,產生了一系列的組件,不斷完善整個大資料平臺的資料處理能力,例如面向KV操作的HBase、面向SQL分析的Hive、面向作業流的PIG等,以Hadoop為核心的資料存盤及資料處理技術逐漸成為資料處理中的“中流砥柱”,部分技術堆疊如下圖所示:

這個時期,在企業資訊化的程序中,隨著資訊化工具的升級和新工具的應用,資料量變的越來越大,資料格式越來越多,決策要求越來越苛刻,資料倉庫技術在大資料場景中被廣泛使用,大資料中的資料倉庫構建就是基于經典數倉架構而來,使用大資料中的工具來替代經典數倉中的傳統工具,架構建設上沒有根本區別,在離線大資料架構中離線數倉結構如下:

隨著資料處理能力和處理需求的不斷變化,越來越多的用戶發現,批處理模式無論如何提升性能,也無法滿足一些實時性要求高的處理場景,流式計算引擎應運而生,例如Storm、Spark Streaming、Flink等,
以上離線大資料架構不能夠處理實時性業務,早期,很過公司都是基于Storm來處理處理實時性比較強的業務場景,隨著越來越多的應用上線,大家發現,其實批處理和流計算配合使用,才能滿足大部分應用需求,而對于用戶而言,其實他們并不關心底層的計算模型是什么,用戶希望無論是批處理還是流計算,都能基于統一的資料模型來回傳處理結果,于是Lambda架構被提出,
02 Lambda架構
在Lambda架構中,為了計算一些實時指標,就在原來的離線數倉基礎之上增加了一個實時計算的鏈路,并對資料源做流式改造:把訊息發送到訊息佇列中(大資料中常用Kafka),實時計算去消費訊息佇列中的資料,完成實時指標計算,推送到下游的資料服務中去,由資料服務層完成離線與實時結果的合并,
Lambda架構中資料從底層的資料源開始,經過各種各樣的格式進入大資料平臺,在大資料平臺中經過Kafka、Flume等資料組件進行收集,然后分成兩條線進行計算,一條線是進入流式計算平臺(例如 Storm、Flink或者Spark Streaming),去計算實時的一些指標,保證資料實時性;另一條線進入批量資料處理離線計算平臺(例如Mapreduce、Hive,Spark SQL),去計算T+1的相關業務指標,這些指標需要隔日才能看見,保證資料有效、準確性,
根據實時業務統計的復雜程度Lambda架構也分為以下兩種情況,
-
離線資料+實時處理鏈路(傳統實時開發)
根據實時鏈路中實時指標計算的復雜程度,開始實時業務不復雜,都是“煙囪(cong)式”開發設計,不需要構建實時數倉,我們可以選擇不分層,這種場景下Lambda架構中是由離線數倉和實時業務處理部分組成,這部分實時還達不到叫做實時數倉階段,只能叫做實時處理鏈路,其結構如下:


注意:“煙囪式”開發:在一個有一定規模的企業中,通常都會存在各種各樣的應用系統,它們分別由企業的各個不同部門、在各種不同歷史時期、為滿足各種不同業務目的而開發,由于資料格式沒有統一規范,相互之間沒有聯通、資料更沒有整合,像一個個煙囪,因此稱其為“煙囪式系統”,同樣,在資料處理程序中,各個資料處理程式之間不能很好做到資料規范統一、處理資料流程統一、資料復用,各自獨立,叫做“煙囪式”開發,
-
離線數倉+實時數倉
隨著企業實時業務增多,統計的實時指標越來越多,復雜程度也越來越高,為了在實時鏈路中更好的復用資料,這是就有必要在實時鏈路中加入資料分層設計,構建真正的實時數倉,這種場景下Lambda架構中是由離線數倉和實時數倉兩部分組成,其結構如下:

以上Lambda架構中“實時處理鏈路”這種傳統實時與“實時數倉”區別在于,傳統實時“煙囪式”開發導致代碼耦合問題嚴重,當需求越來越多,有時需要明細資料,有時需要OLAP分析,這種模式難以應付這些需求,缺少完善的規范,“實時數倉”在保證資料實時性的前提下,實作了資料基于資料倉庫管理,更加統一規范化,穩定性和業務性更強,
在Lambda架構中流處理計算的指標批處理依然計算,最終以批處理結果為準,即每次批處理計算后會覆寫流處理的結果,這是由于流處理程序中不完善做的折中辦法,由資料服務處理,其功能主要是合并離線計算和實時計算結果,例如:在統計實時交易訂單時,可能實時統計的結果需要當日分鐘級別向外展示,T+1后才能展示昨日總的交易訂單數,顯然,后者是T+1每日離線批處理統計結果,那么假設當日有些用戶進行了訂單取消有可能T+1后統計統計結果與當日實時展示資料出現不一致問題,那么這里就需要使用資料服務來進行處理,統一資料,決定如何使用資料,
Lambda資料架構成為每一個公司大資料平臺必備的架構,它解決了一個公司大資料批量離線處理和實時資料處理的需求,Lambda架構的核心理念是“流批一體”,如上圖所示,整個資料流向自左向右流入平臺,進入平臺后一分為二,一部分走批處理模式,一部分走流式計算模式,無論哪種計算模式,最終的處理結果都通過統一服務層對應用提供,確保訪問的一致性,底層到底是批或流對用戶透明,經歷多年的發展,Lambda架構優點是穩定,對于實時計算部分的計算成本可控,批量處理可以用晚上的時間來整體批量計算,這樣把實時計算和離線計算高峰分開,但是它也有一些致命缺點:
1)同樣的需求需要開發兩套一樣的代碼
這是Lambda架構最大的問題,針對同一個需求需要開發兩套代碼,一個在批處理引擎上實作,一個在流處理引擎上實作,在寫好代碼后還需構造資料測驗保證兩者結果一致,另外,兩套代碼對于后期維護也非常麻煩,一旦需求變更,兩套代碼都需要修改,并且兩套代碼也需同時上線,
2)集群資源使用增多
同樣的邏輯需要計算兩次,整體占用資源會增多,雖然離線部分是在凌晨運行,但是有可能任務多,在凌晨時造成集群資源使用暴增,報表產出效率就有可能下降,報表延遲對后續展示也有影響,
3)離線結果和實時結果不一致
在此架構中經常我們看到次日統計的結果比昨晚的結果要少,原因就在于次日統計結果和昨日統計結果走了兩條線的計算方式:次日統計結果是按照批處理得到了更為準確的批量處理結果,昨晚看的結果是通過流式運行的結果,依靠實時鏈路統計出的實時結果(實時結果統計累加),犧牲了部分準確性,對于這種來自批量和實時的資料結果對不上的問題,無解,
4)批量計算T+1可能計算不完
隨著物聯網時代的到來,一些企業中資料量級越來越大,經常發現夜間運行批量任務已經無法完成白天20多個小時累計的資料,保證早上上班前準時出現資料已成為部分大資料團隊頭疼的問題,
5)服務器存盤大
由于批流兩個程序都需要將資料存盤在集群中,并且中間也會產生大量臨時資料,會造成資料急速膨脹,加大服務器存盤壓力,
03 Kappa架構
隨著Flink等流式處理引擎的不斷完善,流處理技術相關的技術成熟發展(例如:Kafka、ClickHouse),針對Lambda架構的需要維護兩套程式等以上缺點,LinkedIn的Jay Kreps結合實際經驗和個人體會提出了Kappa架構,
Kappa架構的核心思想是通過改進流計算系統來解決資料全量處理的問題,使得實時計算和批處理程序使用同一套代碼,此外Kappa架構認為只有在有必要的時候才會對歷史資料進行重復計算,而如果需要重復計算時,Kappa架構下可以啟動很多個實體進行重復計算,方式是通過上游重放完成(從資料源拉取資料重新計算),
Kappa架構就是基于流來處理所有資料,流計算天然的分布式特征,注定了他的擴展性更好,通過加大流計算的并發性,加大流式資料的“時間視窗”,來統一批處理與流式處理兩種計算模式,其架構如下:

Kappa架構構建的數倉當之無愧稱為實時數倉,Kappa架構最大的問題是流式重新處理歷史的吞吐能力會低于批處理,但這個可以通過增加計算資源來彌補,重新處理資料看似比較麻煩,但在Kappa架構中并不復雜,其步驟如下:

-
選擇一個具有重放功能,能夠保存歷史資料的訊息佇列,根據要求設定歷史資料保存時長,例如:Kafka,可以設定保存全部歷史資料,
-
當某個或某些指標有重新處理的需求時,按照新邏輯撰寫新的作業,然后從上游訊息佇列最開始地方重新消費資料,把結果寫往一個新的下游結果表,
-
當新作業趕上進度后,切換資料源,讀取新作業產生的結果表,
-
停止老的作業,洗掉老的結果表,
另外,Kappa 架構并不是中間結果完全不落地,現在很多大資料系統都需要支持機器學習(離線訓練),所以實時中間結果需要落地對應的存盤引擎供機器學習使用,另外有時候還需要對明細資料查詢,這種場景也需要把實時明細層寫出到對應的引擎中,
Kappa架構也有一定的缺點,其缺點例如:Kappa架構由于采集的資料格式不統一,每次都需要開發不同的Streaming程式,導致開發周期長,更多Kappa架構的問題在實時數倉發展趨勢中討論,
04 混合結構
傳統離線大資料架構已經不能滿足一些公司中實時業務需求,因為隨著互聯網及物聯網發展,越來越多的公司多多少少涉及一些流式業務處理場景,由Lambda離線數倉+實時數倉架構到Kappa實時數倉架構,都涉及到實時數倉開發,那么現實業務開發中到底使用Lambda架構還是Kappa架構?
我們可以先看下以上三個架構之間的區別:

通過以上對比來看,三者對比結果如下:
從架構上來看,三套架構有比較明顯區別,真正的實時數倉以Kappa架構為主,而離線數倉以傳統離線大資料架構為主,Lambda架構可以認為是兩者的中間態,目前在業界中所說的實時數倉大多是Lambda架構,這是由需求決定的,
從建設方法上來看,實時數倉和離線數倉基本還是沿用傳統的數倉主題建模理論,產出事實寬表,另外實時數倉中實時流資料的join有隱藏時間語意,在建設中需注意,
從資料保障上來看,實時數倉因為要保證實時性,所以對資料量的變化較為敏感,在大促等場景下需要提前做好壓測和主備保障作業,這是與離線數倉較為明顯的一個區別,
目前在一些沒有實時資料處理場景公司中,使用傳統離線大資料架構居多,在這些公司中離線大資料架構性價比高,比較實用,
在一些涉及到實時業務場景的公司,在實際作業中到底選擇哪種架構,需要根據具體業務需求來決定,很多時候并不是完全規范的Lambda架構或者Kappa架構,可以是兩者的混合,比如大部分實時指標統計使用Kappa架構完成計算,少量關鍵指標使用Lambda架構用批處理重新計算,增加一次校對程序,為了應對更廣泛的場景,大多數公司采用這種混合架構,離線和實時資料鏈路都存在,根據每個業務需求選擇在合適的鏈路上來實作,注意:這種方式并不是Lambda架構,例如:某企業有多個業務模塊,某些業務模塊需要運行在Lambda架構中,某些業務模塊需要運行在Kappa架構中,
02 離線數倉與實時數倉區別
離線資料與實時數倉區別如下:

03 實時數倉建設思路
在實時數倉中計算框架選型建議優先選擇Flink,其具有“流批一體”特性,并且在處理復雜業務場景上性能優異,在實時處理中有逐漸替代spark的趨勢,
在實時數倉分層方面,實時數倉可采用離線數倉的資料模型進行分層處理,目前建議選擇Kafka,實時數倉的資料來源可以為kafka訊息佇列,這樣可以做到佇列中的資料既可以寫入HDFS用于批量分析,也可以實時處理,下游可以寫入資料集市供業務使用,如果實時資料量不大也可以將實時明細層寫入ClickHouse、Druid等查詢效率高的存盤方便下游使用,輕度匯總層對資料進行匯總分析后供下游使用,
在資料存盤選型中首要考慮查詢效率,其次是插入、更新等問題,這里說的存盤時最終計算資料結果的存盤,可選擇ClickHouse、Hbase、apache Druid、Redis等,頻繁更新的資料建議不要采用ClickHouse與Druid,當然存盤這塊需要具體問題具體分析,不同場景下hbase、redis等都是可選項,
04 實時數倉發展趨勢
01 實時數倉現狀
當前基于Hive的離線資料倉庫已經非常成熟,隨著實時計算引擎的不斷發展以及業務對于實時報表的產出需求不斷膨脹,業界最近幾年就一直聚焦并探索于實時數倉建設,根據數倉架構演變程序,在Lambda架構中含有離線處理與實時處理兩條鏈路,其架構圖如下:

正是由于兩條鏈路處理資料導致資料不一致等一些列問題所以才有了Kappa架構,Kappa架構如下:

Kappa架構可以稱為真正的實時數倉,目前在業界最常用實作就是Flink + Kafka,然而基于Kafka+Flink的實時數倉方案也有幾個非常明顯的缺陷,所以在目前很多企業中實時數倉構建中經常使用混合架構,沒有實作所有業務都采用Kappa架構中實時處理實作,Kappa架構缺陷如下:
-
Kafka無法支持海量資料存盤,
對于海量資料量的業務線來說,Kafka一般只能存盤非常短時間的資料,比如最近一周,甚至最近一天,
-
Kafka無法支持高效的OLAP查詢,大多數業務都希望能在DWD\DWS層支持即席查詢的,但是Kafka無法非常友好地支持這樣的需求,
-
無法復用目前已經非常成熟的基于離線數倉的資料血緣、資料質量管理體系,
需要重新實作一套資料血緣、資料質量管理體系,
-
Kafka不支持update/upsert,目前Kafka僅支持append,
實際場景中在DWS輕度匯聚層很多時候是需要更新的,DWD明細層到DWS輕度匯聚層一般會根據時間粒度以及維度進行一定的聚合,用于減少資料量,提升查詢性能,
假如原始資料是秒級資料,聚合視窗是1分鐘,那就有可能產生某些延遲的資料經過時間視窗聚合之后需要更新之前資料的需求,
這部分更新需求無法使用Kafka實作,
所以實時數倉發展到現在的架構,一定程度上解決了資料報表時效性問題,但是這樣的架構依然存在不少問題,隨著技術的發展,相信基于Kafka+Flink的實時數倉架構也會進一步往前發展,那么到底往哪些方向發展,我們可以結合大公司中技術選型可以推測實時數倉的發展大致會走向“批流一體”,
02 批流一體
最近一兩年中和實時數倉一樣火的概念是“批流一體”,那么到底什么是“批流一體”?在業界中很多人認為批和流在開發層面上都統一到相同的SQL上處理是批流一體,也有一些人認為在計算引擎層面上批和流可以集成在同一個計算引擎是批流一體,比如:Spark/SparkStreaming/Structured Streaming/Flink框架在計算引擎層面上實作了批處理和流處理集成,
以上無論是在業務SQL使用上統一還是計算引擎上的統一,都是批流一體的一個方面,除此之外,批流一體還有一個最核心的方面就是存盤層面上的統一,這個方面上也有一些流行的技術:delta/hudi/iceberg,存盤一旦能夠做到統一,例如:一些大型公司使用Iceberg作為存盤,那么Kappa架構中很多問題都可以得到解決,Kappa架構將變成個如下模樣:

這條架構中無論是流處理還是批處理,資料存盤都統一到資料湖Iceberg上,這一套結構將存盤統一后,解決了Kappa架構很多痛點,解決方面如下:
-
可以解決Kafka存盤資料量少的問題,
目前所有資料湖基本思路都是基于HDFS之上實作的一個檔案管理系統,所以資料體量可以很大,
-
DW層資料依然可以支持OLAP查詢,
同樣資料湖基于HDFS之上實作,只需要當前的OLAP查詢引擎做一些適配就可以進行OLAP查詢,
-
批流存盤都基于Iceberg/HDFS存盤之后,就完全可以復用一套相同的資料血緣、資料質量管理體系,
-
實時資料的更新,
上述架構也可以認為是Kappa架構的變種,也有兩條資料鏈路,一條是基于Spark的離線資料鏈路,一條是基于Flink的實時資料鏈路,通常資料都是直接走實時鏈路處理,而離線鏈路則更多的應用于資料修正等非常規場景,這樣的架構要成為一個可以落地的實時數倉方案、可以做到實時報表產生,這得益于Iceberg技術:
-
支持流式寫入-增量拉取
流式寫入其實作在基于Flink就可以實作,無非是將checkpoint間隔設定的短一點,比如1分鐘,就意味每分鐘生成的檔案就可以寫入到HDFS,這就是流式寫入,但是這里有兩個問題,第一個問題是小檔案很多,但這不是最關鍵的,第二個問題才是最致命的,就是上游每分鐘提交了很多檔案到HDFS上,下游消費的Flink是不知道哪些檔案是最新提交的,因此下游Flink就不知道應該去消費處理哪些檔案,這個問題才是離線數倉做不到實時的最關鍵原因之一,離線數倉的玩法是說上游將資料全部匯入完成了,告訴下游說這波資料全部導完了,你可以消費處理了,這樣的話就做不到實時處理,
資料湖就解決了這個問題,實時資料鏈路處理的時候上游Flink寫入的檔案進來之后,下游就可以將資料檔案一致性地讀走,這里強調一致性地讀,就是不能多讀一個檔案也不能少讀一個檔案,上游這段時間寫了多少檔案,下游就要讀走多少檔案,我們稱這樣的讀取叫增量拉取,
-
解決小檔案多的問題
資料湖實作了相關合并小檔案的介面,Spark/Flink上層引擎可以周期性地呼叫介面進行小檔案合并,
-
支持批量以及流式的Upsert(Delete)功能
批量Upsert/Delete功能主要用于離線資料修正,流式upsert場景上文介紹了,主要是流處理場景下經過視窗時間聚合之后有延遲資料到來的話會有更新的需求,這類需求是需要一個可以支持更新的存盤系統的,而離線數倉做更新的話需要全量資料覆寫,這也是離線數倉做不到實時的關鍵原因之一,資料湖是需要解決掉這個問題的,
-
支持比較完整的OLAP生態
比如支持Hive/Spark/Presto/Impala等OLAP查詢引擎,提供高效的多維聚合查詢性能,
目前Iceberg部分功能還在開發中,有一些功能還不完善,但是整體實時數倉的發展會大致朝著這個方向行進,目前業界大多數公司還是處于Lambda架構,使用Kappa架構的公司一般都是實時業務居多的公司,隨著資料湖技術的發展,這些公司實時數倉的構建慢慢會走向最終的“批流一體”,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/434510.html
標籤:其他
