Spark Streaming
人們通常想知道類似的系統(tǒng)如何比較。我們已盡全力將Samza的功能集與其他系統(tǒng)進(jìn)行對比。但是我們不是這些框架的專家,當(dāng)然我們也是完全有偏見的。如果我們有任何東西,請讓我們知道,我們會糾正。
本概述正在比較 Spark Streaming 1.3.1 和 Samza 0.9.0。未來的版本可能會有變化。
Spark Streaming 是使用核心 Apache Spark API 的流處理系統(tǒng)。Samza 和 Spark Streaming 都提供數(shù)據(jù)一致性,容錯性,編程 API 等。Spark 的流媒體方式與 Samza 不同。Samza處理收到的消息,而 Spark Streaming 將流視為一系列確定性批處理操作。Spark Streaming 將流分組為固定持續(xù)時間(如1秒)的批次。每個批處理都表示為彈性分布式數(shù)據(jù)集(RDD)。這些 RDD 的漸進(jìn)序列稱為離散化流(DStream)。
在進(jìn)行比較之前,以下是 Spark Streaming 應(yīng)用程序的簡要概述。如果您已經(jīng)熟悉 Spark Streaming,您可以跳過此部分。Spark Streaming 應(yīng)用程序有兩個主要部分:數(shù)據(jù)接收和數(shù)據(jù)處理。
以下是 Spark Streaming 部署的概述。Spark 有一個 SparkContext(在 SparkStreaming 中,它在驅(qū)動程序中被稱為StreamingContext對象,SparkContext 與集群管理器(例如YARN,Mesos)交談,然后為 Spark 應(yīng)用程序分配資源(即執(zhí)行程序),執(zhí)行程序?qū)⑦\行任務(wù)通過 SparkContext,在 YARN 的上下文中,一個執(zhí)行器相當(dāng)于一個容器,任務(wù)是容器中運行的,驅(qū)動程序在提交作業(yè)(客戶端模式)或應(yīng)用程序管理器(客戶端模式)的客戶機(jī)中運行,集群模式),數(shù)據(jù)接收和數(shù)據(jù)處理都是執(zhí)行器的任務(wù),一個接收器(接收一個輸入流)是一個長期運行的任務(wù)。處理有一堆任務(wù)。所有的任務(wù)都將發(fā)送給可用的執(zhí)行者。
Spark Streaming 保證在一個 DStream 中對 RDD 的有序處理。由于每個 RDD 并行處理,所以在 RDD 內(nèi)沒有保證的順序。這是 Spark 做的一個權(quán)衡設(shè)計。如果要在 RDD 中按順序處理消息,則必須在一個線程中處理它們,這不具有并行性的好處。
Samza 保證按照它們在流的分區(qū)中顯示的順序來處理消息。Samza 還允許您使用 MessageChooser 定義分區(qū)之間的消息的確定性排序。
Spark Streaming 對于不同的數(shù)據(jù)源具有不同的容錯語義。在這里,為了更好的比較,只討論使用 Spark Streaming 與 Kafka 時的語義。在 Spark 1.2中,Spark Streaming 在接收端提供了至少一次語義。在 Spark 1.3中,它采用無接收方式,這提供了一些好處。但是,它仍然不能保證輸出動作的一次性語義。因為副作用的輸出操作可能在作業(yè)失敗時重復(fù),并從檢查點恢復(fù)。如果您的輸出操作中的更新不是冪等或事務(wù)性的(例如發(fā)送到 Kafka 主題的消息),您將獲得重復(fù)的消息。不要被 Spark Streaming 指南中的“一次性語義”所困惑。
Samza 提供了至少一次的郵件傳遞保證。當(dāng)作業(yè)發(fā)生故障時,它重新啟動容器并從檢查點讀取最新的偏移。當(dāng) Samza 的工作從故障中恢復(fù)時,它可能會多次處理一些數(shù)據(jù)。這是因為作業(yè)在最后一個檢查點重新啟動,并且在該檢查點和故障之間已處理的任何消息將再次被處理??梢酝ㄟ^設(shè)置小的檢查點間隔周期來最小化再處理數(shù)據(jù)的數(shù)量。
如果您可以確保冪等更新或事務(wù)更新, Spark Streaming 和 Samza 都可以實現(xiàn)端到端的一次性語義。該鏈接指向 Spark Streaming 頁面,同樣的想法也適用于 Samza。
Spark Streaming 提供一個狀態(tài) DStream,它保持每個鍵的狀態(tài)和一個稱為 updateStateByKey 的轉(zhuǎn)換操作來突變狀態(tài)。每當(dāng)應(yīng)用 updateStateByKey 時,您將獲得一個新狀態(tài)DStream,其中所有狀態(tài)都通過應(yīng)用傳遞給 updateStateByKey 的函數(shù)進(jìn)行更新。這種轉(zhuǎn)換可以作為基本的鍵值存儲,盡管它有一些缺點:
Spark Streaming 定期將狀態(tài)操作(updateStateByKey 和基于窗口的操作)的媒體數(shù)據(jù)寫入 HDFS。在 updateStateByKey 的情況下,在每個檢查點間隔之后,將整個狀態(tài) RDD 寫入HDFS。正如我們在帶有檢查點的內(nèi)存狀態(tài)中提到的,當(dāng)狀態(tài)變大時,將整個狀態(tài)寫入持久存儲是非常昂貴的。
Samza 使用嵌入式鍵值存儲進(jìn)行狀態(tài)管理。這個商店被復(fù)制,因為它是突變的,并支持非常高的吞吐量寫入和閱讀。并且它給你很大的靈活性來決定你想要保持什么樣的狀態(tài)。更重要的是,您還可以插入其他存儲引擎,從而在您可以使用的流處理算法中實現(xiàn)極大的靈活性。在這里可以找到不同類型的國家經(jīng)理方法的良好比較。
狀態(tài)管理的常見用例之一是流式流連接。雖然星火流有加入操作,該操作僅將兩個批次是在相同的時間間隔。它不處理兩個流中的事件不匹配的情況。Spark Streaming 的updateStateByKey 存儲不匹配事件的方法也有一個限制,因為如果不匹配事件的數(shù)量很大,會有一個很大的狀態(tài),這會導(dǎo)致 Spark Streaming 中的無效。雖然 Samza 沒有這個限制。
Spark Streaming的并行性是通過將工作分解成小任務(wù)并將其發(fā)送給執(zhí)行者而實現(xiàn)的。在Spark Streaming中有兩種并行性:在并行處理流中并行化并行處理流:*在接收端,一個輸入DStream 創(chuàng)建一個接收器,一個接收器接收一個輸入數(shù)據(jù)流并作為長時間運行,運行任務(wù) 因此,為了并行化接收過程,您可以根據(jù)某些條件將一個輸入流分解成多個輸入流(例如,如果您正在接收一些分區(qū)的 Kafka 流,則可以根據(jù)分區(qū)拆分此流)。然后,您可以為這些流創(chuàng)建多個輸入 DStream(因此多個接收器),并且接收器將作為多個任務(wù)運行。因此,您應(yīng)該通過增加執(zhí)行人員的核心數(shù)量或增加更多的執(zhí)行人員來提供足夠的資源。然后,如果需要,您可以在處理過程中將所有輸入的 Dstream 組合成一個 DStream。在 Spark 1.3 中,Spark Streaming + Kafka Integration 正在使用無接收方式(directsream)。Spark Streaming 創(chuàng)建一個 RDD,其分區(qū)映射到 Kafka 分區(qū)是一對一的。這簡化了接收機(jī)側(cè)的并行性。*在處理方面,由于DStream是RDD的連續(xù)序列,所以通過正常的RDD操作(如map,reduceByKey,reduceByWindow)可以簡單地實現(xiàn)并行。Spark Streaming + Kafka Integration 正在使用無接收器方法(稱為directSream)。Spark Streaming 創(chuàng)建一個RDD,其分區(qū)映射到Kafka分區(qū)是一對一的。這簡化了接收機(jī)側(cè)的并行性。*在處理方面,由于DStream是RDD的連續(xù)序列,所以通過正常的RDD操作(如map,reduceByKey,reduceByWindow)可以簡單地實現(xiàn)并行。Spark Streaming + Kafka Integration 正在使用無接收器方法(稱為 directSream)。Spark Streaming 創(chuàng)建一個 RDD,其分區(qū)映射到 Kafka 分區(qū)是一對一的。這簡化了接收機(jī)側(cè)的并行性。*在處理方面,由于DStream是RDD的連續(xù)序列,所以通過正常的RDD操作(如map,reduceByKey,reduceByWindow)可以簡單地實現(xiàn)并行。
Samza 的并行性是通過將處理分解成可并行化的獨立任務(wù)來實現(xiàn)的。您可以在一個容器中運行多個任務(wù),或者每個容器只運行一個任務(wù)。這取決于您的工作負(fù)載和延遲要求。例如,如果要快速重新處理流,則可以將容器的數(shù)量增加到每個容器一個任務(wù)。重要的是注意到一個容器只使用一個線程,它映射到一個 CPU。該 設(shè)計嘗試簡化資源管理和作業(yè)之間的隔離。
在 Samza 中,您可以靈活地定義一個任務(wù)所包含的內(nèi)容。例如,在 Kafka 用例中,默認(rèn)情況下,Samza 將具有相同分區(qū) ID 的分區(qū)分組到一個任務(wù)中。這允許不同流之間的容易連接。開箱即用,Samza 還提供了將一個分區(qū)分配給一個任務(wù)的分組策略。這提供了可以使用多少個容器來處理這些輸入流的最大可擴(kuò)展性,并且適用于不需要輸入流分組的非常高容量的作業(yè)。
Spark 流主要是一系列小批處理。使用快速執(zhí)行引擎,它可以達(dá)到低至1秒的延遲(從他們的論文)。從他們的頁面,“塊間隔的推薦最小值約為50 ms,低于此值的任務(wù)啟動開銷可能是一個問題。
如果處理速度比接收速度慢,則數(shù)據(jù)將作為內(nèi)存中的 DStream 排隊,隊列將不斷增加。為了運行健康的 Spark 流應(yīng)用程序,系統(tǒng)應(yīng)該被調(diào)整,直到處理速度與接收速度一樣快。
使用 Apache Kafka 運行時,Samza作業(yè)可能會在低毫秒內(nèi)延遲。它具有不同的緩沖方法。緩沖機(jī)制取決于輸入和輸出系統(tǒng)。例如,當(dāng)使用 Kafka 作為輸入和輸出系統(tǒng)時,數(shù)據(jù)實際上被緩沖到磁盤。這種設(shè)計決定,通過犧牲一點延遲,允許緩沖區(qū)在工作落后于其處理時吸收大量積壓的消息。
Spark Streaming 和 Samza 中有兩種故障:Spark Streaming 中的工作節(jié)點(運行執(zhí)行程序)故障(相當(dāng)于 Samza 中的容器故障)和驅(qū)動程序節(jié)點(運行驅(qū)動程序)故障(相當(dāng)于應(yīng)用程序管理器(AM))失敗 Samza)。
當(dāng) Spark Streaming 中的工作節(jié)點出現(xiàn)故障時,集群管理器將重新啟動它。當(dāng) Samza 中的容器發(fā)生故障時,應(yīng)用程序管理器將與 YARN 一起啟動新的容器。當(dāng) Spark Streaming 中的驅(qū)動程序節(jié)點出現(xiàn)故障時,YARN / Mesos / Spark Standalone 將自動重新啟動驅(qū)動程序節(jié)點。Spark Streaming 可以使用 HDFS 中的檢查點重新創(chuàng)建 StreamingContext。
在薩姆薩,YARN 負(fù)責(zé)處理容錯。當(dāng) Samza 的 AM 失敗時,YARN 將處理重新啟動 AM。如果 AM 重新啟動,Samza 將重新啟動所有的容器。當(dāng)集裝箱發(fā)生故障時,AM 將打開一個新的集裝箱。
Spark 有一個 SparkContext 對象與群集管理器通信,然后為應(yīng)用程序分配資源。目前,Spark 支持三種類型的集群管理器:Spark獨立,Apache Mesos和Hadoop YARN。除此之外,Spark 還有一個用于在 Amazon EC2 中啟動的腳本。
Samza 目前支持 YARN 和本地執(zhí)行。還有 Mesos 支持正在整合。
Spark Streaming 和 Samza 有相同的隔離。Spark Streaming 取決于集群管理器(例如 Mesos 或 YARN),Samza 依靠 YARN / Mesos 來提供處理器隔離。不同的應(yīng)用程序在不同的JVM 中運行。除非寫入外部存儲器,否則數(shù)據(jù)不能在不同應(yīng)用程序之間共享。由于 Samza 提供開箱即用的 Kafka 集成,因此很容易重用其他 Samza 作業(yè)的輸出(見這里)。
Spark Streaming 是用 Java 和 Scala 編寫的,它提供 Scala,Java 和 Python API。
Samza 是用 Java 和 Scala 編寫的,并且有一個 Java API。
在 Spark Streaming 中,您將使用 DSL API 構(gòu)建整個處理圖,并將整個圖形部署為一個單元。該圖中的節(jié)點之間的通信(以 DStreams 的形式)由框架提供。那就像風(fēng)暴一樣。Samza 是完全不同的 - 每個工作只是一個消息處理器,并且沒有框架支持拓?fù)?。處理任?wù)的輸出總是需要返回到消息代理(例如 Kafka)。
Samza 設(shè)計的一個積極的后果是,工作的產(chǎn)出可以被多個不相關(guān)的工作所消耗,這些工作可能由不同的團(tuán)隊運行,而這些工作通過 Kafka 的緩沖來相互隔離。Storm 和 Spark Streaming 的框架內(nèi)部流并不是這樣。
雖然 Storm / Spark Streaming 工作原則上可以將其輸出寫入消息代理,但框架并沒有真正使這個簡單。似乎 Storm / Spark 不是以一種拓?fù)漭敵鰹榱硪煌負(fù)漭斎氲姆绞绞褂玫?。相比之下,在薩薩,這種使用模式是標(biāo)準(zhǔn)的。
Spark 有一個活躍的用戶和開發(fā)人員社區(qū),最近發(fā)布了1.3.1版本。它有一個列表的公司,在其 Powered by 頁面使用它。由于 Spark 包含 Spark Streaming,Spark SQL,MLlib,GraphX 和 Bagel,因此很難告訴列表中的哪些公司實際上是使用 Spark Streaming,而不僅僅是 Spark。
Samza 還很年輕,但剛剛發(fā)布了0.9.0版本。它有一個敏感的社區(qū),正在積極發(fā)展。也就是說,它是建立在像 YARN 和 Kafka 這樣的固體系統(tǒng)上。Samza 在 LinkedIn 和其他公司被大量使用。我們希望別人也會覺得有用。
更多建議: