現如今,實時或近實時處理大數據的分布式計算系統的確有不少。本文對來自Apache的三個處理框架進行一個簡短的描述,并從整體上對它們進行快速的比較,了解它們的相似和差異點。
Apache Storm在Storm中,用戶需設計一個實時計算圖,即拓撲(Topology),并將其部署到集群上。Storm集群的主節點會將代碼分發至工作節點來執行該拓撲。在一個拓撲之中,數據流以只讀Key-Value對集合的形式存在,稱之為元組(Tuple),數據流通過Spout形成元組,Bolt對元組進行變換(如聚合、過濾等)。另外, Bolt可以串聯起來,以處理流水線的形式將數據傳遞到下一個Bolt。
Apache SparkSpark Streaming(一個基于Spark核心接口的擴展項目)并不是像Storm那樣,一次處理一個數據流。取而代之地,Spark Streaming在處理前將數據流進行分片,按照時間間隔形成小的批處理任務。對于持續數據流的抽象,Spark稱之為DStream(即Discretized Stream,離散數據流)。一個DStream是一個由RDD(ResilientDistributed Datasets,彈性分布式數據集)構成的微批處理任務。RDD是一個分布式集合,對其可以進行多種并行函數操作、指定時間窗口內的數據轉換操作(窗口計算)等。
Apache SamzaSamza的流計算處理策略是,對接收到的消息逐一、即時處理。Samza的流計算原語并非是上文中提到的元組(Tuple)或離散數據流(DStream),而稱之為消息(Message)。數據流被分成多個分片(Partition),每個分片是由多個只讀消息構成的有序序列,其中每條消息會有一個唯一標識,即偏移量(Offset)。Samza同樣支持批處理任務(Batching),比如對同一個數據流分片中的若干條消息進行消費。Samza的執行引擎和流處理模塊均是插件化可插拔的,Samza通常依賴于Hadoop的YARN(Yet Another Resource Negotiator,另一個資源協調器)組件和Apache Kafka項目。
共同點以上三種實時計算系統均是開源、低延遲、分布式、可擴展以及容錯的。它們具有并行執行流處理任務的功能,并將任務分布到計算集群中,提供故障切換的能力。而且,他們均提供簡單接口,對底層復雜的實現進行了抽象和封裝。
三個框架使用了不同的術語來描述類似的概念:
Apache |
Storm |
Spark |
Samza |
流式數據數據源(S) |
Spouts |
Receivers |
Consumers |
流式數據原語(P) |
Tuple |
DStream |
Message |
流計算(C) |
Bolts |
變換(Tranformations) 窗口操作(Window Operations) |
任務(Tasks) |
下表總結了三個系統的一些不同點:
Apache |
Storm |
Spark |
Samza |
送達語義 |
至少送達一次(使用Trident接口能實現精確一次) |
有且只有一次(某些發生故障的場景除外) |
至少送達一次 |
狀態管理 |
無狀態管理(自行實現或使用Trident接口) |
有狀態管理(將狀態持久化到存儲中) |
有狀態管理(內置Key-Value存儲) |
延遲 |
亞秒級 |
秒級(依賴于批處理大小) |
亞秒級 |
語言支持 |
JVM語言,Ruby,Python,Javascript,Perl
|
Scala,Java,Python |
僅支持JVM語言(如Scala,Java) |
關于送達模式,通常有以下三類:
1. 至多送達一次:消息可能丟失。這通常不是想要的結果。
2. 至少送達一次:消息可能會被多次投遞(無丟失,但可能重復)。對于許多應用場景不錯。
3. 有且只有一次:每條消息只會投遞一次(無丟失,無重復)。這是一個理想的結果,但很多場景均難以保證。
需要注意的另一方面是關于狀態管理(state management)的。對于狀態的存儲是有不同策略的。Spark Streaming將數據寫到分布式文件系統上(如HDFS)。Samza使用內置的Key-Value存儲。而Storm,則要么在用戶應用層對自身的狀態進行管理,要么使用更高的接口抽象即Trident。
用例以上三種框架均是高效處理持續化、海量實時數據的不錯之選。三者選其一怎么選呢?這并無定規,有幾條意見僅供參考。
如果你想要一個能夠支持增量計算的高速事件處理系統,Storm是不錯的選擇。如果你的進一步需求是按需進行分布式計算,而客戶端會同步等待結果的返回,那么分布式RPC(RPC)開箱即用,效果不錯。最后一條也是重要的一條是Storm使用了Apache Thrift庫,你可以使用任何語言來寫拓撲。如果你需要對狀態進行持久化或者要求有且只有一次的送達保證,那么就看一看更高層次的接口Trident,該接口提供微批處理(micro-batching)的功能。
使用Storm框架的公司有:Twitter,雅虎,Spotify,The Weather Channel等。提到微批處理,如果你要求內置狀態管理的計算、有且只有一次的送達保證、并不在意稍微高一些的延遲,那么應當考慮Spark Streaming。尤其是你打算做圖計算、機器學習或使用SQL接口,Spark Streaming是不錯的選擇。Apache Spark軟件棧支持將流計算與多種庫(如Spark SQL、MLlib、GraphX)結合,并提供方便統一的編程模型。有必要指出的一點是流計算算法(如K-means算法)能夠使用Spark實時地加速決策。
使用Spark的公司有:亞馬遜,雅虎,NASA JPL,eBay,百度等。
如果你有大量的狀態需要處理(如每個分片多達幾個GB),Samza能夠將存儲和處理盡可能的集中到同一機器上,進而允許即使在狀態超出內存的情況下也能正常工作。該框架還提供可插拔的API以提高其靈活性:其默認的執行引擎、消息隊列和存儲引擎均可被按照用戶想法進行替換。此外,如果你的應用場景是不同的團隊使用不同的代碼來處理大量的數據,Samza的粗粒度任務特性則特別適合,因為他們可以在連鎖反應最小化的前提下進行添加或刪除。
使用Samza的公司有:LinkedIn,Intuit,Metamarkets,Quantiply,Fortscale等。結語對于三個頂級的Apache項目,本文僅作淺嘗輒止。并未對它們的大量特性和不同之處做進一步描述。不過,一定要記得上面的比較是有局限性的,因為這些系統會一直演化和進步。