大数据凉了?No,流式计算浪潮才刚刚开始!
AI 前線導(dǎo)讀:本文重點(diǎn)討論了大數(shù)據(jù)系統(tǒng)發(fā)展的歷史軌跡,行文輕松活潑,內(nèi)容通俗易懂,是一篇茶余飯后用來作為大數(shù)據(jù)談資的不嚴(yán)肅說明文。本文翻譯自《Streaming System》最后一章《The Evolution of Large-Scale Data Processing》,在探討流式系統(tǒng)方面本書是市面上難得一見的深度書籍,非常值得學(xué)習(xí)。
大規(guī)模數(shù)據(jù)處理的演化歷程
大數(shù)據(jù)如果從 Google 對(duì)外發(fā)布 MapReduce 論文算起,已經(jīng)前后跨越十五年,我打算在本文和你蜻蜓點(diǎn)水般一起瀏覽下大數(shù)據(jù)的發(fā)展史,我們從最開始 MapReduce 計(jì)算模型開始,一路走馬觀花看看大數(shù)據(jù)這十五年關(guān)鍵發(fā)展變化,同時(shí)也順便會(huì)講解流式處理這個(gè)領(lǐng)域是如何發(fā)展到今天的這幅模樣。這其中我也會(huì)加入一些我對(duì)一些業(yè)界知名大數(shù)據(jù)處理系統(tǒng) (可能里面有些也不那么出名) 的觀察和評(píng)論,同時(shí)考慮到我很有可能簡(jiǎn)化、低估甚至于忽略了很多重要的大數(shù)據(jù)處理系統(tǒng),我也會(huì)附帶一些參考材料幫助大家學(xué)習(xí)更多更詳細(xì)的知識(shí)。
另外,我們僅僅討論了大數(shù)據(jù)處理中偏 MapReduce/Hadoop 系統(tǒng)及其派系分支的大數(shù)據(jù)處理。我沒有討論任何 SQL 引擎 [1],我們同樣也沒有討論 HPC 或者超級(jí)計(jì)算機(jī)。盡管我這章的標(biāo)題聽上去領(lǐng)域覆蓋非常廣泛,但實(shí)際上我僅僅會(huì)討論一個(gè)相對(duì)比較垂直的大數(shù)據(jù)領(lǐng)域。
同樣需要提醒的一件事情是,我在本文里面或多或少會(huì)提到一些 Google 的技術(shù),不用說這塊是因?yàn)榕c我在谷歌工作了十多年的經(jīng)歷有關(guān)。 但還有另外兩個(gè)原因:1)大數(shù)據(jù)對(duì)谷歌來說一直很重要,因此在那里創(chuàng)造了許多有價(jià)值的東西值得詳細(xì)討論,2)我的經(jīng)驗(yàn)一直是 谷歌以外的人似乎更喜歡學(xué)習(xí) Google 所做的事情,因?yàn)?Google 公司在這方面一直有點(diǎn)守口如瓶。 所以,當(dāng)我過分關(guān)注我們一直在"閉門造車"的東西時(shí),姑且容忍下我吧。
圖 10-1 本章討論各個(gè)大數(shù)據(jù)系統(tǒng)時(shí)間表為了使我們這一次大數(shù)據(jù)旅行顯得更加具體有條理,我們?cè)O(shè)計(jì)了圖 10-1 的時(shí)間表,這張時(shí)間表概括地展示了不同系統(tǒng)的誕生日期。
在每一個(gè)系統(tǒng)介紹過程中,我會(huì)盡可能說明清楚該系統(tǒng)的簡(jiǎn)要?dú)v史,并且我會(huì)嘗試從流式處理系統(tǒng)的演化角度來闡釋該系統(tǒng)對(duì)演化過程的貢獻(xiàn)。最后,我們將回顧以上系統(tǒng)所有的貢獻(xiàn),從而全面了解上述系統(tǒng)如何演化并構(gòu)建出現(xiàn)代流式處理系統(tǒng)的。
?
MapReduce
我們從 MapReduce 開始我們的旅程。
圖 10-2 MapReduce 的時(shí)間表我認(rèn)為我們可以很確定地說,今天我們討論的大規(guī)模數(shù)據(jù)處理系統(tǒng)都源自于 2003 年 MapReduce。當(dāng)時(shí),谷歌的工程師正在構(gòu)建各種定制化系統(tǒng),以解決互聯(lián)網(wǎng)時(shí)代下大數(shù)據(jù)處理難題。當(dāng)他們這樣嘗試去解決這些問題時(shí)候,發(fā)現(xiàn)有三個(gè)難以逾越的坎兒:
-
數(shù)據(jù)處理很難 只要是數(shù)據(jù)科學(xué)家或者工程師都很清楚。如果你能夠精通于從原始數(shù)據(jù)挖掘出對(duì)企業(yè)有價(jià)值的信息,那這個(gè)技能能夠保你這輩子吃喝不愁。
-
可伸縮性很難 本來數(shù)據(jù)處理已經(jīng)夠難了,要從大規(guī)模數(shù)據(jù)集中挖掘出有價(jià)值的數(shù)據(jù)更加困難。
-
容錯(cuò)很難 要從大規(guī)模數(shù)據(jù)集挖掘數(shù)據(jù)已經(jīng)很難了,如果還要想辦法在一批廉價(jià)機(jī)器構(gòu)建的分布式集群上可容錯(cuò)地、準(zhǔn)確地方式挖掘數(shù)據(jù)價(jià)值,那真是難于上青天了。
在多種應(yīng)用場(chǎng)景中都嘗試解決了上述三個(gè)問題之后,Google 的工程師們開始注意到各自構(gòu)建的定制化系統(tǒng)之間頗有相似之處。最終,Google 工程師悟出來一個(gè)道理: 如果他們能夠構(gòu)建一個(gè)可以解決上述問題二和問題三的框架,那么工程師就將可以完全放下問題二和三,從而集中精力解決每個(gè)業(yè)務(wù)都需要解決的問題一。于是,MapReduce 框架誕生了。
MapReduce 的基本思想是提供一套非常簡(jiǎn)潔的數(shù)據(jù)處理 API,這套 API 來自于函數(shù)式編程領(lǐng)域的兩個(gè)非常易于理解的操作:map 和 reduce(圖 10-3)。使用該 API 構(gòu)建的底層數(shù)據(jù)流將在這套分布式系統(tǒng)框架上執(zhí)行,框架負(fù)責(zé)處理所有繁瑣的可擴(kuò)展性和容錯(cuò)性問題。可擴(kuò)展性和容錯(cuò)性問題對(duì)于分布式底層工程師來說無疑是非常有挑戰(zhàn)的課題,但對(duì)于我們普通工程師而言,無益于是災(zāi)難。
圖 10-3 MapReduce 作業(yè)原理圖我們已經(jīng)在第 6 章詳細(xì)討論了 MapReduce 的語義,所以我們?cè)诖瞬辉儋樖觥H僅簡(jiǎn)單地回想一下,我們將處理過程分解為六個(gè)離散階段(MapRead,Map,MapWrite,ReduceRead,Reduce,ReduceWrite)作為對(duì)于流或者表進(jìn)行分析的幾個(gè)步驟。我們可以看到,整體上 Map 和 Reduce 階段之間差異其實(shí)也不大 ; 更高層次來看,他們都做了以下事情:
-
從表中讀取數(shù)據(jù),并轉(zhuǎn)換為數(shù)據(jù)流 (譯者注: 即 MapRead、ReduceRead)
-
針對(duì)上述數(shù)據(jù)流,將用戶編寫業(yè)務(wù)處理代碼應(yīng)用于上述數(shù)據(jù)流,轉(zhuǎn)換并形成新的一個(gè)數(shù)據(jù)流。 (譯者注: 即 Map、Reduce)
-
將上述轉(zhuǎn)換后的流根據(jù)某些規(guī)則分組,并寫出到表中。 (譯者注: 即 MapWrite、ReduceWrite)
隨后,Google 內(nèi)部將 MapReduce 投入生產(chǎn)使用并得到了非常廣泛的業(yè)務(wù)應(yīng)用,Google 認(rèn)為應(yīng)該和公司外的同行分享我們的研究成果,最終我們將 MapReduce 論文發(fā)表于 OSDI 2004(見圖 10-4)。
圖 10-4? MapReduce 論文發(fā)表在 OSDI 2004 上論文中,Google 詳細(xì)描述了 MapReduce 項(xiàng)目的歷史,API 的設(shè)計(jì)和實(shí)現(xiàn),以及有關(guān)使用了 MapReduce 框架的許多不同生產(chǎn)案例的詳細(xì)信息。當(dāng)然,Google 沒有提供任何實(shí)際的源代碼,以至于最終 Google 以外的人都認(rèn)為:“是的,這套系統(tǒng)確實(shí)牛啊!”,然后立馬回頭去模仿 MapReduce 去構(gòu)建他們的定制化系統(tǒng)。
在隨后這十年的過程中,MapReduce 繼續(xù)在谷歌內(nèi)部進(jìn)行大量開發(fā),投入大量時(shí)間將這套系統(tǒng)規(guī)模推進(jìn)到前所未有的水平。如果讀者朋友希望了解一些更加深入更加詳細(xì)的 MapReduce 說明,我推薦由我們的 MapReduce 團(tuán)隊(duì)中負(fù)責(zé)擴(kuò)展性、性能優(yōu)化的大牛 Maria?n Dvorsky?撰寫的文章《History of massive-scale sorting experiments at Google》(圖 10-5)
圖 10-5? MariánDvorsky的《History of massive-scale sorting experiments》博客文章我這里希望強(qiáng)調(diào)的是,這么多年來看,其他任何的分布式架構(gòu)最終都沒有達(dá)到 MapReduce 的集群規(guī)模,甚至在 Google 內(nèi)部也沒有。從 MapReduce 誕生起到現(xiàn)在已經(jīng)跨越十載之久,都未能看到真正能夠超越 MapReduce 系統(tǒng)規(guī)模的另外一套系統(tǒng),足見 MapReduce 系統(tǒng)之成功。14 年的光陰看似不長(zhǎng),對(duì)于互聯(lián)網(wǎng)行業(yè)已然永久。
從流式處理系統(tǒng)來看,我想為讀者朋友強(qiáng)調(diào)的是 MapReduce 的簡(jiǎn)單性和可擴(kuò)展性。 MapReduce 給我們的啟發(fā)是:MapReduce 系統(tǒng)的設(shè)計(jì)非常勇于創(chuàng)新,它提供一套簡(jiǎn)便且直接的 API,用于構(gòu)建業(yè)務(wù)復(fù)雜但可靠健壯的底層分布式數(shù)據(jù) Pipeline,并足夠?qū)⑦@套分布式數(shù)據(jù) Pipeline 運(yùn)行在廉價(jià)普通的商用服務(wù)器集群之上。
?
Hadoop
我們大數(shù)據(jù)旅程的下一站是 Hadoop(圖 10-6)。需要著重說明的是:我為了保證我們討論的重心不至于偏離太多,而壓縮簡(jiǎn)化討論 Hadoop 的內(nèi)容。但必須承認(rèn)的是,Hadoop 對(duì)我們的行業(yè)甚至整個(gè)世界的影響不容小覷,它帶來的影響遠(yuǎn)遠(yuǎn)超出了我在此書討論的范圍。
圖 10-6? Hadoop 的時(shí)間表Hadoop 于 2005 年問世,當(dāng)時(shí) Doug Cutting 和 Mike Cafarella 認(rèn)為 MapReduce 論文中的想法太棒了,他們?cè)跇?gòu)建 Nutch webcrawler 的分布式版本正好需要這套分布式理論基礎(chǔ)。在這之前,他們已經(jīng)實(shí)現(xiàn)了自己版本的 Google 分布式文件系統(tǒng)(最初稱為 Nutch 分布式文件系統(tǒng)的 NDFS,后來改名為 HDFS 或 Hadoop 分布式文件系統(tǒng))。因此下一步,自然而然的,基于 HDFS 之上添加 MapReduce 計(jì)算層。他們稱 MapReduce 這一層為 Hadoop。
Hadoop 和 MapReduce 之間的主要區(qū)別在于 Cutting 和 Cafarella 通過開源(以及 HDFS 的源代碼)確保 Hadoop 的源代碼與世界各地可以共享,最終成為 Apache Hadoop 項(xiàng)目的一部分。雅虎聘請(qǐng) Cutting 來幫助將雅虎網(wǎng)絡(luò)爬蟲項(xiàng)目升級(jí)為全部基于 Hadoop 架構(gòu),這個(gè)項(xiàng)目使得 Hadoop 有效提升了生產(chǎn)可用性以及工程效率。自那以后,整個(gè)開源生態(tài)的大數(shù)據(jù)處理工具生態(tài)系統(tǒng)得到了蓬勃發(fā)展。與 MapReduce 一樣,相信其他人已經(jīng)能夠比我更好地講述了 Hadoop 的歷史。我推薦一個(gè)特別好的講解是 Marko Bonaci 的《The history of Hadoop》,它本身也是一本已經(jīng)出版的紙質(zhì)書籍(圖 10-7)。
圖 10-7? Marko Bonaci 的《The history of Hadoop》在 Hadoop 這部分,我期望讀者朋友能夠了解到圍繞 Hadoop 的開源生態(tài)系統(tǒng)對(duì)整個(gè)行業(yè)產(chǎn)生的巨大影響。通過創(chuàng)建一個(gè)開放的社區(qū),工程師可以從早期的 GFS 和 MapReduce 論文中改進(jìn)和擴(kuò)展這些想法,這直接促進(jìn)生態(tài)系統(tǒng)的蓬勃發(fā)展,并基于此之上產(chǎn)生了許多有用的工具,如 Pig,Hive,HBase,Crunch 等等。這種開放性是導(dǎo)致我們整個(gè)行業(yè)現(xiàn)有思想多樣性的關(guān)鍵,同時(shí) Hadoop 開放性生態(tài)亦是直接促進(jìn)流計(jì)算系統(tǒng)發(fā)展。
?
Flume
我們現(xiàn)在再回到 Google,討論 Google 公司中 MapReduce 的官方繼承者:Flume([圖 10-8],有時(shí)也稱為 FlumeJava,這個(gè)名字起源于最初 Flume 的 Java 版本。需要注意的是,這里的 Flume 不要與 Apache Flume 混淆,這部分是面向不同領(lǐng)域的東西,只是恰好有同樣的名字)。
圖 10-8? Flume 的時(shí)間表Flume 項(xiàng)目由 Craig Chambers 在 2007 年谷歌西雅圖辦事處成立時(shí)發(fā)起。Flume 最初打算是希望解決 MapReduce 的一些固有缺點(diǎn),這些缺點(diǎn)即使在 MapReduce 最初大紅大紫的階段已經(jīng)非常明顯。其中許多缺點(diǎn)都與 MapReduce 完全限定的 Map→Shuffle→Reduce 編程模型相關(guān) ; 這個(gè)編程模型雖然簡(jiǎn)單,但它帶來了一些缺點(diǎn):
-
由于單個(gè) MapReduce 作業(yè)并不能完成大量實(shí)際上的業(yè)務(wù)案例,因此許多定制的編排系統(tǒng)開始在 Google 公司內(nèi)部出現(xiàn),這些編排系統(tǒng)主要用于協(xié)調(diào) MapReduce 作業(yè)的順序。這些系統(tǒng)基本上都在解決同一類問題,即將多個(gè) MapReduce 作業(yè)粘合在一起,創(chuàng)建一個(gè)解決復(fù)雜問題的數(shù)據(jù)管道。然而,這些編排系統(tǒng)都是 Google 各自團(tuán)隊(duì)獨(dú)立開發(fā)的,相互之間也完全不兼容,是一類典型的重復(fù)造輪子案例。
-
更糟糕的是,由于 MapReduce 設(shè)計(jì)的 API 遵循嚴(yán)格結(jié)構(gòu),在很多情況下嚴(yán)格遵循 MapReduce 編程模型會(huì)導(dǎo)致作業(yè)運(yùn)行效率低下。例如,一個(gè)團(tuán)隊(duì)可能會(huì)編寫一個(gè)簡(jiǎn)單地過濾掉一些元素的 MapReduce,即,僅有 Map 階段沒有 Reduce 階段的作業(yè)。這個(gè)作業(yè)下游緊接著另一個(gè)團(tuán)隊(duì)同樣僅有 Map 階段的作業(yè),進(jìn)行一些字段擴(kuò)展和豐富 (仍然帶一個(gè)空的 Reduce 階段作業(yè))。第二個(gè)作業(yè)的輸出最終可能會(huì)被第三個(gè)團(tuán)隊(duì)的 MapReduce 作業(yè)作為輸入,第三個(gè)作業(yè)將對(duì)數(shù)據(jù)執(zhí)行某些分組聚合。這個(gè) Pipeline,實(shí)際上由一個(gè)合并 Map 階段 (譯者注: 前面兩個(gè) Map 合并為一個(gè) Map),外加一個(gè) Reduce 階段即可完成業(yè)務(wù)邏輯,但實(shí)際上卻需要編排三個(gè)完全獨(dú)立的作業(yè),每個(gè)作業(yè)通過 Shuffle 和 Output 兩個(gè)步驟鏈接在一起。假設(shè)你希望保持代碼的邏輯性和清潔性,于是你考慮將部分代碼進(jìn)行合并,但這個(gè)最終導(dǎo)致第三個(gè)問題。
-
為了優(yōu)化 MapReduce 作業(yè)中的這些低效代碼,工程師們開始引入手動(dòng)優(yōu)化,但不幸的是,這些優(yōu)化會(huì)混淆 Pipeline 的簡(jiǎn)單邏輯,進(jìn)而增加維護(hù)和調(diào)試成本。
Flume 通過提供可組合的高級(jí) API 來描述數(shù)據(jù)處理流水線,從而解決了這些問題。這套設(shè)計(jì)理念同樣也是 Beam 主要的抽象模型,即 PCollection 和 PTransform 概念,如圖 10-9 所示。
圖 10-9? Flume 的高層抽象模型(圖片來源:Frances Perry)這些數(shù)據(jù)處理 Pipeline 在作業(yè)啟動(dòng)時(shí)將通過優(yōu)化器生成,優(yōu)化器將以最佳效率生成 MapReduce 作業(yè),然后交由框架編排執(zhí)行。整個(gè)編譯執(zhí)行原理圖可以在圖 10-10 中看到。
圖 10-10? 從邏輯管道到物理執(zhí)行計(jì)劃的優(yōu)化也許 Flume 在自動(dòng)優(yōu)化方面最重要的案例就是是合并(Reuven 在第 5 章中討論了這個(gè)主題),其中兩個(gè)邏輯上獨(dú)立的階段可以在同一個(gè)作業(yè)中順序地(消費(fèi)者 - 生產(chǎn)者融合)執(zhí)行或者并行執(zhí)行(兄弟融合),如圖 10-11 所示。
圖 10-11? 合并優(yōu)化將順序或并行操作 (算子) 組合在一起,到同一個(gè)操作 (算子)。將兩個(gè)階段融合在一起消除了序列化 / 反序列化和網(wǎng)絡(luò)開銷,這在處理大量數(shù)據(jù)的底層 Pipeline 中非常重要。
另一種類型的自動(dòng)優(yōu)化是 combiner lifting(見圖 10-12),當(dāng)我們討論增量合并時(shí),我們已經(jīng)在第 7 章中討論了這些機(jī)制。combiner lifting 只是我們?cè)谠撜掠懻摰亩嗉?jí)組合邏輯的編譯器自動(dòng)優(yōu)化:以求和操作為例,求和的合并邏輯本來應(yīng)該運(yùn)算在分組 (譯者注: 即 Group-By) 操作后,由于優(yōu)化的原因,被提前到在 group-by-key 之前做局部求和(根據(jù) group-by-key 的語義,經(jīng)過 group-by-key 操作需要跨網(wǎng)絡(luò)進(jìn)行大量數(shù)據(jù) Shuffle)。在出現(xiàn)數(shù)據(jù)熱點(diǎn)情況下,將這個(gè)操作提前可以大大減少通過網(wǎng)絡(luò) Shuffle 的數(shù)據(jù)量,并且還可以在多臺(tái)機(jī)器上分散掉最終聚合的機(jī)器負(fù)載。
圖 10-12: combiner lifting 在數(shù)據(jù)上游直接進(jìn)行局部聚合后再發(fā)送給下游端進(jìn)行二次聚合。由于其更清晰的 API 定義和自動(dòng)優(yōu)化機(jī)制,在 2009 年初 Google 內(nèi)部推出后 FlumeJava 立即受到巨大歡迎。之后,該團(tuán)隊(duì)發(fā)表了題為《Flume Java: Easy, Efficient Data-Parallel Pipelines》(https://storage.googleapis.com/pub-tools-public-publication-data/pdf/35650.pdf) 的論文(參見圖 10-13),這篇論文本身就是一個(gè)很好的學(xué)習(xí) FlumeJava 的資料。
圖 10-13? FlumeJava 的論文Flume C++ 版本很快于 2011 年發(fā)布。之后 2012 年初,Flume 被引入為 Google 的所有新工程師提供的 Noogler6 培訓(xùn)內(nèi)容。MapReduce 框架于是最終被走向被替換的命運(yùn)。
從那時(shí)起,Flume 已經(jīng)遷移到不再使用 MapReduce 作為執(zhí)行引擎 ; 相反,Flume 底層基于一個(gè)名為 Dax 的內(nèi)置自定義執(zhí)行引擎。 工作本身。不僅讓 Flume 更加靈活選擇執(zhí)行計(jì)劃而不必拘泥于 Map→Shuffle→Reduce MapReduce 的模型,Dax 還啟用了新的優(yōu)化,例如 Eugene Kirpi-chov 和 Malo Denielou 的《No shard left behind》博客文章(https://cloud.google.com/blog/products/gcp/no-shard-left-behind-dynamic-work-rebalancing-in-google-cloud-dataflow) 中描述的動(dòng)態(tài)負(fù)載均衡(圖 10-14)。
圖 10-14? 帖子 《No shard left behind》盡管那篇博客主要是基于 Google DataFlow 框架下討論問題,但動(dòng)態(tài)負(fù)載均衡(或液態(tài)分片,Google 內(nèi)部更習(xí)慣這樣叫)可以讓部分已經(jīng)完成工作的 Worker 能夠從另外一些繁忙的 Worker 手中分配一些額外的工作。在 Job 運(yùn)行過程中,通過不斷的動(dòng)態(tài)調(diào)整負(fù)載分配可以將系統(tǒng)運(yùn)行效率趨近最優(yōu),這種算法將比傳統(tǒng)方法下有經(jīng)驗(yàn)工程師手工設(shè)置的初始參數(shù)性能更好。Flume 甚至為 Worker 池變化進(jìn)行了適配,一個(gè)拖慢整個(gè)作業(yè)進(jìn)度的 Worker 會(huì)將其任務(wù)轉(zhuǎn)移到其他更加高效的 Worker 上面進(jìn)行執(zhí)行。Flume 的這些優(yōu)化手段,在 Google 內(nèi)部為公司節(jié)省了大量資源。
最后一點(diǎn),Flume 后來也被擴(kuò)展為支持流語義。除 Dax 作為一個(gè)批處理系統(tǒng)引擎外,Flume 還擴(kuò)展為能夠在 MillWheel 流處理系統(tǒng)上執(zhí)行作業(yè)(稍后討論)。在 Google 內(nèi)部,之前本書中討論過的大多數(shù)高級(jí)流處理語義概念首先被整合到 Flume 中,然后才進(jìn)入 Cloud Dataflow 并最終進(jìn)入 Apache Beam。
總而言之,本節(jié)我們主要強(qiáng)調(diào)的是 Flume 產(chǎn)品給人引入高級(jí)管道概念,這使得能夠讓用戶編寫清晰易懂且自動(dòng)優(yōu)化的分布式大數(shù)據(jù)處理邏輯,從而讓創(chuàng)建更大型更復(fù)雜的分布式大數(shù)據(jù)任務(wù)成為了可能,Flume 讓我們業(yè)務(wù)代碼在保持代碼清晰邏輯干凈的同時(shí),自動(dòng)具備編譯器優(yōu)化能力。
?
Storm
接下來是 Apache Storm(圖 10-15),這是我們研究的第一個(gè)真正的流式系統(tǒng)。 Storm 肯定不是業(yè)界使用最早的流式處理系統(tǒng),但我認(rèn)為這是整個(gè)行業(yè)真正廣泛采用的第一個(gè)流式處理系統(tǒng),因此我們?cè)谶@里需要仔細(xì)研究一下。
圖 10-15 Storm 的時(shí)間軸Storm 是 Nathan Marz 的心血結(jié)晶,Nathan Marz 后來在一篇題為《History of Apache Storm and lessons learned》的博客文章(http://nathanmarz.com/blog/history-of-apache-storm-and-lessons-learned.html) 中記錄了其創(chuàng)作歷史(圖 10-16)。 這篇冗長(zhǎng)的博客講述了 BackType 這家創(chuàng)業(yè)公司一直在自己通過消息隊(duì)列和自定義代碼去處理 Twitter 信息流。Nathan 和十幾年前 Google 里面設(shè)計(jì) MapReduce 相關(guān)工程師有相同的認(rèn)識(shí):實(shí)際的業(yè)務(wù)處理的代碼僅僅是系統(tǒng)代碼很小一部分,如果有個(gè)統(tǒng)一的流式實(shí)時(shí)處理框架負(fù)責(zé)處理各類分布式系統(tǒng)底層問題,那么基于之上構(gòu)建我們的實(shí)時(shí)大數(shù)據(jù)處理將會(huì)輕松得多。基于此,Nathan 團(tuán)隊(duì)完成了 Storm 的設(shè)計(jì)和開發(fā)。
值得一提的是,Storm 的設(shè)計(jì)原則和其他系統(tǒng)大相徑庭,Storm 更多考慮到實(shí)時(shí)流計(jì)算的處理時(shí)延而非數(shù)據(jù)的一致性保證。后者是其他大數(shù)據(jù)系統(tǒng)必備基礎(chǔ)產(chǎn)品特征之一。Storm 針對(duì)每條流式數(shù)據(jù)進(jìn)行計(jì)算處理,并提供至多一次或者至少一次的語義保證;同時(shí)不提供任何狀態(tài)存儲(chǔ)能力。相比于 Batch 批處理系統(tǒng)能夠提供一致性語義保證,Storm 系統(tǒng)能夠提供更低的數(shù)據(jù)處理延遲。對(duì)于某些數(shù)據(jù)處理業(yè)務(wù)場(chǎng)景來說,這確實(shí)也是一個(gè)非常合理的取舍。
圖 10-16 《History of Apache Storm and lessons learned》不幸的是,人們很快就清楚地知道他們想要什么樣的流式處理系統(tǒng)。他們不僅希望快速得到業(yè)務(wù)結(jié)果,同時(shí)希望系統(tǒng)具有低延遲和準(zhǔn)確性,但僅憑 Storm 架構(gòu)實(shí)際上不可能做到這一點(diǎn)。針對(duì)這個(gè)情況,Nathan 后面又提出了 Lambda 架構(gòu)。
鑒于 Storm 的局限性,聰明的工程師結(jié)合弱一致語義的 Storm 流處理以及強(qiáng)一致語義的 Hadoop 批處理。前者產(chǎn)生了低延遲,但不精確的結(jié)果,而后者產(chǎn)生了高延遲,但精確的結(jié)果,雙劍合璧,整合兩套系統(tǒng)整體提供的低延遲但最終一致的輸出結(jié)果。我們?cè)诘?1 章中了解到,Lambda 架構(gòu)是 Marz 的另一個(gè)創(chuàng)意,詳見他的文章《“如何擊敗 CAP 定理”》(http://nathanmarz.com/blog/how-to-beat-the-cap-theorem.html) (圖 10-17)。
圖 10-17 《How to beat the CAP theorem》我已經(jīng)花了相當(dāng)多的時(shí)間來分析 Lambda 架構(gòu)的缺點(diǎn),以至于我不會(huì)在這里啰嗦這些問題。但我要重申一下:盡管它帶來了大量成本問題,Lambda 架構(gòu)當(dāng)前還是非常受歡迎,僅僅是因?yàn)樗鼭M足了許多企業(yè)一個(gè)關(guān)鍵需求:系統(tǒng)提供低延遲但不準(zhǔn)確的數(shù)據(jù),后續(xù)通過批處理系統(tǒng)糾正之前數(shù)據(jù),最終給出一致性的結(jié)果。從流處理系統(tǒng)演變的角度來看,Storm 確實(shí)為普羅大眾帶來低延遲的流式實(shí)時(shí)數(shù)據(jù)處理能力。然而,它是以犧牲數(shù)據(jù)強(qiáng)一致性為代價(jià)的,這反過來又帶來了 Lambda 架構(gòu)的興起,導(dǎo)致接下來多年基于兩套系統(tǒng)架構(gòu)之上的數(shù)據(jù)處理帶來無盡的麻煩和成本。
撇開其他問題先不說,Storm 是行業(yè)首次大規(guī)模嘗試低延遲數(shù)據(jù)處理的系統(tǒng),其影響反映在當(dāng)前線上大量部署和應(yīng)用各類流式處理系統(tǒng)。在我們要放下 Storm 開始聊其他系統(tǒng)之前,我覺得還是很有必要去說說 Heron 這個(gè)系統(tǒng)。在 2015 年,Twitter 作為 Storm 項(xiàng)目孵化公司以及世界上已知最大的 Storm 用戶,突然宣布放棄 Storm 引擎,宣稱正在研發(fā)另外一套稱之為 Heron 的流式處理框架。Heron 旨在解決困擾 Storm 的一系列性能和維護(hù)問題,同時(shí)向 Storm 保持 API 兼容,詳見題為《Twitter Heron:Stream Processing at scale》的論文(https://www.semanticscholar.org/paper/Twitter-Heron%3A-Stream-Processing-at-Scale-Kulkarni-Bhagat/e847c3ec130da57328db79a7fea794b07dbccdd9) (圖 10-18)。
圖 10-18 Heron 的論文Heron 本身也是開源產(chǎn)品(但開源不在 Apache 項(xiàng)目中)。鑒于 Storm 仍然在社區(qū)中持續(xù)發(fā)展,現(xiàn)在又冒出一套和 Storm 競(jìng)爭(zhēng)的軟件,最終兩邊系統(tǒng)鹿死誰手,我們只能拭目以待了。
?
Spark
繼續(xù)走起,我們現(xiàn)在來到 Apache Spark(圖 10-19)。再次,我又將大量簡(jiǎn)化 Spark 系統(tǒng)對(duì)行業(yè)的總體影響探討,僅僅關(guān)注我們的流處理領(lǐng)域部分。
圖 10-19 Spark 的時(shí)間軸Spark 在 2009 年左右誕生于加州大學(xué)伯克利分校的著名 AMPLab。最初推動(dòng) Spark 成名的原因是它能夠經(jīng)常在內(nèi)存執(zhí)行大量的計(jì)算工作,直到作業(yè)的最后一步才寫入磁盤。工程師通過彈性分布式數(shù)據(jù)集(RDD)理念實(shí)現(xiàn)了這一目標(biāo),在底層 Pipeline 中能夠獲取每個(gè)階段數(shù)據(jù)結(jié)果的所有派生關(guān)系,并且允許在機(jī)器故障時(shí)根據(jù)需要重新計(jì)算中間結(jié)果,當(dāng)然,這些都基于一些假設(shè) a)輸入是總是可重放的,b)計(jì)算是確定性的。對(duì)于許多案例來說,這些先決條件是真實(shí)的,或者看上去足夠真實(shí),至少用戶確實(shí)在 Spark 享受到了巨大的性能提升。從那時(shí)起,Spark 逐漸建立起其作為 Hadoop 事實(shí)上的繼任產(chǎn)品定位。
在 Spark 創(chuàng)建幾年后,當(dāng)時(shí) AMPLab 的研究生 Tathagata Das 開始意識(shí)到:嘿,我們有這個(gè)快速的批處理引擎,如果我們將多個(gè)批次的任務(wù)串接起來,用它能否來處理流數(shù)據(jù)?于是乎,Spark Streaming 誕生了。
關(guān)于 Spark Streaming 的真正精彩之處在于:強(qiáng)大的批處理引擎解決了太多底層麻煩的問題,如果基于此構(gòu)建流式處理引擎則整個(gè)流處理系統(tǒng)將簡(jiǎn)單很多,于是世界又多一個(gè)流處理引擎,而且是可以獨(dú)自提供一致性語義保障的流式處理系統(tǒng)。換句話說,給定正確的用例,你可以不用 Lambda 架構(gòu)系統(tǒng)直接使用 Spark Streaming 即可滿足數(shù)據(jù)一致性需求。為 Spark Streaming 手工點(diǎn)贊!
這里的一個(gè)主要問題是“正確的用例”部分。早期版本的 Spark Streaming(1.x 版本)的一大缺點(diǎn)是它僅支持特定的流處理語義:即,處理時(shí)間窗口。因此,任何需要使用事件時(shí)間,需要處理延遲數(shù)據(jù)等等案例都無法讓用戶使用 Spark 開箱即用解決業(yè)務(wù)。這意味著 Spark Streaming 最適合于有序數(shù)據(jù)或事件時(shí)間無關(guān)的計(jì)算。而且,正如我在本書中重申的那樣,在處理當(dāng)今常見的大規(guī)模、以用戶為中心的數(shù)據(jù)集時(shí),這些先決條件看上去并不是那么常見。
圍繞 Spark Streaming 的另一個(gè)有趣的爭(zhēng)議是“microbatch 和 true streaming”爭(zhēng)論。由于 Spark Streaming 建立在批處理引擎的重復(fù)運(yùn)行的基礎(chǔ)之上,因此批評(píng)者聲稱 Spark Streaming 不是真正的流式引擎,因?yàn)檎麄€(gè)系統(tǒng)的處理基于全局的數(shù)據(jù)切分規(guī)則。這個(gè)或多或少是實(shí)情。盡管流處理引擎幾乎總是為了吞吐量而使用某種批處理或者類似的加大吞吐的系統(tǒng)策略,但它們可以靈活地在更精細(xì)的級(jí)別上進(jìn)行處理,一直可以細(xì)化到某個(gè) key。但基于微批處理模型的系統(tǒng)在基于全局切分方式處理數(shù)據(jù)包,這意味著同時(shí)具備低延遲和高吞吐是不可能的。確實(shí)我們看到許多基準(zhǔn)測(cè)試表明這說法或多或少有點(diǎn)正確。當(dāng)然,作業(yè)能夠做到幾分鐘或幾秒鐘的延遲已經(jīng)相當(dāng)不錯(cuò)了,實(shí)際上生產(chǎn)中很少有用例需要嚴(yán)格數(shù)據(jù)正確性和低延遲保證。所以從某種意義上說,Spark 瞄準(zhǔn)最初目標(biāo)客戶群體打法是非常到位的,因?yàn)榇蠖鄶?shù)業(yè)務(wù)場(chǎng)景均屬于這一類。但這并未阻止其競(jìng)爭(zhēng)對(duì)手將此作為該平臺(tái)的巨大劣勢(shì)。就個(gè)人而言,在大多數(shù)情況下,我認(rèn)為這只是一個(gè)很小問題。
撇開缺點(diǎn)不說,Spark Streaming 是流處理的分水嶺:第一個(gè)廣泛使用的大規(guī)模流處理引擎,它也可以提供批處理系統(tǒng)的正確性保證。 當(dāng)然,正如前面提到的,流式系統(tǒng)只是 Spark 整體成功故事的一小部分,Spark 在迭代處理和機(jī)器學(xué)習(xí)領(lǐng)域做出了重要貢獻(xiàn),其原生 SQL 集成以及上述快如閃電般的內(nèi)存計(jì)算,都是非常值得大書特書的產(chǎn)品特性。
如果您想了解有關(guān)原始 Spark 1.x 架構(gòu)細(xì)節(jié)的更多信息,我強(qiáng)烈推薦 Matei Zaharia 關(guān)于該主題的論文《 “An Architecture for Fast and General Data Processing on Large Clusters》(圖 10-20)。 這是 113 頁的 Spark 核心講解論文,非常值得一讀。
圖 10-20 Spark 的學(xué)位論文時(shí)至今日,Spark 的 2.x 版本極大地?cái)U(kuò)展了 Spark Streaming 的語義功能,其中已經(jīng)包含了本書中描述流式處理模型的許多部分,同時(shí)試圖簡(jiǎn)化一些更復(fù)雜的設(shè)計(jì)。 Spark 甚至推出了一種全新的、真正面向流式處理的架構(gòu),用以規(guī)避掉微批架構(gòu)的種種問題。但是曾經(jīng),當(dāng) Spark 第一次出現(xiàn)時(shí),它帶來的重要貢獻(xiàn)是它是第一個(gè)公開可用的流處理引擎,具有數(shù)據(jù)處理的強(qiáng)一致性語義,盡管這個(gè)特性只能用在有序數(shù)據(jù)或使用處理時(shí)間計(jì)算的場(chǎng)景。
?
MillWheel
接下來我們討論 MillWheel,這是我在 2008 年加入 Google 后的花 20%時(shí)間兼職參與的項(xiàng)目,后來在 2010 年全職加入該團(tuán)隊(duì)(圖 10-21)。
圖 10-21 MillWheel 時(shí)間表MillWheel 是 Google 最早的通用流處理架構(gòu),該項(xiàng)目由 Paul Nordstrom 在 Google 西雅圖辦事處開業(yè)時(shí)發(fā)起。 MillWheel 在 Google 內(nèi)的成功與長(zhǎng)期以來一直致力于為無序數(shù)據(jù)提供低延遲,強(qiáng)一致的處理能力不無關(guān)系。在本書的講解中,我們已經(jīng)多次分別討論了促使 MillWheel 成為一款成功產(chǎn)品的方方面面。
-
第五章,Reuven 詳細(xì)討論過數(shù)據(jù)精準(zhǔn)一次的語義保證。精準(zhǔn)一次的語義保證對(duì)于正確性至關(guān)重要。
-
第七章,我們研究了狀態(tài)持久化,這為在不那么靠譜的普通硬件上執(zhí)行的長(zhǎng)時(shí)間數(shù)據(jù)處理業(yè)務(wù)并且需要保證正確性奠定了基礎(chǔ)。
-
第三章,Slava 討論了 Watermark。Watermark 為處理無序數(shù)據(jù)提供了基礎(chǔ)。
-
第七章,我們研究了持久性計(jì)時(shí)器,它們提供了 Watermark 與業(yè)務(wù)邏輯之間的某些關(guān)聯(lián)特性。
有點(diǎn)令人驚訝的是,MillWheel 項(xiàng)目最開始并未關(guān)注數(shù)據(jù)正確性。保羅最初的想法更接近于 Storm 的設(shè)計(jì)理論:具有弱一致性的低延遲數(shù)據(jù)處理。這是最初的 MillWheel 客戶,一個(gè)關(guān)于基于用戶搜索數(shù)據(jù)構(gòu)建會(huì)話和另一個(gè)對(duì)搜索查詢執(zhí)行異常檢測(cè)(來自 MillWheel 論文的 Zeitgeist 示例),這兩家客戶迫使項(xiàng)目走向了正確的方向。兩者都非常需要強(qiáng)一致的數(shù)據(jù)結(jié)果:會(huì)話用于推斷用戶行為,異常檢測(cè)用于推斷搜索查詢的趨勢(shì) ; 如果他們提供的數(shù)據(jù)不靠譜,兩者效果都會(huì)顯著下降。最終,幸運(yùn)的是,MillWheel 的設(shè)計(jì)被客戶需求導(dǎo)向追求數(shù)據(jù)強(qiáng)一致性的結(jié)果。
支持亂序數(shù)據(jù)處理,這是現(xiàn)代流式處理系統(tǒng)的另一個(gè)核心功能。這個(gè)核心功能通常也被認(rèn)為是被 MillWheel 引入到流式處理領(lǐng)域,和數(shù)據(jù)準(zhǔn)確性一樣,這個(gè)功能也是被客戶需求推動(dòng)最終加入到我們系統(tǒng)。 Zeitgeist 項(xiàng)目的大數(shù)據(jù)處理過程,通常被我們拿來用作一個(gè)真正的流式處理案例來討論。Zeitgeist 項(xiàng)目希望檢測(cè)識(shí)別搜索查詢流量中的異常,并且需要捕獲異常流量。對(duì)于這個(gè)大數(shù)據(jù)項(xiàng)目數(shù)據(jù)消費(fèi)者來說,流計(jì)算將所有計(jì)算結(jié)果產(chǎn)出并讓用戶輪詢所有 key 用來識(shí)別異常顯然不太現(xiàn)實(shí),數(shù)據(jù)用戶要求系統(tǒng)直接計(jì)算某個(gè) key 出現(xiàn)異常的數(shù)據(jù)結(jié)果,而不需要上層再來輪詢。對(duì)于異常峰值(即查詢流量的增加),這還相對(duì)來說比較簡(jiǎn)單好解決:當(dāng)給定查詢的計(jì)數(shù)超過查詢的預(yù)期值時(shí),系統(tǒng)發(fā)出異常信號(hào)。但是對(duì)于異常下降(即查詢流量減少),問題有點(diǎn)棘手。僅僅看到給定搜索詞的查詢數(shù)量減少是不夠的,因?yàn)樵谌魏螘r(shí)間段內(nèi),計(jì)算結(jié)果總是從零開始。在這些情況下你必須確保你的數(shù)據(jù)輸入真的能夠代表當(dāng)前這段時(shí)間真實(shí)業(yè)務(wù)流量,然后才將計(jì)算結(jié)果和預(yù)設(shè)模型進(jìn)行比較。
真正的流式處理
“真正的流式處理用例”需要一些額外解釋。流式系統(tǒng)的一個(gè)新的演化趨勢(shì)是,舍棄掉部分產(chǎn)品需求以簡(jiǎn)化編程模型,從而使整個(gè)系統(tǒng)簡(jiǎn)單易用。例如,在撰寫本文時(shí),Spark Structured Streaming 和 Apache Kafka Streams 都將系統(tǒng)提供的功能限制在第 8 章中稱為“物化視圖語義”范圍內(nèi),本質(zhì)上對(duì)最終一致性的輸出表不停做數(shù)據(jù)更新。當(dāng)您想要將上述輸出表作為結(jié)果查詢使用時(shí),物化視圖語義非常匹配你的需求:任何時(shí)候我們只需查找該表中的值并且 (譯者注: 盡管結(jié)果數(shù)據(jù)一直在不停被更新和改變) 以當(dāng)前查詢時(shí)間請(qǐng)求到查詢結(jié)果就是最新的結(jié)果。但在一些需要真正流式處理的場(chǎng)景,例如異常檢測(cè),上述物化視圖并不能夠很好地解決這類問題。
接下來我們會(huì)討論到,異常檢測(cè)的某些需求使其不適合純物化視圖語義(即,依次針對(duì)單條記錄處理),特別當(dāng)需要完整的數(shù)據(jù)集才能夠識(shí)別業(yè)務(wù)異常,而這些異常恰好是由于數(shù)據(jù)的缺失或者不完整導(dǎo)致的。另外,不停輪詢結(jié)果表以查看是否有異常其實(shí)并不是一個(gè)擴(kuò)展性很好的辦法。真正的流式用戶場(chǎng)景是推動(dòng) watermark 等功能的原始需求來源。(Watermark 所代表的時(shí)間有先有后,我們需要最低的 Watermark 追蹤數(shù)據(jù)的完整性,而最高的 Watermark 在數(shù)據(jù)時(shí)間發(fā)生傾斜時(shí)候非常容易導(dǎo)致丟數(shù)據(jù)的情況發(fā)生,類似 Spark Structured Streaming 的用法)。省略類似 Watermark 等功能的系統(tǒng)看上去簡(jiǎn)單不少,但換來代價(jià)是功能受限。在很多情況下,這些功能實(shí)際上有非常重要的業(yè)務(wù)價(jià)值。但如果這樣的系統(tǒng)聲稱這些簡(jiǎn)化的功能會(huì)帶來系統(tǒng)更多的普適性,不要聽他們忽悠。試問一句,功能需求大量被砍掉,如何保證系統(tǒng)的普適性呢?
Zeitgeist 項(xiàng)目首先嘗試通過在計(jì)算邏輯之前插入處理時(shí)間的延遲數(shù)值來解決數(shù)據(jù)延遲問題。當(dāng)數(shù)據(jù)按順序到達(dá)時(shí),這個(gè)思路處理邏輯正常。但業(yè)務(wù)人員隨后發(fā)現(xiàn)數(shù)據(jù)有時(shí)可能會(huì)延遲很大,從而導(dǎo)致數(shù)據(jù)無序進(jìn)入流式處理系統(tǒng)。一旦出現(xiàn)這個(gè)情況,系統(tǒng)僅僅采用處理時(shí)間的延遲是不夠的,因?yàn)榈讓訑?shù)據(jù)處理會(huì)因?yàn)閿?shù)據(jù)亂序原因被錯(cuò)誤判斷為異常。最終,我們需要一種等待數(shù)據(jù)到齊的機(jī)制。
之后 Watermark 被設(shè)計(jì)出來用以解決數(shù)據(jù)亂序的問題。正如 Slava 在第 3 章中所描述的那樣,基本思想是跟蹤系統(tǒng)輸入數(shù)據(jù)的當(dāng)前進(jìn)度,對(duì)于每個(gè)給定的數(shù)據(jù)源,構(gòu)建一個(gè)數(shù)據(jù)輸入進(jìn)度用來表征輸入數(shù)據(jù)的完整性。對(duì)于一些簡(jiǎn)單的數(shù)據(jù)源,例如一個(gè)帶分區(qū)的 Kafka Topic,每個(gè) Topic 下屬的分區(qū)被寫入的是業(yè)務(wù)時(shí)間持續(xù)遞增的數(shù)據(jù)(例如通過 Web 前端實(shí)時(shí)記錄的日志事件),這種情況下我們可以計(jì)算產(chǎn)生一個(gè)非常完美的 Watermark。但對(duì)于一些非常復(fù)雜的數(shù)據(jù)輸入,例如動(dòng)態(tài)的輸入日志集,一個(gè)啟發(fā)式算法可能是我們能夠設(shè)計(jì)出來最能解決業(yè)務(wù)問題的 Watermark 生成算法了。但無論哪種方式,Watermark 都是解決輸入事件完整性最佳方式。之前我們嘗試使用處理時(shí)間來解決事件輸入完整性,有點(diǎn)驢頭不及馬嘴的感覺。
得益于客戶的需求推動(dòng),MillWheel 最終成為能夠支持無序數(shù)據(jù)的強(qiáng)大流處理引擎。因此,題為《MillWheel: Fault-Tolerant Stream Processing at Internet Scale》(圖 10-22)的論文花費(fèi)大部分時(shí)間來討論在這樣的系統(tǒng)中提供正確性的各種問題,一致性保證、Watermark。如果您對(duì)這個(gè)主題感興趣,那值得花時(shí)間去讀讀這篇論文。
圖 10-22 MillWheel 論文MillWheel 論文發(fā)表后不久,MillWheel 就成為 Flume 底層提供支撐的流式處理引擎,我們稱之為 Streaming Flume。今天在谷歌內(nèi)部,MillWheel 被下一代理論更為領(lǐng)先的系統(tǒng)所替換: Windmill(這套系統(tǒng)同時(shí)也為 DataFlow 提供了執(zhí)行引擎),這是一套基于 MillWheel 之上,博采眾家之長(zhǎng)的大數(shù)據(jù)處理系統(tǒng),包括提供更好的調(diào)度和分發(fā)策略、更清晰的框架和業(yè)務(wù)代碼解耦。
MillWheel 給我們帶來最大的價(jià)值是之前列出的四個(gè)概念(數(shù)據(jù)精確一次性處理,持久化的狀態(tài)存儲(chǔ),Watermark,持久定時(shí)器)為流式計(jì)算提供了工業(yè)級(jí)生產(chǎn)保障:即使在不可靠的商用硬件上,也可以對(duì)無序數(shù)據(jù)進(jìn)行穩(wěn)定的、低延遲的處理。
?
Kafka
我們開始討論 Kafka(圖 10-23)。 Kafka 在本章討論的系統(tǒng)中是獨(dú)一無二的,因?yàn)樗皇菙?shù)據(jù)計(jì)算框架,而是數(shù)據(jù)傳輸和存儲(chǔ)的工具。但是,毫無疑問,Kafka 在我們正在討論的所有系統(tǒng)中扮演了推動(dòng)流處理的最有影響力的角色之一。
圖 10-23 Kafka 的時(shí)間軸如果你不熟悉它,我們可以簡(jiǎn)單描述為: Kafka 本質(zhì)上是一個(gè)持久的流式數(shù)據(jù)傳輸和存儲(chǔ)工具,底層系統(tǒng)實(shí)現(xiàn)為一組帶有分區(qū)結(jié)構(gòu)的日志型存儲(chǔ)。它最初是由 Neha Narkhede 和 Jay Kreps 等業(yè)界大牛在 LinkedIn 公司內(nèi)部開發(fā)的,其卓越的特性有:
-
提供一個(gè)干凈的持久性模型,讓大家在流式處理領(lǐng)域里面可以享受到批處理的產(chǎn)品特性,例如持久化、可重放。
-
在生產(chǎn)者和消費(fèi)者之間提供彈性隔離。
-
我們?cè)诘?6 章中討論過的流和表之間的關(guān)系,揭示了思考數(shù)據(jù)處理的基本方式,同時(shí)還提供了和數(shù)據(jù)庫打通的思路和概念。
-
來自于上述所有方面的影響,不僅讓 Kafka 成為整個(gè)行業(yè)中大多數(shù)流處理系統(tǒng)的基礎(chǔ),而且還促進(jìn)了流處理數(shù)據(jù)庫和微服務(wù)運(yùn)動(dòng)。
在這些特性中,有兩個(gè)對(duì)我來說最為突出。第一個(gè)是流數(shù)據(jù)的持久化和可重放性的應(yīng)用。在 Kafka 之前,大多數(shù)流處理系統(tǒng)使用某種臨時(shí)、短暫的消息系統(tǒng),如 Rabbit MQ 甚至是普通的 TCP 套接字來發(fā)送數(shù)據(jù)。數(shù)據(jù)處理的一致性往往通過生產(chǎn)者數(shù)據(jù)冗余備份來實(shí)現(xiàn)(即,如果下游數(shù)據(jù)消費(fèi)者出現(xiàn)故障,則上游生產(chǎn)者將數(shù)據(jù)進(jìn)行重新發(fā)送),但是上游數(shù)據(jù)的備份通常也是臨時(shí)保存一下。大多數(shù)系統(tǒng)設(shè)計(jì)完全忽略在開發(fā)和測(cè)試中需要重新拉取數(shù)據(jù)重新計(jì)算的需求。但 Kafka 的出現(xiàn)改變了這一切。從數(shù)據(jù)庫持久日志概念得到啟發(fā)并將其應(yīng)用于流處理領(lǐng)域,Kafka 讓我們享受到了如同 Batch 數(shù)據(jù)源一樣的安全性和可靠性。憑借持久化和可重放的特點(diǎn),流計(jì)算在健壯性和可靠性上面又邁出關(guān)鍵的一步,為后續(xù)替代批處理系統(tǒng)打下基礎(chǔ)。
作為一個(gè)流式系統(tǒng)開發(fā)人員,Kafka 的持久化和可重放功能對(duì)業(yè)界產(chǎn)生一個(gè)更有意思的變化就是: 當(dāng)今大量流處理引擎依賴源頭數(shù)據(jù)可重放來提供端到端精確一次的計(jì)算保障。可重放的特點(diǎn)是 Apex,Flink,Kafka Streams,Spark 和 Storm 的端到端精確一次保證的基礎(chǔ)。當(dāng)以精確一次模式執(zhí)行時(shí),每個(gè)系統(tǒng)都假設(shè) / 要求輸入數(shù)據(jù)源能夠重放之前的部分?jǐn)?shù)據(jù) (從最近 Checkpoint 到故障發(fā)生時(shí)的數(shù)據(jù))。當(dāng)流式處理系統(tǒng)與不具備重放能力的輸入源一起使用時(shí)(哪怕是源頭數(shù)據(jù)能夠保證可靠的一致性數(shù)據(jù)投遞,但不能提供重放功能),這種情況下無法保證端到端的完全一次語義。這種對(duì)可重放(以及持久化等其他特點(diǎn))的廣泛依賴是 Kafka 在整個(gè)行業(yè)中產(chǎn)生巨大影響的間接證明。
Kafka 系統(tǒng)中第二個(gè)值得注意的重點(diǎn)是流和表理論的普及。我們花了整個(gè)第 6 章以及第 8 章、第 9 章來討論流和表,可以說流和表構(gòu)成了數(shù)據(jù)處理的基礎(chǔ),無論是 MapReduce 及其演化系統(tǒng),SQL 數(shù)據(jù)庫系統(tǒng),還是其他分支的數(shù)據(jù)處理系統(tǒng)。并不是所有的數(shù)據(jù)處理方法都直接基于流或者表來進(jìn)行抽象,但從概念或者理論上說,表和流的理論就是這些系統(tǒng)的運(yùn)作方式。作為這些系統(tǒng)的用戶和開發(fā)人員,理解我們所有系統(tǒng)構(gòu)建的核心基礎(chǔ)概念意義重大。我們都非常感謝 Kafka 社區(qū)的開發(fā)者,他們幫助我們更廣泛更加深入地了解到批流理論。
如果您想了解更多關(guān)于 Kafka 及其理論核心,JackKreps 的《I?Logs》(O'Reilly; 圖 10-24)是一個(gè)很好的學(xué)習(xí)資料。另外,正如第 6 章中引用的那樣,Kreps 和 Martin Kleppmann 有兩篇文章(圖 10-25),我強(qiáng)烈建議您閱讀一下關(guān)于流和表相關(guān)理論。
圖 10-24 《I ? Logs》Kafka 為流處理領(lǐng)域做出了巨大貢獻(xiàn),可以說比其他任何單一系統(tǒng)都要多。特別是,對(duì)輸入和輸出流的持久性和可重放的設(shè)計(jì),幫助將流計(jì)算從近似工具的小眾領(lǐng)域發(fā)展到在大數(shù)據(jù)領(lǐng)域婦孺皆知的程度起了很大作用。此外,Kafka 社區(qū)推廣的流和表理論對(duì)于數(shù)據(jù)處理引發(fā)了我們深入思考。
圖10-25? Martin 的帖子 (左邊) 以及 Jay 的帖子 (右邊)?
DataFlow
Cloud Dataflow(圖 10-26)是 Google 完全托管的、基于云架構(gòu)的數(shù)據(jù)處理服務(wù)。 Dataflow 于 2015 年 8 月推向全球。DataFlow 將 MapReduce,Flume 和 MillWheel 的十多年經(jīng)驗(yàn)融入其中,并將其打包成 Serverless 的云體驗(yàn)。
圖 10-26 Google DataFlow 的時(shí)間軸雖然 Google 的 Dataflow 的 Serverless 特點(diǎn)可能是從系統(tǒng)角度來看最具技術(shù)挑戰(zhàn)性以及有別于其他云廠商產(chǎn)品的重要因素,但我想在此討論主要是其批流統(tǒng)一的編程模型。編程模型包括我們?cè)诒緯拇蟛糠謨?nèi)容中所討論的轉(zhuǎn)換,窗口,水印,觸發(fā)器和聚合計(jì)算。當(dāng)然,所有這些討論都包含了思考問題的 what、where、when、how。
DataFlow 模型首先誕生于 Flume,因?yàn)槲覀兿M麑?MillWheel 中強(qiáng)大的無序數(shù)據(jù)計(jì)算能力整合到 Flume 提供的更高級(jí)別的編程模型中。這個(gè)方式可以讓 Google 員工在內(nèi)部使用 Flume 進(jìn)行統(tǒng)一的批處理和流處理編程。
關(guān)于統(tǒng)一模型的核心關(guān)鍵思考在于,盡管在當(dāng)時(shí)我們也沒有深刻意識(shí)到,批流處理模型本質(zhì)上沒有區(qū)別: 僅僅是在表和流的處理上有些小變化而已。正如我們?cè)诘?6 章中所討論到的,主要的區(qū)別僅僅是在將表上增量的變化轉(zhuǎn)換為流,其他一切在概念上是相同的。通過利用批處理和流處理兩者大量的共性需求,可以提供一套引擎,適配于兩套不同處理方式,這讓流計(jì)算系統(tǒng)更加易于使用。
除了利用批處理和流處理之間的系統(tǒng)共性之外,我們還仔細(xì)查看了多年來我們?cè)?Google 中遇到的各種案例,并使用這些案例來研究統(tǒng)一模型下系統(tǒng)各個(gè)部分。我們研究主要內(nèi)容如下:
-
未對(duì)齊的事件時(shí)間窗口(如會(huì)話窗口),能夠簡(jiǎn)明地表達(dá)這類復(fù)雜的分析,同時(shí)亦能處理亂序數(shù)據(jù)。
-
自定義窗口支持,系統(tǒng)內(nèi)置窗口很少適合所有業(yè)務(wù)場(chǎng)景,需要提供給用戶自定義窗口的能力。
-
靈活的觸發(fā)和統(tǒng)計(jì)模式,能夠滿足正確性,延遲,成本的各項(xiàng)業(yè)務(wù)需求。
-
使用 Watermark 來推斷輸入數(shù)據(jù)的完整性,這對(duì)于異常檢測(cè)等用例至關(guān)重要,其中異常檢測(cè)邏輯會(huì)根據(jù)是否缺少數(shù)據(jù)做出異常判斷。
-
底層執(zhí)行環(huán)境的邏輯抽象,無論是批處理,微批處理還是流式處理,都可以在執(zhí)行引擎中提供靈活的選擇,并避免系統(tǒng)級(jí)別的參數(shù)設(shè)置(例如微批量大小)進(jìn)入邏輯 API。
總之,這些平衡了靈活性,正確性,延遲和成本之間的關(guān)系,將 DataFlow 的模型應(yīng)用于大量用戶業(yè)務(wù)案例之中。
考慮到我們之前整本書都在討論 DataFlow 和 Beam 模型的各類問題,我在此處重新給大家講述這些概念純屬多此一舉。但是,如果你正在尋找稍微更具學(xué)術(shù)性的內(nèi)容以及一些應(yīng)用案例,我推薦你看下 2015 年發(fā)表的《DataFlow 論文..》(圖 10-27)。
圖 10-27 DataFlow 的論文DataFlow 還有不少可以大書特書的功能特點(diǎn),但在這章內(nèi)容構(gòu)成來看,我認(rèn)為 DataFlow 最重要的是構(gòu)建了一套批流統(tǒng)一的大數(shù)據(jù)處理模型。DataFlow 為我們提供了一套全面的處理無界且無序數(shù)據(jù)集的能力,同時(shí)這套系統(tǒng)很好的平衡了正確性、延遲、成本之間的相互關(guān)系。
?
Flink??
Flink(圖 10-28)在 2015 年突然出現(xiàn)在大數(shù)據(jù)舞臺(tái),然后似乎在一夜之間從一個(gè)無人所知的系統(tǒng)迅速轉(zhuǎn)變?yōu)槿巳私灾牧魇教幚硪妗?/p> 圖 10-28? Flink 的時(shí)間軸
在我看來,Flink 崛起有兩個(gè)主要原因:
-
采用 Dataflow/Beam 編程模型,使其成為完備語義功能的開源流式處理系統(tǒng)。
-
其高效的快照實(shí)現(xiàn)方式,源自 Chandy 和 Lamport 的原始論文《“Distributed Snapshots: Determining Global States of Distributed Systems”》的研究,這為其提供了正確性所需的強(qiáng)一致性保證。
Reuven 在第 5 章中簡(jiǎn)要介紹了 Flink 的一致性機(jī)制,這里在重申一下,其基本思想是在系統(tǒng)中的 Worker 之間沿著數(shù)據(jù)傳播路徑上產(chǎn)生周期性 Barrier。這些 Barrier 充當(dāng)了在不同 Worker 之間傳輸數(shù)據(jù)時(shí)的對(duì)齊機(jī)制。當(dāng)一個(gè) Worker 在其所有上游算子輸入來源(即來自其所有上游一層的 Worker)上接收到全部 Barrier 時(shí),Worker 會(huì)將當(dāng)前所有 key 對(duì)應(yīng)的狀態(tài)寫入一個(gè)持久化存儲(chǔ)。這個(gè)過程意味著將這個(gè) Barrier 之前的所有數(shù)據(jù)都做了持久化。
圖 10-29 Chandy-Lamport 快照 ??通過調(diào)整 Barrier 的生成頻率,可以間接調(diào)整 Checkpoint 的執(zhí)行頻率,從而降低時(shí)延并最終獲取更高的吞吐(其原因是做 Checkpoint 過程中涉及到對(duì)外進(jìn)行持久化數(shù)據(jù),因此會(huì)有一定的 IO 導(dǎo)致延時(shí))。
Flink 既能夠支持精確一次的語義處理保證,同時(shí)又能夠提供支持事件時(shí)間的處理能力,這讓 Flink 獲取的巨大的成功。接著, Jamie Grier 發(fā)表他的題為“《Extending the Yahoo! Streaming Benchmark》“(圖 10-30)的文章,文章中描述了 Flink 性能具體的測(cè)試數(shù)據(jù)。在那篇文章中,杰米描述了兩個(gè)令人印象深刻的特點(diǎn):
構(gòu)建一個(gè)用于測(cè)試的 Flink 數(shù)據(jù)管道,其擁有比 Twitter Storm 更高的準(zhǔn)確性(歸功于 Flink 的強(qiáng)一次性語義),但成本卻降到了 1%。
2. Flink 在精確一次的處理語義參數(shù)設(shè)定下,仍然達(dá)到 Storm 的 7.5 倍吞吐量(而且,Storm 還不具備精確一次的處理語義)。此外,由于網(wǎng)絡(luò)被打滿導(dǎo)致 Flink 的性能受到限制 ; 進(jìn)一步消除網(wǎng)絡(luò)瓶頸后 Flink 的吞吐量幾乎達(dá)到 Storm 的 40 倍。
從那時(shí)起,許多其他流式處理項(xiàng)目(特別是 Storm 和 Apex)都采用了類似算法的數(shù)據(jù)處理一致性機(jī)制。
圖 10-31 《Savepoints: Turning Back Time》通過快照機(jī)制,Flink 獲得了端到端數(shù)據(jù)一致性。Flink 更進(jìn)了一步,利用其快照的全局特性,提供了從過去的任何一點(diǎn)重啟整個(gè)管道的能力,這一功能稱為 SavePoint(在 Fabian Hueske 和 Michael Winters 的帖子 [《Savepoints: Turning Back Time》(https://data-artisans.com/blog/turning-back-time-savepoints)] 中有所描述,[圖 10-31])。Savepoints 功能參考了 Kafka 應(yīng)用于流式傳輸層的持久化和可重放特性,并將其擴(kuò)展應(yīng)用到整個(gè)底層 Pipeline。流式處理仍然遺留大量開放性問題有待優(yōu)化和提升,但 Flink 的 Savepoints 功能是朝著正確方向邁出的第一步,也是整個(gè)行業(yè)非常有特點(diǎn)的一步。 如果您有興趣了解有關(guān) Flink 快照和保存點(diǎn)的系統(tǒng)構(gòu)造的更多信息,請(qǐng)參閱《State Management in Apache Flink》(圖 10-32),論文詳細(xì)討論了相關(guān)的實(shí)現(xiàn)。
圖 10-32 《State Management in Apache Flink》除了保存點(diǎn)之外,Flink 社區(qū)還在不斷創(chuàng)新,包括將第一個(gè)實(shí)用流式 SQL API 推向大規(guī)模分布式流處理引擎的領(lǐng)域,正如我們?cè)诘?8 章中所討論的那樣。 總之,Flink 的迅速崛起成為流計(jì)算領(lǐng)軍角色主要?dú)w功于三個(gè)特點(diǎn):
整合行業(yè)里面現(xiàn)有的最佳想法(例如,成為第一個(gè)開源 DataFlow/Beam 模型)
創(chuàng)新性在表上做了大量?jī)?yōu)化,并將狀態(tài)管理發(fā)揮更大價(jià)值,例如基于 Snapshot 的強(qiáng)一致性語義保證,Savepoints 以及流式 SQL。
迅速且持續(xù)地推動(dòng)上述需求落地。
另外,所有這些改進(jìn)都是在開源社區(qū)中完成的,我們可以看到為什么 Flink 一直在不斷提高整個(gè)行業(yè)的流計(jì)算處理標(biāo)準(zhǔn)。
?
Beam?
我們今天談到的最后一個(gè)系統(tǒng)是 Apache Beam(圖 10-33)。 Beam 與本章中的大多數(shù)其他系統(tǒng)的不同之處在于,它主要是編程模型,API 設(shè)計(jì)和可移植層,而不是帶有執(zhí)行引擎的完整系統(tǒng)棧。但這正是我想強(qiáng)調(diào)的重點(diǎn):正如 SQL 作為聲明性數(shù)據(jù)處理的通用語言一樣,Beam 的目標(biāo)是成為程序化數(shù)據(jù)處理的通用語言。
圖 10-33 Apache Beam 的時(shí)間軸具體而言,Beam 由許多組件組成:
-
一個(gè)統(tǒng)一的批量加流式編程模型,繼承自 Google DataFlow 產(chǎn)品設(shè)計(jì),以及我們?cè)诒緯拇蟛糠謨?nèi)容中討論的細(xì)節(jié)。該模型獨(dú)立于任何語言實(shí)現(xiàn)或 runtime 系統(tǒng)。您可以將此視為 Beam 等同于描述關(guān)系代數(shù)模型的 SQL。
-
一組實(shí)現(xiàn)該模型的 SDK(軟件開發(fā)工具包),允許底層的 Pipeline 以不同 API 語言的慣用方式編排數(shù)據(jù)處理模型。 Beam 目前提供 Java,Python 和 Go 的 SDK,可以將它們視為 Beam 的 SQL 語言本身的程序化等價(jià)物。
-
一組基于 SDK 的 DSL(特定于域的語言),提供專門的接口,以獨(dú)特的方式描述模型在不同領(lǐng)域的接口設(shè)計(jì)。SDK 來描述上述模型處理能力的全集,但 DSL 描述一些特定領(lǐng)域的處理邏輯。 Beam 目前提供了一個(gè)名為 Scio 的 Scala DSL 和一個(gè) SQL DSL,它們都位于現(xiàn)有 Java SDK 之上。
-
一組可以執(zhí)行 Beam Pipeline 的執(zhí)行引擎。執(zhí)行引擎采用 Beam SDK 術(shù)語中描述的邏輯 Pipeline,并盡可能高效地將它們轉(zhuǎn)換為可以執(zhí)行的物理計(jì)劃。目前,針對(duì) Apex,Flink,Spark 和 Google Cloud Dataflow 存在對(duì)應(yīng)的 Beam 引擎適配。在 SQL 術(shù)語中,您可以將這些引擎適配視為 Beam 在各種 SQL 數(shù)據(jù)庫的實(shí)現(xiàn),例如 Postgres,MySQL,Oracle 等。
Beam 的核心愿景是實(shí)現(xiàn)一套可移植接口層,最引人注目的功能之一是它計(jì)劃支持完整的跨語言可移植性。盡管最終目標(biāo)尚未完全完成(但即將面市),讓 Beam 在 SDK 和引擎適配之間提供足夠高效的抽象層,從而實(shí)現(xiàn) SDK 和引擎適配之間的任意切換。我們暢想的是,用 JavaScript SDK 編寫的數(shù)據(jù) Pipeline 可以在用 Haskell 編寫的引擎適配層上無縫地執(zhí)行,即使 Haskell 編寫的引擎適配本身沒有執(zhí)行 JavaScript 代碼的能力。
作為一個(gè)抽象層,Beam 如何定位自己和底層引擎關(guān)系,對(duì)于確保 Beam 實(shí)際為社區(qū)帶來價(jià)值至關(guān)重要,我們也不希望看到 Beam 引入一個(gè)不必要的抽象層。這里的關(guān)鍵點(diǎn)是,Beam 的目標(biāo)永遠(yuǎn)不僅僅是其所有底層引擎功能的交集(類似最小公分母)或超集(類似廚房水槽)。相反,它旨在為整個(gè)社區(qū)大數(shù)據(jù)計(jì)算引擎提供最佳的想法指導(dǎo)。這里面有兩個(gè)創(chuàng)新的角度:
-
Beam 本身的創(chuàng)新
Beam 將會(huì)提出一些 API,這些 API 需要底層 runtime 改造支持,并非所有底層引擎最初都支持這些功能。這沒關(guān)系,隨著時(shí)間的推移,我們希望許多底層引擎將這些功能融入未來版本中 ; 對(duì)于那些需要這些功能的業(yè)務(wù)案例來說,具備這些功能的引擎通常會(huì)被業(yè)務(wù)方選擇。
圖 10-34 《Powerful and modular I/O connec‐ tors with Splittable DoFn in Apache Beam》這里舉一個(gè) Beam 里面關(guān)于 SplittableDoFn 的 API 例子,這個(gè) API 可以用來實(shí)現(xiàn)一個(gè)可組合的,可擴(kuò)展的數(shù)據(jù)源。(具體參看 Eugene Kirpichov 在他的文章《 “Powerful and modular I/O connectors with Splittable DoFn in Apache Beam》中描述 [圖 10-34])。它設(shè)計(jì)確實(shí)很有特點(diǎn)且功能強(qiáng)大,目前我們還沒有看到所有底層引擎對(duì)動(dòng)態(tài)負(fù)載均衡等一些更具創(chuàng)新性功能進(jìn)行廣泛支持。然而,我們預(yù)計(jì)這些功能將隨著時(shí)間的推移而持續(xù)加入底層引擎支持的范圍。
-
底層引擎的創(chuàng)新
底層引擎適配可能會(huì)引入底層引擎所獨(dú)特的功能,而 Beam 最初可能并未提供 API 支持。這沒關(guān)系,隨著時(shí)間的推移,已證明其有用性的引擎功能將在 Beam API 逐步實(shí)現(xiàn)。
這里的一個(gè)例子是 Flink 中的狀態(tài)快照機(jī)制,或者我們之前討論過的 Savepoints。 Flink 仍然是唯一一個(gè)以這種方式支持快照的公開流處理系統(tǒng),但是 Beam 提出了一個(gè)圍繞快照的 API 建議,因?yàn)槲覀兿嘈艛?shù)據(jù) Pipeline 運(yùn)行時(shí)優(yōu)雅更新對(duì)于整個(gè)行業(yè)都至關(guān)重要。如果我們今天推出這樣的 API,Flink 將是唯一支持它的底層引擎系統(tǒng)。但同樣沒關(guān)系,這里的重點(diǎn)是隨著時(shí)間的推移,整個(gè)行業(yè)將開始迎頭趕上,因?yàn)檫@些功能的價(jià)值會(huì)逐步為人所知。這些變化對(duì)每個(gè)人來說都是一件好事。
通過鼓勵(lì) Beam 本身以及引擎的創(chuàng)新,我們希望推進(jìn)整個(gè)行業(yè)快速演化,而不用再接受功能妥協(xié)。 通過實(shí)現(xiàn)跨執(zhí)行引擎的可移植性承諾,我們希望將 Beam 建立為表達(dá)程序化數(shù)據(jù)處理流水線的通用語言,類似于當(dāng)今 SQL 作為聲明性數(shù)據(jù)處理的通用處理方式。這是一個(gè)雄心勃勃的目標(biāo),我們并沒有完全實(shí)現(xiàn)這個(gè)計(jì)劃,到目前為止我們還有很長(zhǎng)的路要走。
?
總? ?結(jié)
我們對(duì)數(shù)據(jù)處理技術(shù)的十五年發(fā)展進(jìn)行了蜻蜓點(diǎn)水般的回顧,重點(diǎn)關(guān)注那些推動(dòng)流式計(jì)算發(fā)展的關(guān)鍵系統(tǒng)和關(guān)鍵思想。來,最后,我們?cè)僮鲆淮慰偨Y(jié):
-
MapReduce:可擴(kuò)展性和簡(jiǎn)單性 通過在強(qiáng)大且可擴(kuò)展的執(zhí)行引擎之上提供一組簡(jiǎn)單的數(shù)據(jù)處理抽象,MapReduce 讓我們的數(shù)據(jù)工程師專注于他們的數(shù)據(jù)處理需求的業(yè)務(wù)邏輯,而不是去構(gòu)建能夠適應(yīng)在一大堆普通商用服務(wù)器上的大規(guī)模分布式處理程序。
-
Hadoop:開源生態(tài)系統(tǒng) 通過構(gòu)建一個(gè)關(guān)于 MapReduce 的開源平臺(tái),無意中創(chuàng)建了一個(gè)蓬勃發(fā)展的生態(tài)系統(tǒng),其影響力所及的范圍遠(yuǎn)遠(yuǎn)超出了其最初 Hadoop 的范圍,每年有大量的創(chuàng)新性想法在 Hadoop 社區(qū)蓬勃發(fā)展。
-
Flume:管道及優(yōu)化 通過將邏輯流水線操作的高級(jí)概念與智能優(yōu)化器相結(jié)合,Flume 可以編寫簡(jiǎn)潔且可維護(hù)的 Pipeline,其功能突破了 MapReduce 的 Map→Shuffle→Reduce 的限制,而不會(huì)犧牲性能。
-
Storm:弱一致性,低延遲 通過犧牲結(jié)果的正確性以減少延遲,Storm 為大眾帶來了流計(jì)算,并開創(chuàng)了 Lambda 架構(gòu)的時(shí)代,其中弱一致的流處理引擎與強(qiáng)大一致的批處理系統(tǒng)一起運(yùn)行,以實(shí)現(xiàn)真正的業(yè)務(wù)目標(biāo)低延遲,最終一致型的結(jié)果。
-
Spark: 強(qiáng)一致性 通過利用強(qiáng)大一致的批處理引擎的重復(fù)運(yùn)行來提供無界數(shù)據(jù)集的連續(xù)處理,Spark Streaming 證明至少對(duì)于有序數(shù)據(jù)集的情況,可以同時(shí)具有正確性和低延遲結(jié)果。
-
MillWheel:亂序處理 通過將強(qiáng)一致性、精確一次處理與用于推測(cè)時(shí)間的工具(如水印和定時(shí)器)相結(jié)合,MillWheel 做到了無序數(shù)據(jù)進(jìn)行準(zhǔn)確的流式處理。
-
Kafka: 持久化的流式存儲(chǔ),流和表對(duì)偶性 通過將持久化數(shù)據(jù)日志的概念應(yīng)用于流傳輸問題,Kafka 支持了流式數(shù)據(jù)可重放功能。通過對(duì)流和表理論的概念進(jìn)行推廣,闡明數(shù)據(jù)處理的概念基礎(chǔ)。
-
Cloud Dataflow:統(tǒng)一批流處理引擎 通過將 MillWheel 的無序流式處理與高階抽象、自動(dòng)優(yōu)化的 Flume 相結(jié)合,Cloud Dataflow 為批流數(shù)據(jù)處理提供了統(tǒng)一模型,并且靈活地平衡正確性、計(jì)算延遲、成本的關(guān)系。
-
Flink:開源流處理創(chuàng)新者 通過快速將無序流式數(shù)據(jù)處理的強(qiáng)大功能帶到開源世界,并將其與分布式快照及保存點(diǎn)功能等自身創(chuàng)新相結(jié)合,Flink 提高了開源流處理的業(yè)界標(biāo)準(zhǔn)并引領(lǐng)了當(dāng)前流式處理創(chuàng)新趨勢(shì)。
-
Beam: 可移植性 通過提供整合行業(yè)最佳創(chuàng)意的強(qiáng)大抽象層,Beam 提供了一個(gè)可移植 API 抽象,其定位為與 SQL 提供的聲明性通用語言等效的程序接口,同時(shí)也鼓勵(lì)在整個(gè)行業(yè)中推進(jìn)創(chuàng)新。
可以肯定的說,我在這里強(qiáng)調(diào)的這 10 個(gè)項(xiàng)目及其成就的說明并沒有超出當(dāng)前大數(shù)據(jù)的歷史發(fā)展。但是,它們對(duì)我來說是一系列重要且值得注意的大數(shù)據(jù)發(fā)展里程碑,它共同描繪了過去十五年中流處理演變的時(shí)間軸。自最早的 MapReduce 系統(tǒng)開始,盡管沿途有許多起伏波折,但不知不覺我們已經(jīng)走出來很長(zhǎng)一段征程。即便如此,在流式系統(tǒng)領(lǐng)域,未來我們?nèi)匀幻媾R著一系列的問題亟待解決。正所謂:路漫漫其修遠(yuǎn)兮,吾將上下而求索。
?
譯者簡(jiǎn)介
陳守元(花名:巴真),阿里巴巴高級(jí)產(chǎn)品專家。阿里巴巴實(shí)時(shí)計(jì)算團(tuán)隊(duì)產(chǎn)品負(fù)責(zé)人,2010 年畢業(yè)即加入阿里集團(tuán)參與淘寶數(shù)據(jù)平臺(tái)建設(shè),近 10 年的大數(shù)據(jù)從業(yè)經(jīng)驗(yàn),開源項(xiàng)目 Alibaba DataX 發(fā)起人,當(dāng)前負(fù)責(zé)阿里實(shí)時(shí)計(jì)算產(chǎn)品 Flink 的規(guī)劃與設(shè)計(jì),致力于推動(dòng) Flink 成為下一代大數(shù)據(jù)處理標(biāo)準(zhǔn)。
《Streaming System》一書目前正由阿里巴巴實(shí)時(shí)計(jì)算團(tuán)隊(duì)進(jìn)行翻譯,預(yù)計(jì)今年年底上市,對(duì)流式系統(tǒng)感興趣的同學(xué)可以關(guān)注。
總結(jié)
以上是生活随笔為你收集整理的大数据凉了?No,流式计算浪潮才刚刚开始!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么大数据需要数据湖?
- 下一篇: Nginx 配置文件 nginx.con