質疑Lambda架構

banq發表於2014-07-04
Google和Twitter剛釋出它們綜合實時流處理和批處理的Lambda架構,LinkedIn的Jay Kreps則對這種架構提出了質疑,指出實時處理和批處理其實是兩種正規化,將它們硬生生捆綁在一起會犯ORM框架一樣的錯誤,並且提出一種類似EventSourcing或CQRS架構思路只要使用一個實時流處理框架解決兩種框架捆綁在一起的問題。以下為大意翻譯,原文見這裡

Storm 作者Nathan Marz 發表了Lambda Architecture (見:How to beat the CAP theorem如何打敗CAPLambda架構兩篇文章). Lambda Architecture是一個基於MapReduce 和 Storm 建立流式處理的應用,這已經被證明是一個非常令人激動的流行想法,LinkedIn也使用 Kafka 和 Samza 實現實時大資料處理,。

[img index=1]

這種方式對於不可變的記錄序列工作得很好,將這些不可變記錄截獲後並行地送進批處理系統和流處理系統. 實現邏輯轉換兩次,一次是在批處理系統,另外一次是在流處理系統,然後在查詢時間將兩個系統的結果混合在一起產生一個完整的響應結果。

在這裡有許多變數,例如,你能使用Kafka, Storm, 和 Hadoop, 人們經常使用兩個不同的資料庫儲存輸出表,一個是為實時最佳化的,另外一個是為批處理更新最佳化的。

Lambda 架構是定位建立複雜非同步的需要低延遲執行的轉換場合。典型案例是建設一個推薦系統,需要抓取各種資料來源,處理輸入,索引 排序 任何儲存便於讀取處理結果。

我已經在LinkedIn建立這樣一個大資料實時系統和pipeline系統,但這不是我喜歡的風格,下面我談談它的優缺點,然後表達我喜歡的風格。

Lambda架構的優點

我喜歡Lambda 架構注重輸入資料的不可變性,我認為建模一個從原始輸入到系列過程的資料轉換必須遵照紀律會有很多好處。這能建立一個可跟蹤的大型MapReduce工作流,讓你可以獨立除錯每個階段。
我也喜歡Reprocessing 重新處理資料,也就是將輸入資料再計算一次輸出,只要你的程式碼變化,你需要重新計算一下結果,以便檢視程式碼對資料處理結果的影響。

那麼程式碼為什麼會變化呢?也許你的應用在演進,你需要重新計算輸出一些新的欄位。或者你發現Bug並訂正了它。無論什麼原因,只要程式碼變化你都需要重新產生你的輸出。

有很多針對Lambda Architecture反對意見,他們認為流式實時處理與批處理本質上類似,沒有後者強大,經常會丟失資料,不穩定,流式技術是沒有現在批處理計數成熟,但沒有理由認為流處理系統不能如同一個批處理系統提供強大的語義保證。

lambda架構的缺點
Lambda Architecture 的問題是改變程式碼後需要重新在兩個複雜的分散式系統中再次處理輸出結果是非常痛苦的,而且我不認為這個問題能夠解決。

為什麼流式處理系統不能自己提高到處理整個資料,不需要藉助批處理框架?首先得有一種語言框架是基於實時和批處理兩種模型的抽象,你可以使用這樣高階框架程式設計,它會編譯到流處理或MapReduce, Summingbird 是這樣的一個框架(見http://www.jdon.com/46501
). 但是我還是不認為它解決了問題。

最終即使你可以避免兩次編碼。在兩個系統中執行和除錯程式碼的負擔也是比較高的。任何抽象只能提供兩個系統交叉部分的共同特點,更糟糕的是,致力於發明一種新的超級框架會脫離Hadoop強大的生態圈 (Hive, Pig, Crunch, Cascading, Oozie, etc).

以類推方式,想想跨資料庫ORM框架臭名昭著的困難,試圖跨越這兩個系統提供一個近似標準介面語言也會如此,試圖在兩個不同程式設計正規化的頂部建立一個抽象層是非常難的。


LinkedIn的經驗
我們已經在LinkedIn透過數輪實踐。我們已經建立了混合各種Hadoop架構和甚至提供一個特定領域的API(DSL),允許程式碼 “透明”的執行在實時系統或在Hadoop上。這些方法能夠工作,但不是很好或具有生產性。保持兩個不同系統的程式碼完全同步,真的,真的很難。該API是隱藏了底層框架。這樣就不需要深入Hadoop和實時的知識就能加入的新的需求。

關於使用類似MapReduce這樣的批處理框架我的建議是:如果你對延遲(效能)很敏感,你可以使用流處理框架,否則就不要試圖將兩者混合一起使用。

那麼Lambda Architecture激動點在哪裡呢? 我認為那是因為人們日益迫切需要構建一個複雜的低延時的處理系統,一種是可伸縮擴充套件的高延遲批處理系統只能處理歷史資料,而低延遲的流式處理系統並不能重複處理產生結果,透過橫跨這兩個系統放在一起,他們就能得到一個有效的解決方案。
雖然這是有痛苦的,但是Lambda Architecture也是解決了重要問題,否則就會被普遍忽視,但是我不認為這是一個新的正規化,或代表大資料未來。這只是一個臨時狀態,會有更好的替代。

替代方案
我認為首先考慮下面問題:為什麼流式處理系統不能提高到能處理整個領域問題?為什麼需要和另外一個批處理系統攪和在一起?為什麼你不能既做實時流處理也能實現在程式碼變化時進行重複處理reprocessing?流處理系統已經有很好的並行機制,為什麼不透過提高並行來實現重複處理reprocessing和很快地重新播放歷史?答案是你能做這些,這就是我認為可以有更好替代的理由。

有人會說流式處理對於歷史資料的高吞吐量會力不從心,但是我認為這是因為他們使用系統的限制或可伸縮性不夠或不能保持歷史資料。那麼流式系統如何實現重複處理reprocessing呢?我的答案很簡單:
使用 Kafka等類似系統保留住你要重複處理的完整日誌資料,並且允許它有多個訂閱者,比如你要重複處理30天資料,你就讓Kafka保留到30天。

當你要開始再次處理reprocessing資料時,你只要從你流式處理job第二個例項開始處理你的保留資料,但是這次輸出資料是直接輸出到一個新的輸出表,當這第二個job例項完成後,切換到應用從這個新表中讀取,然後停止這個job的老版本執行,再刪除剛才的輸出表。

不像Lambda Architecture,,這個設計只是在你程式碼改變時實現重複處理,也就是重新計算你的結果. 你需要啟動並行機制讓這個工作更快些。

[img index=2]

我們可以稱為這個架構為Kappa Architecture, 我們已經有文件說明如何使用Samza實現重複處理reprocessing 架構的 。

實際上這個主意和Kafka一點也沒有關係. 你可以使用有序保留長時間資料的介質來替代如HDFS或某些資料庫. 如果熟悉Event Sourcing 或 CQRS的人不會感到陌生。

我們在使用Samza已經這樣成熟執行一段時間,這個方案真正的優勢不是效率,而是讓人們在一個單一的處理框架下開發,測試,除錯,作業系統。所以,如果簡單是重要的,那麼可以作為Lambda架構的替代。

相關:

Lambda架構

如何打敗CAP

Twitter基於時間流的聚合設計

Google使用Pipeline統一了大資料批處理和流處理

相關文章