|0x00 從實時數(shù)倉的歷史談起
實時數(shù)倉的歷史行剂,有三個顯著的分水嶺钳降。
第一個分水嶺是從無到有,隨著以Storm為代表的實時計算框架出現(xiàn)遂填,大數(shù)據(jù)從此擺脫了MapReduce單一的計算方式,有了當(dāng)天算當(dāng)天數(shù)據(jù)的能力备燃。
第二個分水嶺是是從有到全凌唬,以Lambad和Kappa為代表的架構(gòu)漏麦,能夠?qū)崟r與離線架構(gòu)結(jié)合在一起,一套產(chǎn)品可以實現(xiàn)多種數(shù)據(jù)更新策略更耻。
第三個分水嶺是從全到簡捏膨,以Flink為代表的支持窗口計算的流式框架出現(xiàn)食侮,使離線和實時的邏輯能夠統(tǒng)一起來目胡,一套代碼實現(xiàn)兩種更新策略,避免了因為開發(fā)方式不統(tǒng)一導(dǎo)致的數(shù)據(jù)不一致問題誉己。
未來會有第四個分水嶺,就是從架構(gòu)走向工具噪猾,以Hologres為代表的HSAP引擎筑累,用服務(wù)分析一體化的設(shè)計理念,極有可能徹底統(tǒng)一掉分析型數(shù)據(jù)庫和業(yè)務(wù)數(shù)據(jù)庫疼阔,再配合Flink,真正實現(xiàn)數(shù)倉的徹底實時化迅细。未來不再存在離線和實時的區(qū)分淘邻,F(xiàn)link + Hologres,用一套結(jié)構(gòu)统阿、一套產(chǎn)品筹我,就完事了。
過去蔬蕊,面對實時,數(shù)倉的邏輯是:性能不夠麻献,架構(gòu)來補猜扮;
現(xiàn)在,面對實時齿桃,數(shù)倉的邏輯是:既要、還要短纵、全都要。
過去刮刑,我們使用OLAP引擎养渴,是為了更快的查詢數(shù)據(jù);
現(xiàn)在翘紊,我們使用OLAP引擎藐唠,是為了當(dāng)線上業(yè)務(wù)庫,替代Mysql用宇立。
當(dāng)我們覺得摩爾定律要失效時,它卻仍然在發(fā)展柳琢。當(dāng)我們覺得數(shù)倉架構(gòu)定型時润脸,它卻依然在高速演化。只有了解歷史倒堕,才能看清未來爆价,我想重新了解一下Lambda/Kappa/Flink的歷史,熟悉架構(gòu)的演進允坚,以此來探討實時數(shù)倉建設(shè)的一些問題稠项。
本人才學(xué)疏淺鲜结,很多細節(jié)恐怕不能講的非常清楚活逆,有更多想法的拗胜,歡迎添加微信:xiaoyang_gai,咱們繼續(xù)聊锈遥。
我們先從Lambda的歷史講起勘畔。
|0x01 Lambda
對低成本規(guī)模化的數(shù)據(jù)服務(wù)炫七,以及盡可能低延遲的數(shù)據(jù)應(yīng)用,是推動Lambda架構(gòu)誕生的原動力侠驯。
早期的Storm框架奕巍,能夠幫助解決低延遲的問題,但這個框架并不完美踊挠,其中一個痛點,便是Storm無法支持基于時間窗口的邏輯處理冲杀,這導(dǎo)致實時流無法計算跨周期的邏輯,用戶不得不尋找一些額外的方法來實現(xiàn)剩檀。為了解決痛點旺芽,Storm的作者Nathan Marz,提出了一種混合計算的方式运嗜,通過批量MapReduce提供離線結(jié)果悯舟,同時通過Storm提供最新的數(shù)據(jù),這種離線與實時混合的框架奋救,就是如今廣為流傳的“Lambda架構(gòu)”。
亞馬遜上有一本《Big Data: Principles and best practices of scalable realtime data systems》演侯,就是Nathan Marz用來詳細闡述Lambda架構(gòu)的背亥,而最重要的圖,就是下面這張:
Lambda架構(gòu)通過兩條分支來整合實時計算和離線計算, 一條叫Speed Layer程癌,用于提供實時數(shù)據(jù), 另一條叫作Batch Layer & Serving Layer轴猎,用于處理離線的數(shù)據(jù)。
為什么這么設(shè)計呢锐峭?在深入理解Lambda之前可婶,我們首先了解一下數(shù)據(jù)系統(tǒng)的本質(zhì),主要有兩個:一個是數(shù)據(jù)椎扬,另一個是查詢具温。
數(shù)據(jù)的本質(zhì),主要體現(xiàn)在三個方面:
- when:數(shù)據(jù)的時間特性揖铜,對于分布式系統(tǒng)而言达皿,這個特別重要,因為時間決定了數(shù)據(jù)發(fā)生的先后順序龄寞,也決定了數(shù)據(jù)計算的先后順序汤功;
- what:數(shù)據(jù)的內(nèi)容特性,數(shù)據(jù)本身是不可變的拂封,分布式系統(tǒng)對數(shù)據(jù)的操作鹦蠕,可以簡化為兩點:讀取和新增,也就是Create和Read萧恕,而Update和Delete可以用Create來替代肠阱;
- where:數(shù)據(jù)的存儲特性,基于分布式系統(tǒng)數(shù)據(jù)不可變的特性走趋,存儲數(shù)據(jù)只需要進行添加即可噪伊,系統(tǒng)的邏輯設(shè)計會更加簡單,容錯性也可以大幅度提升姨伟。
查詢的本質(zhì)豆励,特指一個公式:Query = Function(All Data)。
表面的意思是技扼,不論數(shù)據(jù)是存在Mysql這種RDBMS的嫩痰,還是MPP類型的,或者是OLAP和橙、OLTP造垛,甚至是文件系統(tǒng),都能夠支持查詢办斑。
更深入一點,意味著數(shù)據(jù)的查詢鳞疲,要支持Monoid特性蠕蚜,例如整數(shù)的加法就要支持:(a+b)+c=a+(b+c)。
概念本身比較抽象腺毫,這里只需要了解挣柬,如果函數(shù)滿足Monoid特性,那么計算時就可以支持分散到多臺計算機急黎,進行并行計算侧到。
了解了數(shù)據(jù)系統(tǒng)的本質(zhì),我們再看實時架構(gòu)荣回,我們就發(fā)現(xiàn)戈咳,如何在平衡性能和資源消耗的基礎(chǔ)上,滿足Query = Function(All Data)的特性删铃,就是Lambda架構(gòu)設(shè)計的精髓踏堡。
離線數(shù)據(jù)能夠支持龐大數(shù)據(jù)量的計算,耗時長诫隅,但處理的數(shù)據(jù)量大帐偎,適合歷史數(shù)據(jù)的處理削樊。并且兔毒,因為我們不能避免系統(tǒng)或者人為發(fā)生的錯誤甸箱,那么離線方案對于結(jié)果的兜底,要遠優(yōu)于實時方案豪嗽,任何問題都可以通過邏輯的修正围小,來得到最終正確的結(jié)果树碱。所以查詢應(yīng)該是:
batch view=function(all data)
而實時數(shù)據(jù)要支持實時的部分成榜,為了實現(xiàn)低延遲的特性,勢必要減少計算的數(shù)據(jù)量赎婚,那么只針對增量的做處理,作為對離線處理的補充挣输,就是一種最優(yōu)的方案撩嚼。這里查詢就變成了:
realtime view=function(realtime view,new data)
而最終的結(jié)果完丽,因為要支持歷史+實時數(shù)據(jù)的查詢逻族,所以需要合并前面的兩個結(jié)果集。如果我們的查詢函數(shù)滿足Monoid性質(zhì)的話薄辅,只需要簡單合并兩個流的數(shù)據(jù)抠璃,就能得到最終的結(jié)果。所以:
query=function(batch view, realtime view)
總結(jié)下來源请,Lambda架構(gòu)就是如下的三個等式:
batch view = function(all data)
realtime view = function(realtime view, new data)
query = function(batch view, realtime view)
這么設(shè)計的優(yōu)點,Nathan Marz也進行了總結(jié)舅踪,最重要的有三條良蛮,即:
- 高容錯:對于分布式系統(tǒng)而言,機器宕機是很普遍的情況货徙,因此架構(gòu)的設(shè)計需要是非常健壯的皮胡,即便是機器跪了屡贺,任務(wù)也要能正常執(zhí)行。除此之外泻仙,由于人的操作也很容易出現(xiàn)問題量没,因此系統(tǒng)的復(fù)雜性要控制在一定的程度內(nèi)。復(fù)雜度越高究抓,出錯概率越大饶套。
- 低延遲:實時計算對于延遲的要求很高,對應(yīng)的系統(tǒng)讀操作和寫操作應(yīng)該是低延遲的怠李,對系統(tǒng)數(shù)據(jù)的查詢響應(yīng)也應(yīng)該是低延遲的蛤克。
- 可擴展:系統(tǒng)不僅要能夠適應(yīng)多種業(yè)務(wù)形態(tài)构挤,比如電商、金融等場景筋现,當(dāng)數(shù)據(jù)量或負載突然增加時,系統(tǒng)也應(yīng)該通過增加更多的機器來維持架構(gòu)性能一膨。因此豹绪,可擴展性,應(yīng)該是scale out(增加機器的個數(shù))蝉衣,而不是scale up(增強機器的性能)巷蚪。
最后,Lambda的架構(gòu)剪验,就設(shè)計成了我們經(jīng)城傲看到的樣子:
盡管結(jié)果看起來是“正確的廢話”似嗤,但思考的過程届宠,卻是非常的透徹和深入。這本書很不錯伤塌,但了解的人不多轧铁,感興趣的可以了解一下。
|0x02 Kappa
Lambad框架盡管考慮的很深入了药薯,但仍然存在兩個問題:
- 第一個是數(shù)據(jù)復(fù)雜度高救斑,由于有多套數(shù)據(jù)源脸候,因此口徑對齊就成為了一個大問題绑蔫;同時泵额,產(chǎn)品在建設(shè)時梯刚,交互上要考慮實時和離線兩套邏輯,面對邏輯多一點的業(yè)務(wù)澜共,計算也會變得非常復(fù)雜锥腻;
- 第二個是搭建成本高:不僅框架需要維護多套,開發(fā)人員需要熟悉多種框架京革,而且相互之間運維成本很高幸斥。
離線和實時維護兩套邏輯甲葬,太容易導(dǎo)致數(shù)據(jù)結(jié)果不一致,這個點非常痛坡垫!LinkedIn的Jay Kreps對此很不滿意画侣,于是提出了“Kappa架構(gòu)”,作為Lambda方案的簡化版溉卓,刪除了批處理系統(tǒng)的邏輯宪卿,認為數(shù)據(jù)只需要流式處理就可以。
這個方案的設(shè)計其實有一些暴力西疤,讓我們看下主體思路是怎樣的:
- 以Kafka作為數(shù)據(jù)的存儲系統(tǒng)代赁;
- 當(dāng)需要計算增量數(shù)據(jù)時,只需要訂閱相應(yīng)的broker芭碍,讀取增量即可窖壕;
- 當(dāng)需要計算全量數(shù)據(jù)時,啟動一個流式計算的實例鸳吸,從頭進行計算速勇;
- 當(dāng)新的實例完成后烦磁,停止舊的實例,并刪除舊的結(jié)果都伪。
架構(gòu)上應(yīng)該是這樣樣子:
邏輯上是這個樣子:
有一句話很適合Kappa架構(gòu)楣嘁,即“如無必要珍逸,勿增實體”聋溜,也就是只有在有必要的時候才會對歷史數(shù)據(jù)進行重復(fù)計算。由于實時計算跟離線計算是同一套代碼漱病,因此規(guī)避了兩套邏輯帶來的結(jié)果不一致問題把曼。但相應(yīng)的嗤军,Kappa的性能其實就成為了一個問題,需要對實例的數(shù)量進行控制老客。
感興趣的,在這里進行擴展閱讀:
http://milinda.pathirage.org/kappa-architecture.com/
|0x03 Flink
我們經(jīng)常聽說 "天下武功鳍鸵,唯快不破"尉间,大概意思是說 "任何一種武功的招數(shù)都是有拆招的哲嘲,唯有速度快,快到對手根本來不及反應(yīng)古掏,你就將對手KO了侦啸,對手沒有機會拆招,所以唯快不破"庞萍。Apache Flink是Native Streaming(純流式)計算引擎忘闻,在實時計算場景最關(guān)心的就是"快"齐佳,也就是 "低延時"。
Flink最近實在太火了本鸣,明面上硅蹦,它有這些優(yōu)點:
- 豐富的流式處理用例:事件驅(qū)動型應(yīng)用程序童芹;支持流式/批量處理;支持數(shù)據(jù)通道及ETL署咽。
- 正確性有保障:嚴格執(zhí)行一次機制嗜价;基于事件時間的處理幕庐;復(fù)雜情況下的延遲數(shù)據(jù)處理异剥。
- 分層API機制:流式計算SQL與批量處理數(shù)據(jù)共存絮重;數(shù)據(jù)流API與數(shù)據(jù)集API共存青伤;基于時間和狀態(tài)的過程控制挡育。
但實際上丰歌,F(xiàn)link通過窗口和時間兩個大的特性,有效解決了數(shù)據(jù)的亂序眼溶、周期計算問題晓勇,再配合SQL層統(tǒng)一邏輯绑咱,解決了一套代碼,同時支持實時和離線兩種模式别智。過去通過架構(gòu)來解決性能不夠的問題稼稿,一下子變得不再重要了讳窟。
也許有很多人有質(zhì)疑丽啡,Spark也支持流批的模式,它倆的區(qū)別在哪改执?Spark和Flink雖然都希望能夠?qū)⒘魈幚砗团幚斫y(tǒng)一起來處理,但兩者的實現(xiàn)方式卻各不相同衬横。
Spark是以批處理的技術(shù)為根本蜂林,并嘗試在批處理之上支持流計算拇泣;Flink則認為流計算技術(shù)是最基本的,在流計算的基礎(chǔ)之上支持批處理睁蕾。
因為這種設(shè)計理念的差異债朵,二者存在一些比較顯著的差異。例如在低延遲場景中葱弟,由于Spark是基于批處理的方式進行流式計算壹店,因而在運行的過程中存在一些額外的開銷,如果遇到對延遲的要求非持ゼ樱苛刻的場景硅卢,例如百毫秒甚至十毫秒級別,F(xiàn)link就存在顯著的優(yōu)勢藏杖。
講Flink的文章很多将塑,這里就不再贅述了,希望系統(tǒng)學(xué)習(xí)的蝌麸,還是要去官方網(wǎng)站看看:http://flink.iteblog.com/。
這里也推薦一個大神的博客:https://enjoyment.cool/catalog/
|0xFF 實時數(shù)倉的設(shè)計
講完了實時架構(gòu)来吩,我們再看實時數(shù)倉敢辩。
我們已經(jīng)對離線數(shù)倉怎么做很清楚了,但實時數(shù)倉要怎么做弟疆,則沒有很明確的方法論戚长。有一些觀點是,實時不需要數(shù)倉怠苔,也有一些觀點是同廉,實時像離線一樣做數(shù)倉就行了。這其實都是不對的。
新中國在造核潛艇時迫肖,原本以為核潛艇 = 潛艇 + 核動力锅劝,不就是潛艇換一下動力源嘛,有什么不同的蟆湖,但實際做的時候才發(fā)現(xiàn)故爵,核潛艇與潛艇,完全是兩個物種帐姻。今天很多人在看轟-6K的時候稠集,樣子與轟6差不多,那它們應(yīng)該是同一種飛機饥瓷,但6K和6之間剥纷,除了殼子一樣,里面的東西呢铆,已經(jīng)完全沒什么相似的了晦鞋。
同樣,實時數(shù)倉與離線數(shù)倉棺克,看起來是類似的悠垛,但實質(zhì)卻是不同的。
例如娜谊,這里提一個問題确买,實時數(shù)倉需要維度建模嗎?也可以說是的纱皆,也可以說不需要湾趾,這主要取決于業(yè)務(wù)的復(fù)雜度。其實離線數(shù)倉派草,在業(yè)務(wù)不復(fù)雜的情況下搀缠,也不需要,直接加工目標數(shù)據(jù)庫就行近迁。如果離線都沒必要艺普,那么實時更沒必要。但如果業(yè)務(wù)搞的非常復(fù)雜鉴竭,那么不僅離線需要歧譬,實時也就需要。
但拓瞪,離線與實時缴罗,數(shù)倉的挑戰(zhàn)和思路,還是有一些不同的祭埂。
實時數(shù)倉的挑戰(zhàn),主要體現(xiàn)在四個方面:
- 時效性挑戰(zhàn):實時數(shù)倉如果延遲大了,那么跟分鐘級計算就沒有本質(zhì)區(qū)別蛆橡,因此如何盡可能的快舌界,就是實時數(shù)倉最大的挑戰(zhàn);
- 準確性挑戰(zhàn):離線數(shù)據(jù)有完整的質(zhì)量保證體系泰演,但這些在實時數(shù)倉還都是比較新的挑戰(zhàn)呻拌,過去我們通過流批一體解決了多數(shù)據(jù)源帶來的結(jié)果不一致性,但如果保證開發(fā)結(jié)果的準確睦焕,挑戰(zhàn)依舊很大藐握;
- 穩(wěn)定性挑戰(zhàn):實時數(shù)倉與離線不同,數(shù)據(jù)計算過程中出現(xiàn)了錯誤垃喊,修補的成本非常高猾普,甚至可能導(dǎo)致永久性的數(shù)據(jù)丟失;
- 靈活性挑戰(zhàn):離線數(shù)倉最大的特點本谜,就是可以應(yīng)對海量需求的開發(fā)挑戰(zhàn)初家,而實時數(shù)倉一旦運行任務(wù)太多,不論對開發(fā)還是運維乌助,挑戰(zhàn)都是很大的溜在,尤其是面對需求頻繁變更的場景。
從數(shù)倉的規(guī)范上看他托,各層的變化如下:
- ODS:由于流批一體統(tǒng)一了數(shù)據(jù)源掖肋,而且ODS原本就不對原始數(shù)據(jù)做處理,因此可以無需再建表赏参,直接用數(shù)據(jù)源即可志笼;
- DWD:與離線類似,實時業(yè)務(wù)也需要構(gòu)建事實明細表登刺,但區(qū)別在于籽腕,離線方案中,我們?yōu)榱颂岣呙骷毐淼氖褂帽憬莩潭戎郊螅鶗岩恍┏S玫木S度退化到事實表皇耗,但實時方案出于時效性的考慮,傾向于不退化或者只退化不會變的維度揍很;
- DWS:這一層根據(jù)業(yè)務(wù)情況的不同郎楼,在實時數(shù)倉的建設(shè)策略上,差異比較大窒悔;通常情況下呜袁,離線建設(shè)DWS,是針對比較成熟的業(yè)務(wù)简珠,將維度逐級上卷阶界;這樣做能夠?qū)⑦壿嬤M行收口虹钮,提高下游使用的復(fù)用率,但缺點就是做的比較厚重膘融;如果實時業(yè)務(wù)不是那么復(fù)雜芙粱,那么就不建議將DWS建的很重;究其原因氧映,匯總層的目的在于預(yù)計算春畔、提升效率和保證指標的一致性,實時鏈路太長岛都,容易造成高的延遲和比較大的資源消耗律姨;
- DIM:維表在實時計算中非常重要,也是重點維護的部分臼疫,維表需要實時更新择份,且下游基于最新的維表進行計算;
- ADS:功能和用途不變多矮。
除了維度建模缓淹,現(xiàn)在依然面臨幾個問題。
第一個是實時數(shù)倉是否能完全替代離線數(shù)倉塔逃。
答案是不能完全替代讯壶。尤其是對結(jié)果準確性要求非常高的場景,離線可以通過數(shù)據(jù)回刷等措施來對結(jié)果進行兜底湾盗,但實時一旦數(shù)據(jù)源出錯伏蚊,就很難再進行彌補了。
第二個是公共層是否有必要建設(shè)格粪。
答案是有必要躏吊。如果面對流量暴漲的業(yè)務(wù)場景,如果實時沒有公共層縮減計算數(shù)據(jù)量的話帐萎,一些數(shù)據(jù)傾斜場景很有可能直接干爆了整個實時體系比伏。
第三個是資源的錯峰使用。
實時數(shù)倉的方案通常比較貴疆导,為了解決成本壓力赁项,通常會與離線方案進行混布。凌晨實時壓力小澈段、離線壓力大悠菜,而白天實時壓力大、離線壓力小败富,這時就可以充分根據(jù)集群資源運行情況悔醋,將水位線抹平。
后話:
其實本文涉及了兩個崗位的內(nèi)容:數(shù)據(jù)開發(fā)和數(shù)據(jù)倉庫兽叮,從分工來看芬骄,數(shù)據(jù)開發(fā)更偏向底層猾愿,側(cè)重于工具的優(yōu)化;數(shù)據(jù)倉庫更偏向業(yè)務(wù)德玫,側(cè)重業(yè)務(wù)的最優(yōu)實現(xiàn)》梭埃現(xiàn)代數(shù)據(jù)體系椎麦,單一崗位很難把所有的事情都做了(開發(fā)宰僧、數(shù)倉、分析观挎、算法)琴儿,但又需要你懂所有崗位在做什么。雖然我們都有共同的目標:數(shù)據(jù)科學(xué)家嘁捷,但復(fù)合型人才造成,尤其是一專多能的人才,是邁向數(shù)據(jù)科學(xué)家過程中雄嚣,檢驗階段性結(jié)果的一步晒屎。
本文只是簡單描述了一下實時數(shù)倉用到的一些原理性知識,以及部分的實踐知識缓升,要想出真知鼓鲁,還是需要自己去實踐。大公司之所以是普通人向往的目標港谊,正是因為大公司提供了最好的實踐機會骇吭,并不是做的有多好,只是練的足夠多歧寺。