帶有Apache Spark的Lambda架構

騰訊雲加社群發表於2018-05-29

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~

目標

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

簡史

Apache Hadoop的豐富歷史始於2002年。Hadoop由Doug Cutting建立,Doug Cutting是Apache Lucene(一個被廣泛使用的文字搜尋庫)的建立者。Hadoop起源於Apache Nutch,一個開源的網路搜尋引擎,它本身就是Lucene專案的一部分。它在10年前成為一個獨立的專案。

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

  • Oozie編排的工作流程每天執行並處理高達150 TB的資料以生成分析結果
  • bash管理的工作流程每天執行並處理高達8 TB的資料以生成分析結果

現狀

商業現實已經發生了變化,所以現在更快做出的決定更有價值。除此之外,技術也在不斷髮展。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架構系統是刪除了批處理系統的架構。要取代批處理,資料只需通過流式傳輸系統快速提供:

但即使在這種情況下,Kappa Architecture也有使用Apache Spark的地方,例如流處理系統:

問答
如何使用MySQL和ApacheSPark?
相關閱讀
大資料系統的Lambda架構
Spark生態頂級專案彙總
大資料平臺架構技術選型與場景運用

此文已由作者授權騰訊雲+社群釋出,原文連結:https://cloud.tencent.com/developer/article/1138267?fromSource=waitui


相關文章