Apache Spark的Lambda架構(gòu)示例應(yīng)用
目前,市場(chǎng)上很多玩家都已經(jīng)成功構(gòu)建了MapReduce工作流程,每天可以處理TB級(jí)的歷史數(shù)據(jù),但是在MapReduce上跑數(shù)據(jù)分析真的太慢了。所以我們給大家介紹利用批處理和流處理方法的Lambda架構(gòu),本文中將利用Apache Spark(Core,SQL,Streaming),Apache Parquet,Twitter Stream等實(shí)時(shí)流數(shù)據(jù)快速訪問(wèn)歷史數(shù)據(jù)。
Apache Hadoop簡(jiǎn)史
Apache Hadoop由 Apache Software Foundation 公司于 2005 年秋天作為L(zhǎng)ucene的子項(xiàng)目Nutch的一部分正式引入。它受到***由 Google Lab 開發(fā)的 Map/Reduce 和 Google File System(GFS) 的啟發(fā)。它成為一個(gè)獨(dú)立項(xiàng)目的時(shí)間已有10年。
目前已經(jīng)有很多客戶實(shí)施了基于Hadoop的M / R管道,并成功運(yùn)行到現(xiàn)在:
Oozie的工作流每日運(yùn)行處理150TB以上的數(shù)據(jù)并生成分析報(bào)告
Bash的工作流每日運(yùn)行處理8TB以上的數(shù)據(jù)并生成分析報(bào)告
2016年來(lái)了!
2016年商業(yè)現(xiàn)實(shí)發(fā)生了變化,越快做出決策往往價(jià)值就會(huì)越大。另外,技術(shù)本身也在發(fā)展,Kafka,Storm,Trident,Samza,Spark,F(xiàn)link,Parquet,Avro,云提供商等都成為了工程師們的流行語(yǔ)。
因此,現(xiàn)代基于Hadoop的M / R管道可能會(huì)是下圖所示的這樣:
圖上的M/R通道看起來(lái)不錯(cuò),但其實(shí)它本質(zhì)上還是一個(gè)傳統(tǒng)的批處理,有著傳統(tǒng)批處理的缺點(diǎn),當(dāng)新的數(shù)據(jù)源源不斷的進(jìn)入系統(tǒng)中時(shí),還是需要大量的時(shí)間來(lái)處理。
Lambda 架構(gòu)
針對(duì)上面的問(wèn)題,Nathan Marz提出了一個(gè)通用、可擴(kuò)展和容錯(cuò)性強(qiáng)的數(shù)據(jù)處理架構(gòu)即Lambda架構(gòu),它是通過(guò)利用批處理和流處理方法來(lái)處理大量數(shù)據(jù)的。Nathan Marz的書對(duì)從源碼的角度對(duì)Lambda架構(gòu)進(jìn)行了詳盡的介紹。
層結(jié)構(gòu)
這是Lambda架構(gòu)自上而下的層結(jié)構(gòu):
所有數(shù)據(jù)進(jìn)入系統(tǒng)后都分派到批處理層和速度層進(jìn)行處理。批處理層管理主數(shù)據(jù)集(一個(gè)不可變的,只可增加的原始數(shù)據(jù)集),并預(yù)先計(jì)算批處理視圖。 服務(wù)層對(duì)批視圖進(jìn)行索引,以便可以進(jìn)行低延遲的臨時(shí)查詢。 速度層僅處理最近的數(shù)據(jù)。所有的查詢結(jié)果都必須合并批處理視圖和實(shí)時(shí)視圖的查詢結(jié)果。
要點(diǎn)
許多工程師認(rèn)為L(zhǎng)ambda架構(gòu)就只包含層結(jié)構(gòu)和定義數(shù)據(jù)流程,但是Nathan Marz的書中為我們介紹了其它幾個(gè)比較重要的點(diǎn):
- 分布式思想
- 避免增量結(jié)構(gòu)
- 數(shù)據(jù)的不變性
- 創(chuàng)建重新計(jì)算算法
- 數(shù)據(jù)的相關(guān)性
如前所述,任何查詢結(jié)果都必須通過(guò)合并來(lái)自批處理視圖和實(shí)時(shí)視圖的結(jié)果,因此這些視圖必須是可合并的。在這里要注意的一點(diǎn)是,實(shí)時(shí)視圖是前一個(gè)實(shí)時(shí)視圖和新數(shù)據(jù)增量的函數(shù),因此這里使用增量算法,批處理視圖是所有數(shù)據(jù)的函數(shù),因此應(yīng)該使用重新計(jì)算算法。
權(quán)衡
世間萬(wàn)物都是在不斷妥協(xié)和權(quán)衡中發(fā)展的,Lambda結(jié)構(gòu)也不例外。通常,我們需要解決幾個(gè)主要的權(quán)衡:
完全重新計(jì)算 vs.部分重新計(jì)算
在有些情況下,可以使用Bloom過(guò)濾器來(lái)避免完全重新計(jì)算
重計(jì)算算法 vs. 增量算法
增量算法其實(shí)很具吸引力,但是有時(shí)根據(jù)指南,我們必須使用重計(jì)算算法,即便它很難得到相同的結(jié)果
加法算法 vs. 近似算法
雖然Lambda架構(gòu)能夠與加法算法很好地協(xié)同工作,但是在有些情況下更適合使用近似算法,例如使用HyperLogLog處理count-distinct問(wèn)題。
實(shí)現(xiàn)
實(shí)現(xiàn)Lambda架構(gòu)的方法有很多,因?yàn)槊總€(gè)層的底層解決方案是獨(dú)立的。每個(gè)層需要底層實(shí)現(xiàn)的特定功能,有助于做出更好的選擇并避免過(guò)度決策:
- 批量層:一次寫入,批量讀取多次
- 服務(wù)層:支持隨機(jī)讀取但不支持隨機(jī)寫入; 批量計(jì)算和批量寫入
- 速度層:隨機(jī)讀寫; 增量計(jì)算
例如,其中一個(gè)實(shí)現(xiàn)(使用Kafka,Apache Hadoop,Voldemort,Twitter Storm,Cassandra)可能如下所示:
Apache Spark
Apache Spark被視為在所有Lambda架構(gòu)層上進(jìn)行處理的集成解決方案。 其中Spark Core包含了高級(jí)API和支持常規(guī)執(zhí)行圖的優(yōu)化引擎,SparkSQL用于SQL和結(jié)構(gòu)化數(shù)據(jù)處理,Spark Streaming支持實(shí)時(shí)數(shù)據(jù)流的可擴(kuò)展,高吞吐量,容錯(cuò)流處理。 當(dāng)然,使用Spark進(jìn)行批處理的價(jià)格可能比較高,而且也不是所有的場(chǎng)景和數(shù)據(jù)都適合。但是,總體來(lái)說(shuō)Apache Spark是對(duì)Lambda架構(gòu)的合理實(shí)現(xiàn)。
示例應(yīng)用
我們創(chuàng)建一個(gè)示例應(yīng)用程序來(lái)演示Lambda架構(gòu)。這個(gè)示例的主要目的統(tǒng)計(jì)從某個(gè)時(shí)刻到現(xiàn)在此刻的#morningatlohika tweets哈希標(biāo)簽。
批處理視圖
為了簡(jiǎn)單起見,假設(shè)我們的主數(shù)據(jù)集包含自時(shí)間開始以來(lái)的所有tweets。 此外,我們實(shí)現(xiàn)了一個(gè)批處理,創(chuàng)建了我們的業(yè)務(wù)目標(biāo)所需的批處理視圖,因此我們有一個(gè)預(yù)計(jì)算的批處理視圖,其中包含與#morningatlohika一起使用的所有主題標(biāo)記的統(tǒng)計(jì)信息:
因?yàn)閿?shù)字方便記憶,所以我使用對(duì)應(yīng)標(biāo)簽的英文單詞的字母數(shù)目作為編號(hào)。
實(shí)時(shí)視圖
當(dāng)應(yīng)用程序啟動(dòng)并運(yùn)行時(shí),有人發(fā)出了如下的tweet:
在這種情況下,正確的實(shí)時(shí)視圖應(yīng)包含以下標(biāo)簽及其統(tǒng)計(jì)信息(在我們的示例中為1,因?yàn)橄鄳?yīng)的hash標(biāo)簽只使用了一次):
查詢
當(dāng)終端用戶查詢hash標(biāo)簽的統(tǒng)計(jì)結(jié)果時(shí),我們只需要將批量視圖與實(shí)時(shí)視圖合并起來(lái)。 所以輸出應(yīng)該如下所示:
場(chǎng)景
示例場(chǎng)景的簡(jiǎn)化步驟如下:
- 通過(guò)Apache Spark創(chuàng)建批處理視圖(.parquet)
- 在Apache Spark中緩存批處理視圖
- 流應(yīng)用程序連接到Twitter
- 實(shí)時(shí)監(jiān)控#morningatlohika tweets
- 構(gòu)建增量實(shí)時(shí)視圖
- 查詢,即合并批處理視圖和實(shí)時(shí)視圖
技術(shù)細(xì)節(jié)
源代碼基于Apache Spark 1.6.x,(在引入結(jié)構(gòu)化流之前)。 Spark Streaming架構(gòu)是純微型批處理架構(gòu):
所以處理流應(yīng)用程序時(shí),我使用DStream連接使用TwitterUtils的Twitter:
在每個(gè)微批次(使用可配置的批處理間隔),對(duì)新的tweets中hashtags的統(tǒng)計(jì)信息的計(jì)算,并使用updateStateByKey()狀態(tài)轉(zhuǎn)換函數(shù)更新實(shí)時(shí)視圖的狀態(tài)。 為了簡(jiǎn)單起見,使用臨時(shí)表將實(shí)時(shí)視圖存儲(chǔ)在存儲(chǔ)器中。
查詢服務(wù)反映批處理和實(shí)時(shí)視圖的合并:
輸出
文章開頭提到的基于Hadoop的M/R管道使用Apache Spark來(lái)優(yōu)化:
后記:
正如之前提到的Lambda Architecture有其優(yōu)點(diǎn)和缺點(diǎn),所以支持者和反對(duì)者都有。 有些人說(shuō)批處理視圖和實(shí)時(shí)視圖有很多重復(fù)的邏輯,因?yàn)樽罱K他們需要從查詢角度創(chuàng)建可合并的視圖。 所以他們創(chuàng)建了一個(gè)Kappa架構(gòu),并稱其為L(zhǎng)ambda架構(gòu)的簡(jiǎn)化版。 Kappa架構(gòu)系統(tǒng)是刪除了批處理系統(tǒng),取而代之的是通過(guò)流系統(tǒng)快速提供數(shù)據(jù):
但即使在這種情況下,Kappa Architecture中也可以應(yīng)用Apache Spark,例如流處理系統(tǒng):