帶有Apache Spark的Lambda架構

目標
市場上的許多玩家已經建立了成功的MapReduce工作流程來每天處理以TB計的歷史數據。但是誰願意等待24小時才能獲得最新的分析結果?這篇博文將向您介紹旨在利用批處理和流處理方法的Lambda架構。我們將利用Apache Spark(Core,SQL,Streaming),Apache Parquet,Twitter Stream等實時流數據快速訪問歷史數據。還包括清晰的代碼和直觀的演示!

Apache Hadoop:簡史
Apache Hadoop的豐富歷史始於2002年。Hadoop由Doug Cutting創建,Doug Cutting是Apache Lucene(一個被廣泛使用的文本搜索庫)的創建者。Hadoop起源於Apache Nutch,一個開源的網絡搜索引擎,它本身就是Lucene項目的一部分。它在10年前成爲一個獨立的項目。

因此,大量客戶實施了有效的基於Hadoop的M/R處理管道。現實生活中有一些很好的例子:

Oozie編排的工作流程每天運行並處理高達150 TB的數據以生成分析結果
bash管理的工作流程每天運行並處理高達8 TB的數據以生成分析結果
現在是2016年!
商業現實已經發生了變化,所以現在更快做出的決定更有價值。除此之外,技術也在不斷髮展。Kafka,Storm,Trident,Samza,Spark,Flink,Parquet,Avro,Cloud providers等都是工程師和企業廣泛採用的流行語。

因此,現代基於Hadoop的M/R管道(使用Kafka,Avro和數據倉庫等現代二進制格式,即Amazon Redshift,用於臨時查詢)可能採用以下方式:

這看起來相當不錯,但它仍然是一種傳統的批處理方式,具有所有已知的缺點,主要原因是客戶端的數據在批處理花費大量時間完成之前的數據處理時,新的數據已經進入而導致數據過時。

Lambda架構
Nathan Marz針對通用的,可擴展的和容錯的數據處理架構提出了術語Lambda Architecture。它是一種旨在通過利用批處理和流處理這兩者的優勢來處理大量數據的數據處理架構。

我強烈建議閱讀Nathan Marz的書,因爲它從提出者的角度提供了Lambda Architecture的完整表述。

圖層
從宏觀角度看,它的處理流程如下:

所有進入系統的數據都被分配到批處理層和速度層進行處理。批處理層管理主數據集(一個不可變的,僅可擴展的原始數據集)並預先計算批處理視圖。服務層對批處理視圖進行索引,以便可以在低延遲的情況下進行點對點查詢。速度層只處理最近的數據。任何傳入的查詢都必須通過合併來自批量視圖和實時視圖的結果來得到結果。

焦點
許多工程師認爲Lambda Architecture是全部關於這些層次和定義的數據流的,但Nathan Marz在他的書中將重點放在其他重要方面,如:

思考的分佈式
避免增量架構
強制數據不可變
創建重新計算算法
數據的相關性

如前所述,任何傳入查詢都必須通過合併來自批量視圖和實時視圖的結果來得到答案,因此這些視圖需要可合併性。需要注意的一點是,實時視圖是以前的實時視圖和新數據增量的函數,因此可以使用增量算法。批處理視圖是所有數據的函數,因此應該在那裏使用重算算法。

權衡

我們生活中的每一件事都是一種折衷,而Lambda Architecture也不是一個例外。通常,我們需要解決一些主要的折衷:

  • 完全重新計算與部分重新計算
    • 在某些情況下,可以使用Bloom過濾器來避免完全重新計算
  • 重算算法與增量算法
    • 使用增量算法有很大的誘惑力,但根據指南我們必須使用重新計算算法,即使它使達到相同的結果變得更加困難。
  • 加法算法與近似算法
    • Lambda Architecture與加法算法很好地協作。因此,這是我們需要考慮使用近似算法的另一種情況,例如,HyperLogLog用於計數不同的問題等。

實現

有多種實現Lambda體系結構的方法,因爲它對於每個層的底層解決方案都是不可知的。每一層都需要底層實現的特定功能,這可能有助於做出更好的選擇並避免過度的決定:

  • 批處理層:一次寫入,批量讀取多次
  • 服務層:隨機讀取,不隨機寫入; 批量計算和批量寫入
  • 速度層:隨機讀取,隨機寫入; 增量計算

例如,其中一個實現(使用Kafka,Apache Hadoop,Voldemort,Twitter Storm,Cassandra)可能如下所示:

Apache Spark

