談談分布式計算的算子層

jopen 9年前發布 | 18K 次閱讀 布式計算 分布式/云計算/大數據

本文是我對分布式計算的算子這層的一些認識和想法。因為最近自己的開發任務也是這方面相關的,公司內部有自研的類流式計算框架需要做一層算子層。我主要分析的是流式系統上實現算子這一點入手,對比現有計算框架和業界正在開展的項目,分析分析這件事的表面和背后深層的含義,以及可想象空間


趨勢

Yahoo! 的Pig on Storm項目,讓Pig-latin能夠執行在Storm這種流式引擎上,最終使得Pig-latin能夠混用于流式計算和批量計算場景下。應該說,無論是Spark,Summingbird,還是Pig,都在嘗試做同一件事情:借助自己的DSL或原語在流式和批量兩套引擎上表達(近)實時和離線數據處理能力


Spark本身依賴RDD,實現了Spark Streaming這種小批流計算,其DStream就是RDD,所以在Spark上寫批量作業和流式作業API自然是統一的。


Summingbird在API層面統一了Storm上和Hadoop上的作業,對于Hadoop上任務的編寫借助的是Cascading,屬性上看更多的是一種適配的角色,雖然Summingbird也稱為Lambda Architecture的一種解決方案。


總結:表面上看,DSL需要支持不同的計算引擎,以達到算子層面的混用,這是趨勢。那么實現上的難度在哪呢?


挑戰

在流式系統上實現pig-latin這種本身就誕生于批量計算場景里的DSL,對某些關系型操作會有語義層面的不清晰性,具體可以看Pig on Storm初步討論。對于filter,foreach,union,甚至稍微復雜點的需要借助state的distinct,limit,在批量和流式場景下都是沒有歧義的,實現起來不會有太大的區別或難度。但是像兩流做sql語義里的join,或者多流做pig語義里的group,cross的時候,流式上的實現就不一致了,而且這個原語的定義也不同了


在流式系統上實現DSL或者一套FlumeJava,關鍵在能把UDAF給實現了。而要實現UDAF,就涉及到了跨批的事情。這件事情本質上需要引擎的支持,比如Trident有SpoutCoordinator作流控,還具備一定的事務性,那么在你要做跨批之間的UDAF的時候呢,可以借助 Trident的State,也就是輔助存儲,調用persistAggregate這樣的操作來完成。如果引擎不支持的話,比如原生Storm的接口,就沒辦法做流式DSL。


那么像Spark那樣又不同,因為Spark本身不是流式系統,他的Spark Streaming上可以實現DSL,甚至可以和Spark SQL結合起來跑Streaming形式的SQL,原因是Spark是批量計算框架,所以他可以做類流式DSL。


總結:實現上看,流式系統上實現DSL難點在UDAF,本質上是跨批計算。那么流式上的跨批可以抽象為一種怎樣的模式呢?


增量計算

增量計算,理論上可以包含批量計算,流式計算,也包括了迭代計算。怎么理解呢。增量計算可以表達為 newValue = function ( currentValue, oldValue ),而newValue被保存為oldValue與之后新來的currentValue繼續產生關系,而這個不斷傳承下去的oldValue就是增量計算結果。

增量計算和前面提到的流式系統上實現算子有什么關系?這個增量的模型就是跨批計算的一種形式。function可以理解為一個算子,currentValue可以理解為本批計算結果,oldValue可以理解為UDAF的計算結果。

這個模型只有流式系統能實現嗎?不是的,批量計算框架也可以做,大不了newValue每次都落盤嘛。如果Hadoop MR來做這件事情,其實是把每一次MR的數據當作一批,跨批的結果是額外保存的。如果RDD來做這件事情,那就不同了,上述這種模型很適合RDD來做,因為迭代計算可以看成是增量計算的一種,而RDD很擅長構建DAG來完成迭代計算,只是每次計算出來的都是immutable的新RDD。

流式系統怎么實現這種增量計算模型呢?這就是我們組之前老大和同事智慧的結晶了,具體不方便說。其實實現它不是難點,難點是計算框架內需要對oldValue進行容錯。RDD不用擔心容錯,因為有lineage來記錄,大不了可以重算,而且是可以并行的。Storm和Trident也不用擔心容錯,因為他把fail邏輯都交給用戶了!而我們組目前的增量計算引擎完成了這件事情,并且一直在checkpoint的優化上做著努力。

總結:計算模型上,在流式系統上實現增量計算引擎,是實現豐富算子層,做流式SQL的一個必要條件。流式上實現的增量計算模型,有什么本質缺陷嗎?

深入RDD

之前在杭州Spark meetup,分享Spark SQL的時候,我提到過Spark RDD最重要的兩層意義:原語的豐富和數據表示能力前者使得Spark編程很easy,后者使得計算結果做到了reuse,適應了MR模型、迭代計算模型、BSP模型。基于這兩點,Spark Core上可以輕松衍生出SQL產品、機器學習產品、圖計算產品、流計算產品。

反觀流式系統,比如Storm,原語要簡單豐富易用不是難事,問題是你數據能reuse嗎?!reuse有什么優點?拿RDD來說,節省內存空間以及并發的計算能力。RDD在設計之初就是immutable的,而且在計算內部消化掉了MapReduce,而暴露出豐富的Transformation和 Action。在論文中,RDD與DSM(Distributed Shared Memory)也進行了多維度的對比。應該說,Matei在設計RDD之前的參與Hadoop MapReduce源碼的開發經驗,加上當時其他系統內DSM的差異設計,以及Google FlumeJava,微軟DryadLINQ在API層面的理念,最終揉合成了RDD這套東西。現在只有Spark現在實現了它。

最近我在增量計算引擎上實現的算子層,也是參考了FlumeJava,Trident,RDD設計出來的,還在測試中。就像我開頭說的,Pig on Storm這件事情,換引擎是表面。背后意義是算子層面的混用,最終的想象空間是一層統一的DAG,上面承接Pig、Hive、SQL等DSL,下面對接不同的計算系統。實現起來是不困難的,困難點可能不是技術問題。


總結:RDD兩個致命優點,easy to use和數據的reuse,是其他系統難達到的,特別是第二點,也是RDD的精髓所在。


對比Storm

marz做了Storm,ElephentDB之后,按照他的理解在how to beat CAP里提出了一種解決方案。在他提出的lambda achitecture里,Storm的定位在流式處理,而做類似ad-hoc的service layer是HBase。如果換做是我們目前的增量計算框架的愿景的話,我認為,流式和ad-hoc這層有望被增量計算引擎統一。為什么?


Query = Function(All Data)


Data靜,Query動,是ad-hoc計算;Data動,Query靜,是流式計算;Data動,Query動,是持續計算。 Storm處于第二者,增量計算框架可以做到第三者。Storm的拓撲提交是個嚴重問題,等Nimbus拉起bolt和spout的時候,黃花菜都涼了。它的確適合流式計算,為什么呢,因為流式的本質就是消息。Storm抽象的那層拓撲,bolt之間的消息通道,ack機制都很不錯,這層抽象滿足了流式計算,但是work這層以及調度這層遠遠不滿足Query不斷變化而仍需要流式計算的場景。我們現在做的框架將來會滿足這件事情,從此統一了流式、批量、迭代,超越現在的流式計算,不僅僅是StreamSQL,Stream上的DSL都是可以通過算子層來實現的。


總結:Data動,Query動的場景如何統一解決?增量計算想象空間巨大,算子層重要性突顯。


全文完 :)

來自:http://blog.csdn.net/pelick/article/details/39577785

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!