流式計算
大多數的流式計算引擎(比如storm、spark streaming等)都僅僅關注流數據的計算方面:比如使用一個map函數對一個流中每條數據都進行轉換,或者是用reduce函數對一批數據進行聚合。但是,實際上在大部分的流式計算應用中,遠遠不只是需要一個流式計算引擎那么簡單。相反的,流式計算僅僅在流式應用中占據一個部分而已。因此現在出現了一個新的名詞,叫做持續(xù)計算/應用,continuous application。比如以下一些持續(xù)應用的例子:
- 更新需要以服務形式實時提供出去的數據:例如,我們可能需要更新一份數據,然后其他用戶會通過web應用來實時查詢這些數據。這種情況下,一個技術難題就是實時計算應用如何與實時數據服務進行交互,比如說,當實時計算應用在更新數據的時候,如果用戶通過實時數據服務來進行查詢,此時該如何處理?因此為了處理這種場景下的技術難題,就必須以一個完整的持續(xù)計算應用的方式來構建整個系統(tǒng),而不是站在實時計算的角度,僅僅考慮實時更新數據。
- 實時ETL(Extract、Transform和Load):實時計算領域一個常見的應用就是,將一個存儲系統(tǒng)中的數據轉換后遷移至另外一個存儲系統(tǒng)。例如說,將JSON格式的日志數據遷移到Hive表中。這種場景下的技術難題就在于,如何與兩邊的存儲系統(tǒng)進行交互,從而保證數據不會丟失,同時也不會發(fā)生重復。這種協(xié)調邏輯是非常復雜的。
- 為一個已經存在的批量計算作業(yè)開發(fā)一個對應的實時計算作業(yè):這個場景的技術難題在于,大多數的流式計算引擎都無法保證說,它們計算出的結果是與離線計算結果相匹配的。例如說,有些企業(yè)會通過實時計算應用來構建實時更新的dashboard,然后通過批量計算應用來構建每天的數據報表,此時很多用戶就會發(fā)現并且抱怨,離線報表與實時dashboard的指標是不一致的。
- 在線機器學習:這類持續(xù)計算應用,通常都包含了大型的靜態(tài)數據集以及批處理作業(yè),還有實時數據流以及實時預測服務等各個組件。
以上這些例子就表明了在一個大型的流式計算應用中,流式計算本身其實只是占據了一個部分而已,其他部分還包括了數據服務、存儲以及批處理作業(yè)。但是目前的現狀是,幾乎所有的流式計算引擎都僅僅是關注自己的那一小部分而已,僅僅是做流式計算處理。這就使得開發(fā)人員需要去處理復雜的流式計算應用與外部存儲系統(tǒng)之間的交互,比如說管理事務,同時保證他們的流式計算結果與離線批處理計算結果保持一致。這就是目前流式計算領域急需要解決的難題與現狀。
持續(xù)計算應用
持續(xù)計算應用可以定義為,對數據進行實時處理的整套應用系統(tǒng)。spark社區(qū)希望能夠讓開發(fā)人員僅僅使用一套api,就可以完整持續(xù)計算應用中各個部分涉及的任務和操作,而這各個部分的任務和操作目前都是通過分離的單個系統(tǒng)來完成的,比如說實時數據查詢服務,以及與批處理作業(yè)的交互等。舉例來說,未來對于解決這些問題的一些設想如下:
- 更新那些需要被實時提供服務的數據:開發(fā)人員可以開發(fā)一個spark應用,來同時完成更新實時數據,以及提供實時數據查詢服務,可能是通過jdbc相關接口來實現。也可以通過內置的api來實現事務性的、批量的數據更新,對一些諸如mysql、redis等存儲系統(tǒng)。
- 實時ETL:開發(fā)人員僅僅需要如同批處理作業(yè)一樣,開發(fā)一樣的數據轉換操作,然后spark就可以自動完成針對存儲系統(tǒng)的操作,并且保證數據的一次且僅一次的強一致性語義。
- 為一個批處理作業(yè)開發(fā)一個實時版本:spark可以保證實時處理作業(yè)與批處理作業(yè)的結果一定是一致的。
-
在線機器學習:機器學習的api將會同時支持實時訓練、定期批量訓練、以及實時預測服務。
持續(xù)計算應用.png
Structured Streaming
Spark 2.0中,引入的structured streaming,就是為了實現上述所說的continuous application,也就是持續(xù)計算的。首先,structured streaming是一種比spark更高階的api,主要是基于spark的批處理中的高階api,比如dataset/dataframe。此外,structured streaming也提供很多其他流式計算應用所無法提供的功能:
- 保證與批處理作業(yè)的強一致性:開發(fā)人員可以通過dataset/dataframe api以開發(fā)批處理作業(yè)的方式來開發(fā)流式處理作業(yè),進而structured streaming可以以增量的方式來運行這些計算操作。在任何時刻,流式處理作業(yè)的計算結果,都與處理同一份batch數據的批處理作業(yè)的計算結果,是完全一致的。而大多數的流式計算引擎,比如storm、kafka stream、flink等,是無法提供這種保證的。
- 與存儲系統(tǒng)進行事務性的整合:structured streaming在設計時就考慮到了,要能夠基于存儲系統(tǒng)保證數據被處理一次且僅一次,同時能夠以事務的方式來操作存儲系統(tǒng),這樣的話,對外提供服務的實時數據才能在任何時刻都保持一致性。目前spark 2.0版本的structured streaming,僅僅支持hdfs這一種外部存儲,在未來的版本中,會加入更多的外部存儲的支持。事務性的更新是流式計算開發(fā)人員的一大痛點,其他的流式計算引擎都需要我們手動來實現,而structured streaming希望在內核中自動來實現。
- 與spark的其他部分進行無縫整合:structured steaming在未來將支持基于spark sql和jdbc來對streaming state進行實時查詢,同時提供與mllib進行整合。spark 2.0僅僅開始做這些整合的工作,在未來的版本中會逐漸完善這些整合。
除了這些獨一無二的特性以外,structured streaming還會提供其他feature來簡化流式應用的開發(fā),例如對event time的支持,從而可以自動處理延遲到達的數據,以及對滑動窗口和會話的更多的支持。目前structured streaming還停留在beta階段,因此官方聲明,僅供用戶學習、實驗和測試。
Structured Streaming的未來
spark官方對structured streaming未來的計劃是非常有野心的:希望spark的所有組件(core、sql、dataset、mllib等)都能夠通過structured steaming,以增量的方式來運行,進而支持更豐富的實時計算操作。structured streaming會設計為讓其計算結果與批處理計算結果是強一致的。大數據用戶的一個非常大的痛點,就是需要一個完全統(tǒng)一的編程接口。例如說,之前用戶進行大數據開發(fā)時,需要整合使用多種計算引擎,比如mapreduce來進行etl,hive來執(zhí)行sql查詢,giraph來進行圖計算,storm來進行實時計算,等等。而spark則可以完全統(tǒng)一這些操作。此外,structured streaming也希望能夠完全涵蓋一個持續(xù)計算應用中的方方面面。
Structured Streaming與其他流式計算應用的對比
| 屬性 | Structured Streaming | Spark Streaming | Apache Storm | Apache Flink | Kafka Stream | Google Dataflow |
|---|---|---|---|---|---|---|
| Streaming API | 增量執(zhí)行批處理計算 | 基于批處理計算引擎 | 與批處理無關 | 與批處理無關 | 與批處理無關 | 基于批處理計算引擎 |
| 基于數據位置前綴的計算完整性的保證 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| 一致性語義 | exactly once | exactly once | exactly once | exactly once | at least once | exactly once |
| 事務性操作存儲支持 | 支持 | 部分支持 | 部分支持 | 部分支持 | 不支持 | 不支持 |
| 交互式查詢 | 支持 | 支持 | 支持 | 不支持 | 不支持 | 不支持 |
| 與靜態(tài)數據進行join | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