Apache Spark可以被視爲在所有Lambda體系結構層上處理的集成解決方案。它包含Spark Core,包括高層次的API,並且支持通用執行圖表的優化引擎,Spark SQL爲SQL和結構化數據提供處理,以及Spark Streaming,支持可擴展性,高吞吐量,容錯流的實時數據流的處理。當然,使用Spark進行批量處理可能會非常昂貴,並且可能不適合所有場景和數據量,但除此之外,它是Lambda Architecture實施方案的適當匹配。

示例應用程序

讓我們用一些捷徑創建一個示例應用程序來演示Lambda架構。這個程序的主要目標是提供在#morningatlohika推文中使用的主題標籤統計數據(即我在烏克蘭利沃夫舉辦本地技術會談):所有時間直到今天+現在

源代碼位於GitHub上,關於上述主題的更多視覺信息位於Slideshare上

批處理視圖

爲了簡單起見,假設我們的主數據集包含自開始以來的所有推文。另外,我們實施了批量處理,創建我們業務目標所需的批處理視圖,因此我們有一個預先計算的批處理視圖,其中包含與#morningatlohika一起使用的所有主題標籤統計信息:

apache – 6 
architecture – 12 
aws – 3 
java – 4 
jeeconf – 7 
lambda – 6 
morningatlohika – 15 
simpleworkflow – 14 
spark – 5

數字很容易記住,因爲我簡單地在相應的主題標籤中使用了許多字母。

實時視圖

想象一下,當應用程序啓動並運行時,現在有人正在發送推文消息:

@tmatyashovsky關於 #lambda #architecture使用 #apache #spark#morningatlohika的酷博客文章 ”

在這種情況下,適當的實時視圖應該包含以下hash標籤和它們的統計信息(在我們的例子中僅爲1,因爲相應的hash標籤只用了一次):

apache – 1 
architecture – 1 
lambda – 1 
morningatlohika – 1 
spark – 1

查詢

當客戶端爲了實時得到所有的Hash標籤的統計結果進行查詢時,我們只需要將批量視圖與實時視圖合併即可。所以輸出應該如下所示(適當的hashtags的統計數字增加1):

apache – 7 
architecture – 13 
aws – 3 
java – 4 
jeeconf – 7 
lambda – 7 
morningatlohika – 16 
simpleworkflow – 14 
spark – 6

演示方案

演示場景的簡化步驟如下:

  • 通過Apache Spark 創建批處理視圖(.parquet
  • 在Apache Spark中緩存批處理視圖
  • 開始連接到Twitter的流應用程序
  • 關注即時#morningatlohika推文
  • 構建增量的實時視圖
  • 查詢,即即時合併批處理和實時視圖
  • 技術細節
    源代碼基於Apache Spark 1.6.x,即在引入結構化流式傳輸之前。Spark Streaming架構是純粹的微批處理架構:
  • 因此,對於流媒體應用程序,我是用DSTREAM使用連接到Twitter TwitterUtils:

    JavaDStream < Status > twitterStatuses = TwitterUtils 。createStream ( javaStreamingContext ,
                                                                    createTwitterAuthorization (), 
                                                                    new  String [ ] { twitterFilterText } );

    在每個微批處理中(使用可配置的批處理間隔),我正在執行新推文中hashtags統計的計算,並使用updateStateByKey()有狀態轉換更新實時視圖的狀態。爲了簡單起見,使用臨時表將實時視圖存儲在內存中。

    查詢服務反映了通過代碼顯式合併由DataFrame表示的批處理視圖和實時視圖:

    DataFrame realTimeView = streamingService . getRealTimeView ( ) ; 
    DataFrame batchView = servingService . getBatchView ( ) ; 
    DataFrame mergedView = realTimeView . unionAll ( batchView ) 
                                       . groupBy ( realTimeView . col ( HASH_TAG . getValue ( ) ) ) 
                                       . sum ( COUNT . getValue ( ) )
                                       . orderBy ( HASH_TAG . getValue ( ) ) ;
    
    List < Row > merged = mergedView . collectAsList ( ) ;
    
    return merged . stream ( ) 
       . map ( row - >  new  HashTagCount ( row . getString ( 0 ) , row . getLong ( 1 ) ) ) 
       . collect ( Collectors . toList ( ) ) ;

    結果

    使用簡化的方法,開頭提到的真正基於Hadoop的M/R管道可能會使用Apache Spark進行增強,並按以下方式查看:

  •  

    並不是後記
    正如前面提到的,Lambda Architecture有其優點和缺點,人們也劃分成支持者和反對者兩派。他們中的一些人說批處理視圖和實時視圖有很多重複的邏輯,因爲他們最終需要從查詢角度創建可合併的視圖。所以他們創建了Kappa架構 - 簡化了Lambda架構。Kappa架構系統是刪除了批處理系統的架構。要取代批處理,數據只需通過流式傳輸系統快速提供:

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章