例如Kafka已經(jīng)提供了可以通過低延遲方式訪問的數(shù)據(jù)存儲副本,此外還可以為每個(gè)數(shù)據(jù)分區(qū)提供非常易用且低成本的多訂閱者模型。所有輸出內(nèi)容,包括中間態(tài)的結(jié)果都可寫入到Kafka,并可被下游步驟獨(dú)立使用。
這種對Kafka的緊密依賴在很多方面類似于MapReduce引擎對HDFS的依賴。雖然在批處理的每個(gè)計(jì)算之間對HDFS的依賴導(dǎo)致了一些嚴(yán)重的性能問題,但也避免了流處理遇到的很多其他問題。
Samza與Kafka之間緊密的關(guān)系使得處理步驟本身可以非常松散地耦合在一起。無需事先協(xié)調(diào),即可在輸出的任何步驟中增加任意數(shù)量的訂閱者,對于有多個(gè)團(tuán)隊(duì)需要訪問類似數(shù)據(jù)的組織,這一特性非常有用。多個(gè)團(tuán)隊(duì)可以全部訂閱進(jìn)入系統(tǒng)的數(shù)據(jù)話題,或任意訂閱其他團(tuán)隊(duì)對數(shù)據(jù)進(jìn)行過某些處理后創(chuàng)建的話題。這一切并不會對數(shù)據(jù)庫等負(fù)載密集型基礎(chǔ)架構(gòu)造成額外的壓力。
直接寫入Kafka還可避免回壓(Backpressure)問題?;貕菏侵府?dāng)負(fù)載峰值導(dǎo)致數(shù)據(jù)流入速度超過組件實(shí)時(shí)處理能力的情況,這種情況可能導(dǎo)致處理工作停頓并可能丟失數(shù)據(jù)。按照設(shè)計(jì),Kafka可以將數(shù)據(jù)保存很長時(shí)間,這意味著組件可以在方便的時(shí)候繼續(xù)進(jìn)行處理,并可直接重啟動(dòng)而無需擔(dān)心造成任何后果。
Samza可以使用以本地鍵值存儲方式實(shí)現(xiàn)的容錯(cuò)檢查點(diǎn)系統(tǒng)存儲數(shù)據(jù)。這樣Samza即可獲得“至少一次”的交付保障,但面對由于數(shù)據(jù)可能多次交付造成的失敗,該技術(shù)無法對匯總后狀態(tài)(例如計(jì)數(shù))提供精確恢復(fù)。
Samza提供的高級抽象使其在很多方面比Storm等系統(tǒng)提供的基元(Primitive)更易于配合使用。目前Samza只支持JVM語言,這意味著它在語言支持方面不如Storm靈活。
總結(jié)
對于已經(jīng)具備或易于實(shí)現(xiàn)Hadoop和Kafka的環(huán)境,Apache Samza是流處理工作負(fù)載一個(gè)很好的選擇。Samza本身很適合有多個(gè)團(tuán)隊(duì)需要使用(但相互之間并不一定緊密協(xié)調(diào))不同處理階段的多個(gè)數(shù)據(jù)流的組織。Samza可大幅簡化很多流處理工作,可實(shí)現(xiàn)低延遲的性能。如果部署需求與當(dāng)前系統(tǒng)不兼容,也許并不適合使用,但如果需要極低延遲的處理,或?qū)?yán)格的一次處理語義有較高需求,此時(shí)依然適合考慮。
混合處理系統(tǒng):批處理和流處理
一些處理框架可同時(shí)處理批處理和流處理工作負(fù)載。這些框架可以用相同或相關(guān)的組件和API處理兩種類型的數(shù)據(jù),借此讓不同的處理需求得以簡化。
如你所見,這一特性主要是由Spark和Flink實(shí)現(xiàn)的,下文將介紹這兩種框架。實(shí)現(xiàn)這樣的功能重點(diǎn)在于兩種不同處理模式如何進(jìn)行統(tǒng)一,以及要對固定和不固定數(shù)據(jù)集之間的關(guān)系進(jìn)行何種假設(shè)。
雖然側(cè)重于某一種處理類型的項(xiàng)目會更好地滿足具體用例的要求,但混合框架意在提供一種數(shù)據(jù)處理的通用解決方案。這種框架不僅可以提供處理數(shù)據(jù)所需的方法,而且提供了自己的集成項(xiàng)、庫、工具,可勝任圖形分析、機(jī)器學(xué)習(xí)、交互式查詢等多種任務(wù)。
Apache Spark
Apache Spark是一種包含流處理能力的下一代批處理框架。與Hadoop的MapReduce引擎基于各種相同原則開發(fā)而來的Spark主要側(cè)重于通過完善的內(nèi)存計(jì)算和處理優(yōu)化機(jī)制加快批處理工作負(fù)載的運(yùn)行速度。
Spark可作為獨(dú)立集群部署(需要相應(yīng)存儲層的配合),或可與Hadoop集成并取代MapReduce引擎。
批處理模式
與MapReduce不同,Spark的數(shù)據(jù)處理工作全部在內(nèi)存中進(jìn)行,只在一開始將數(shù)據(jù)讀入內(nèi)存,以及將最終結(jié)果持久存儲時(shí)需要與存儲層交互。所有中間態(tài)的處理結(jié)果均存儲在內(nèi)存中。
雖然內(nèi)存中處理方式可大幅改善性能,Spark在處理與磁盤有關(guān)的任務(wù)時(shí)速度也有很大提升,因?yàn)橥ㄟ^提前對整個(gè)任務(wù)集進(jìn)行分析可以實(shí)現(xiàn)更完善的整體式優(yōu)化。為此Spark可創(chuàng)建代表所需執(zhí)行的全部操作,需要操作的數(shù)據(jù),以及操作和數(shù)據(jù)之間關(guān)系的Directed Acyclic Graph(有向無環(huán)圖),即DAG,借此處理器可以對任務(wù)進(jìn)行更智能的協(xié)調(diào)。
為了實(shí)現(xiàn)內(nèi)存中批計(jì)算,Spark會使用一種名為Resilient Distributed Dataset(彈性分布式數(shù)據(jù)集),即RDD的模型來處理數(shù)據(jù)。這是一種代表數(shù)據(jù)集,只位于內(nèi)存中,永恒不變的結(jié)構(gòu)。針對RDD執(zhí)行的操作可生成新的RDD。每個(gè)RDD可通過世系(Lineage)回溯至父級RDD,并最終回溯至磁盤上的數(shù)據(jù)。Spark可通過RDD在無需將每個(gè)操作的結(jié)果寫回磁盤的前提下實(shí)現(xiàn)容錯(cuò)。