這是數(shù)據(jù)處理引擎的發(fā)電站,它們正競相定義下一個大數(shù)據(jù)時代
當(dāng)涉及到大數(shù)據(jù)時,流計算和它所帶來的實時強大分析的重要性是不可避免的。此外,當(dāng)涉及到流計算時,無法避免該領(lǐng)域最強大的兩種數(shù)據(jù)處理引擎:Spark和Flink。
自2014年以來,Apache Spark的受歡迎程度迅速上升,在某些情況下,它的性能超過了Hadoop MapReduce的三位數(shù),提供了一個統(tǒng)一的引擎,支持所有常見的數(shù)據(jù)處理場景,如批處理、流處理、交互查詢和機器學(xué)習(xí)。憑借其高性能和全面的場景支持,它在大數(shù)據(jù)開發(fā)中繼續(xù)受到早期采用者的青睞。
在Spark出現(xiàn)后不久,Apache Flink作為一個外部挑戰(zhàn)者開始進(jìn)入公眾視野,直到2016年才廣為人知。早期的Spark用戶在實時流處理等場景中遇到可用性問題時,F(xiàn)link提供了一個高級流處理引擎,它支持廣泛的場景以及其他優(yōu)勢。
在他們短暫的競爭中,Spark一直在優(yōu)化它的實時流媒體功能,2.3版本(2月份發(fā)布)引入了連續(xù)處理模型,將流處理延遲降低到毫秒。Flink同樣是一個令人敬畏的創(chuàng)新者,這兩種架構(gòu)中哪一種將最終主導(dǎo)下一代大數(shù)據(jù)計算還有待觀察。
通過對它們各自技術(shù)和用途的綜合分析,本文應(yīng)該有助于闡明這一問題。
大數(shù)據(jù)計算引擎的起源
Hadoop和其他基于mapreduce的數(shù)據(jù)處理系統(tǒng)的出現(xiàn)首先是為了滿足傳統(tǒng)數(shù)據(jù)庫無法滿足的數(shù)據(jù)處理需求。隨著2004年谷歌發(fā)布MapReduce白皮書以來的發(fā)展浪潮,利用Hadoop的開源生態(tài)系統(tǒng)或類似系統(tǒng)處理大數(shù)據(jù)已經(jīng)成為行業(yè)的基本需求。
盡管最近努力降低進(jìn)入門檻,但在開發(fā)自己的數(shù)據(jù)處理系統(tǒng)時,組織不可避免地會遇到一系列問題,常常會發(fā)現(xiàn)從數(shù)據(jù)中獲得價值所需的投資大大超出預(yù)期。
下面的章節(jié)將詳細(xì)介紹這些問題中最普遍的部分,這有助于解釋Spark和Flink繼續(xù)競爭行業(yè)偏好的基礎(chǔ)。
非常陡峭的學(xué)習(xí)曲線
剛接觸大數(shù)據(jù)的人通常會對需要掌握的技術(shù)數(shù)量感到震驚。過去幾十年發(fā)展起來的傳統(tǒng)數(shù)據(jù)庫一般都是為了綜合數(shù)據(jù)處理而構(gòu)建的,而像Hadoop這樣的大數(shù)據(jù)生態(tài)系統(tǒng)需要幾個不同的子系統(tǒng),每個子系統(tǒng)在呈現(xiàn)各種需求場景之前都有自己的專長和優(yōu)勢。
上面的圖片描述了一個典型的lambda架構(gòu)。僅僅展示了兩種場景(批處理和流處理),它已經(jīng)涉及了至少四到五種技術(shù),不包括經(jīng)常需要考慮的替代方案。通過添加實時查詢、交互分析、機器學(xué)習(xí)和其他場景,每種情況都涉及到以不同方式覆蓋重疊區(qū)域的幾種技術(shù)之間的選擇。因此,業(yè)務(wù)通常需要使用許多技術(shù)來支持完整的數(shù)據(jù)處理。再加上研究和選擇,投資者需要消化的信息量是巨大的。
為了了解可用的技術(shù),請考慮以下對大數(shù)據(jù)行業(yè)的概述。
開發(fā)運營效率低下
由于涉及的系統(tǒng)種類繁多,每個系統(tǒng)都有自己的開發(fā)工具和語言,大數(shù)據(jù)的開發(fā)效率在默認(rèn)情況下相當(dāng)有限。由于數(shù)據(jù)需要在多個系統(tǒng)之間傳輸,進(jìn)一步的開發(fā)和操作成本不可避免地會出現(xiàn)。同時,數(shù)據(jù)一致性仍然難以保證。
在許多組織中,超過一半的開發(fā)工作花費在系統(tǒng)之間的數(shù)據(jù)傳輸上。
操作復(fù)雜、數(shù)據(jù)質(zhì)量等問題
多個系統(tǒng),每個系統(tǒng)都需要自己的操作和維護(hù),帶來較高的運行成本,增加系統(tǒng)出錯的可能性。此外,很難保證數(shù)據(jù)的質(zhì)量,而且當(dāng)問題確實出現(xiàn)時,很難跟蹤和解決它們。
最后但并非最不重要的,還有人的問題。在許多情況下,系統(tǒng)的復(fù)雜性意味著對每個子系統(tǒng)的支持和使用必須在不同的部門中實現(xiàn),這些部門并不總是與目標(biāo)和優(yōu)先級保持一致。
到一個解決方案
鑒于這些問題,不難理解Spark的受歡迎程度。在其2014年崛起之時,Spark不僅增強了Hadoop MapReduce的性能,而且還提供了一個通用引擎來支持各種數(shù)據(jù)處理場景。在一個筆記本中看到一個Spark演示程序與上述所有場景一起工作,對于許多開發(fā)人員來說,轉(zhuǎn)向Spark是一個相對容易的決定。因此,Spark作為Hadoop中的MapReduce引擎的完全替代品出現(xiàn)也就不足為奇了。
與此同時,F(xiàn)link的出現(xiàn)是為了在一系列場景中提供更方便的使用,特別是在數(shù)據(jù)流的實時處理方面。
隨著競賽領(lǐng)域的建立,下面的部分將在技術(shù)層面上比較這兩種競爭的框架。
在Spark和Flink中處理引擎
本節(jié)重點討論Spark和Flink引擎的架構(gòu)特性,重點討論它們架構(gòu)的潛力和局限性。和它們的數(shù)據(jù)和處理模型一樣,它們在數(shù)據(jù)處理場景、有狀態(tài)處理方法和編程模型中的重點是不同的。
數(shù)據(jù)模型和處理模型
要了解Spark和Flink中的引擎特性,首先必須檢查它們各自的數(shù)據(jù)模型。
Spark使用彈性分布式數(shù)據(jù)集(RDD)數(shù)據(jù)模型。RDD比MapReduce的文件模型更抽象,它依賴沿襲來確保可恢復(fù)性。RDD通常可以實現(xiàn)為分布式共享內(nèi)存或完全虛擬化。這就是說,當(dāng)下游處理完全是本地的時候,可以優(yōu)化和省略某些中間結(jié)果RDD。這節(jié)省了大量不必要的輸入和輸出,這是Spark早期性能優(yōu)勢的主要基礎(chǔ)。
Spark還在RDD上使用轉(zhuǎn)換(操作符)來描述數(shù)據(jù)處理。每個操作符(如map、filter、join)都會生成一個新的RDD。所有的算子一起構(gòu)成一個有向無環(huán)圖(DAG)。Spark簡單地將邊緣劃分為寬依賴項和窄依賴項。當(dāng)上游和下游數(shù)據(jù)不需要洗牌時,邊緣是一個狹窄的依賴項。在這種情況下,上游和下游算子可以在同一階段進(jìn)行本地處理,可以省去上游結(jié)果RDD的物化。下圖顯示了所涉及的基本概念。
相比之下,F(xiàn)link的基本數(shù)據(jù)模型是由數(shù)據(jù)流組成的。,事件的順序。作為數(shù)據(jù)的基本模型,數(shù)據(jù)流可能不像表或數(shù)據(jù)塊那樣直觀和熟悉,但仍然可以提供一組完全等價的特性。一條小溪可以是一條無限的小溪,是無限的,這是普遍的感知。它也可以是有邊界的有限流,處理這些流等同于批處理。
為了描述數(shù)據(jù)處理,F(xiàn)link在數(shù)據(jù)流上使用操作符,每個操作符生成一個新的數(shù)據(jù)流。在運營商、DAGs和上下游運營商鏈方面,整個模型與Spark模型大致相同。Flink的頂點與Spark中的階段大致相同,將操作符劃分為頂點與上圖中Spark DAG中的劃分階段基本相同。
Spark和Flink在DAG執(zhí)行方面有一個顯著的區(qū)別。在Flink的流執(zhí)行模式中,在一個節(jié)點上處理后的事件輸出可以發(fā)送到下一個節(jié)點進(jìn)行立即處理。這樣執(zhí)行引擎就不會引入任何額外的延遲。相應(yīng)地,所有節(jié)點需要同時運行。相反,Spark的微批處理執(zhí)行與正常的批處理執(zhí)行沒有區(qū)別,只有在上游階段完成微批處理后,下游階段才開始處理其輸出。
在Flink的流執(zhí)行模式中,可以一起傳輸或計算多個事件以提高效率。然而,這純粹是執(zhí)行引擎自行決定的優(yōu)化。它可以獨立地為每個操作符確定,并且不像批處理模型中那樣綁定到數(shù)據(jù)集(如RDD)的任何邊界。它可以為優(yōu)化留下靈活性,同時滿足低延遲需求。
Flink使用異步檢查點機制來實現(xiàn)任務(wù)狀態(tài)的可恢復(fù)性,以確保處理一致性。因此,可以消除數(shù)據(jù)源和輸出之間的整個主處理路徑上的I/O延遲,從而實現(xiàn)更高的性能和更低的延遲。
數(shù)據(jù)處理方案
除了批處理,Spark還支持實時數(shù)據(jù)流處理、交互式查詢、機器學(xué)習(xí)和圖形計算等場景。
實時數(shù)據(jù)流處理和批處理之間的主要區(qū)別是低延遲要求。因為Spark RDD是基于內(nèi)存的,所以可以很容易地將其切割成更小的塊進(jìn)行處理。快速處理這些小塊可以實現(xiàn)低延遲。
如果所有數(shù)據(jù)都在內(nèi)存中并且處理速度足夠快,Spark還可以支持交互式查詢。
Spark的機器學(xué)習(xí)和圖形計算可以看作是不同類別的RDD操作符。Spark提供了一些庫來支持常見的操作,用戶或第三方庫還可以擴(kuò)展并提供更多的操作。值得一提的是,Spark的RDD模型與機器學(xué)習(xí)模型訓(xùn)練的迭代計算非常兼容。從一開始,它就在一些場景中帶來了顯著的性能改進(jìn)。
基于這些特性,Spark本質(zhì)上是一個比Hadoop MapReduce更快的基于內(nèi)存的批處理程序,它使用足夠快的批處理來實現(xiàn)各種場景。
在Flink中,如果輸入數(shù)據(jù)流是有界的,則批處理的效果自然會產(chǎn)生。流處理和批處理之間的區(qū)別僅在于輸入類型,并且獨立于底層實現(xiàn)和優(yōu)化,因此用戶需要實現(xiàn)的邏輯是完全相同的,從而產(chǎn)生一種更清晰的抽象。
Flink還提供了一些庫來支持機器學(xué)習(xí)和圖形計算等場景。在這方面,它與Spark并沒有太大的區(qū)別。
值得注意的是,F(xiàn)link的低級API可以單獨使用Flink集群來實現(xiàn)一些數(shù)據(jù)驅(qū)動的分布式服務(wù)。一些公司使用Flink集群來實現(xiàn)社交網(wǎng)絡(luò)、web爬行和其他服務(wù)。這些用途反映了Flink作為通用計算引擎的多功能性,并得益于Flink的內(nèi)置狀態(tài)支持。
通常,Spark和Flink的目標(biāo)都是在單個執(zhí)行引擎中支持大多數(shù)數(shù)據(jù)處理場景,并且都應(yīng)該能夠?qū)崿F(xiàn)這一點。主要的區(qū)別在于,在某些場景中,它們各自的體系結(jié)構(gòu)可能會受到限制。這種情況的一個值得注意的地方是Spark流的微批處理執(zhí)行模式。Spark社區(qū)應(yīng)該已經(jīng)意識到這一點,并且最近開始致力于持續(xù)處理。我們稍后會回到這個問題。
有狀態(tài)的處理
Flink的另一個非常獨特的方面是在引擎中引入了托管狀態(tài)。要理解托管狀態(tài),我們必須首先從有狀態(tài)處理開始。如果處理事件(或數(shù)據(jù)片段)的結(jié)果只與事件本身的內(nèi)容相關(guān),則稱為無狀態(tài)處理;否則,結(jié)果與之前處理的事件相關(guān),稱為有狀態(tài)處理。任何重要的數(shù)據(jù)處理,例如基本聚合,通常都是有狀態(tài)處理。Flink一直認(rèn)為,如果沒有良好的狀態(tài)支持,就不會有有效的流,因此,托管狀態(tài)和狀態(tài)API很早就被引入了。
通常,有狀態(tài)處理是在流的上下文中考慮的,但是仔細(xì)看看它也會影響批處理。以窗口聚合的常見情況為例,如果批處理數(shù)據(jù)周期大于窗口,則可以忽略中間狀態(tài),用戶邏輯容易忽略這個問題。然而,當(dāng)批處理周期小于窗口時,批處理的結(jié)果實際上依賴于之前處理過的批處理。因為批處理引擎通常看不到這種需求,所以它們通常不提供內(nèi)置狀態(tài)支持,需要用戶手動維護(hù)狀態(tài)。例如,在窗口聚合的情況下,用戶將需要一個中間結(jié)果表來存儲不完整窗口的結(jié)果。因此,當(dāng)用戶縮短批處理周期時,處理邏輯就變得更加復(fù)雜。在結(jié)構(gòu)化流發(fā)布之前,這是早期Spark流用戶的一個常見問題。
另一方面,作為流媒體引擎的Flink從一開始就必須面對這個問題,并引入了托管狀態(tài)作為通用解決方案。除了簡化用戶的工作之外,與用戶實現(xiàn)的解決方案相比,內(nèi)置解決方案還可以實現(xiàn)更好的性能。最重要的是,它可以提供更好的一致性保證。
簡單地說,數(shù)據(jù)處理邏輯中存在一些固有的問題,在批處理中可以忽略或簡化而不影響結(jié)果,但在流處理中會暴露并解決這些問題。因此,在流引擎中以有限流的形式實現(xiàn)批處理,自然會產(chǎn)生正確的結(jié)果,而主要的工作是為了優(yōu)化而在某些領(lǐng)域進(jìn)行專門的實現(xiàn)。相反,小批量模擬流場則會暴露出新的問題。當(dāng)計算引擎沒有一個問題的通用解決方案時,它需要用戶自己解決它。除了狀態(tài)之外,問題還包括維度表更改(如更新用戶信息)、批處理數(shù)據(jù)邊界、延遲到達(dá)的數(shù)據(jù)等等。
編程模型
Spark最初的意圖之一是提供一個統(tǒng)一的編程模型,能夠解決不同用戶的各種需求——這是它投入了大量精力的一個重點。Spark最初的基于rd的API已經(jīng)能夠進(jìn)行各種數(shù)據(jù)處理。后來,為了簡化用戶的開發(fā),在Spark 2.0 (DataFrame = Dataset [Row])中引入并整合了更高級別的DataFrame(在RDD中向結(jié)構(gòu)化數(shù)據(jù)中添加列)和Dataset(向DataFrame列添加類型)。Spark SQL支持也相對較早地引入。隨著特定于場景的api的不斷改進(jìn),比如結(jié)構(gòu)化流以及與機器學(xué)習(xí)和深度學(xué)習(xí)的集成,Spark的api變得非常容易使用,現(xiàn)在已經(jīng)成為該框架最強大的方面之一。
Flink的API遵循了一組類似的目標(biāo)和開發(fā)路徑。Flink和Spark的核心api可以看作是粗略的對應(yīng)。在過去的兩年里,通過對機器學(xué)習(xí)和深度學(xué)習(xí)的集成,Spark的API總體上更加完整。Flink仍然領(lǐng)先于流相關(guān)方面,例如它對水印、窗口和觸發(fā)器的支持。
要點
Spark和Flink都是通用計算引擎,支持非常大規(guī)模的數(shù)據(jù)處理和各種類型的處理。每一篇文章都提供了很多這里沒有涉及的內(nèi)容,比如SQL優(yōu)化和機器學(xué)習(xí)集成。這種比較的主要目的是回顧這兩個系統(tǒng)的基本架構(gòu)和設(shè)計特性。其基本原理是,更實際的做法是通過協(xié)作學(xué)習(xí)來趕上更高級別的功能,而在基本設(shè)計中進(jìn)行更改往往代價更大,也更令人望而卻步。
Spark和Flink不同的執(zhí)行模型之間的最大區(qū)別在于它們對流處理的支持。最初Spark流處理的方法過于簡單,在更復(fù)雜的處理中出現(xiàn)了問題。Spark 2.0中引入的結(jié)構(gòu)化流,清理了流語義,并增加了對事件時處理和端到端一致性的支持。盡管在功能方面仍有許多限制,但它在過去的迭代中取得了相當(dāng)大的進(jìn)展。微批處理執(zhí)行方法仍然存在一些問題,特別是在大范圍內(nèi)的性能問題。最近,由于應(yīng)用程序要求開發(fā)一種連續(xù)處理模式,Spark受到了刺激。2.3版的實驗性版本只支持簡單的類地圖操作。
在最近的Spark+AI峰會上的更新之后,連續(xù)處理似乎已經(jīng)發(fā)展成為一個與Flink的流處理模型非常相似的執(zhí)行引擎。然而,如上圖所示,主要功能仍在繼續(xù)發(fā)展。它們的性能如何,以及將來如何與Spark原來的批處理執(zhí)行引擎集成,還有待觀察。
-
數(shù)據(jù)處理
+關(guān)注
關(guān)注
0文章
613瀏覽量
28631 -
大數(shù)據(jù)
+關(guān)注
關(guān)注
64文章
8908瀏覽量
137799 -
SPARK
+關(guān)注
關(guān)注
1文章
105瀏覽量
19977
發(fā)布評論請先 登錄
相關(guān)推薦
評論