[toc]html
版權聲明:本文爲Heriam博主原創文章,遵循CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。算法
原文連接:https://jiang-hao.com/articles/2019/big-data-lambda-architecture.htmlsql
「咱們正在從IT時代走向DT時代(數據時代)。IT和DT之間,不只僅是技術的變革,更是思想意識的變革,IT主要是爲自我服務,用來更好地自我控制和管理,DT則是激活生產力,讓別人活得比你好」數據庫
——阿里巴巴董事局主席馬雲。編程
數據量從M的級別到G的級別到如今T的級、P的級別。數據量的變化數據管理系統(DBMS)和數倉系統(DW)也在悄然的變化着。 傳統應用的數據系統架構設計時,應用直接訪問數據庫系統。當用戶訪問量增長時,數據庫沒法支撐日益增加的用戶請求的負載時,從而致使數據庫服務器沒法及時響應用戶請求,出現超時的錯誤。出現這種狀況之後,在系統架構上就採用下圖的架構,在數據庫和應用中間過一層緩衝隔離,緩解數據庫的讀寫壓力。服務器
然而,當用戶訪問量持續增長時,就須要考慮讀寫分離技術(Master-Slave)架構則以下圖,分庫分表技術。如今,架構變得愈來愈複雜了,增長隊列、分區、複製等處理邏輯。應用程序須要瞭解數據庫的schema,才能訪問到正確的數據。網絡
商業現實已經發生了變化,因此如今更快作出的決定更有價值。除此以外,技術也在不斷髮展。Kafka,Storm,Trident,Samza,Spark,Flink,Parquet,Avro,Cloud providers等都是工程師和企業普遍採用的流行語。所以,現代基於Hadoop的M/R管道(使用Kafka,Avro和數據倉庫等現代二進制格式,即Amazon Redshift,用於臨時查詢)可能採用如下方式:架構
這看起來至關不錯,但它仍然是一種傳統的批處理方式,具備全部已知的缺點,主要緣由是客戶端的數據在批處理花費大量時間完成以前的數據處理時,新的數據已經進入而致使數據過期。app
對低成本規模化的需求促令人們開始使用分佈式文件系統,例如 HDFS和基於批量數據的計算系統(MapReduce 做業)。可是這種系統很難作到低延遲。用 Storm 開發的實時流處理技術能夠幫助解決延遲性的問題,但並不完美。其中的一個緣由是,Storm 不支持 exactly-once 語義,所以不能保證狀態數據的正確性,另外它也不支持基於事件時間的處理。有以上需求的用戶不得不在本身的應用程序代碼中加入這些功能。後來出現了一種混合分析的方法,它將上述兩個方案結合起來,既保證低延遲,又保障正確性。這個方法被稱做 Lambda 架構,它經過批量 MapReduce做業提供了雖有些延遲可是結果準確的計算,同時經過Storm將最新數據的計算結果初步展現出來。框架
Lambda架構是由Storm的做者Nathan Marz提出的一個實時大數據處理框架。Marz在Twitter工做期間開發了著名的實時大數據處理框架Storm,Lambda架構是其根據多年進行分佈式大數據系統的經驗總結提煉而成。Lambda架構的目標是設計出一個能知足實時大數據系統關鍵特性的架構,包括有:高容錯、低延時和可擴展等。Lambda架構整合離線計算和實時計算,融合不可變性(Immunability),讀寫分離和複雜性隔離等一系列架構原則,可集成Hadoop,Kafka,Storm,Spark,Hbase等各種大數據組件。
Marz認爲大數據系統應具備如下的關鍵特性:
Note:xpleaf我的認爲Robust應該翻譯爲健壯性,而不是魯棒性,由於魯棒性從字面上理解很難明白是什麼意思,但健壯性在計算機領域當中應該是一聽就懂的。
爲了設計出能知足前述的大數據關鍵特性的系統,咱們須要對數據系統有本質性的理解。咱們可將數據系統簡化爲:
數據系統 = 數據 + 查詢
從而從數據和查詢兩方面來認識大數據系統的本質。
數據的特性: when & what
咱們先從「數據」的特性談起。數據是一個不可分割的單位,數據有兩個關鍵的性質:When和What。
數據的存儲:Store Everything Rawly and Immutably
根據上述對數據本質特性的分析,Lamba架構中對數據的存儲採用的方式是:數據不可變,存儲全部數據。
經過採用不可變方式存儲全部的數據,能夠有以下好處:
當前業界有不少採用不可變數據模型來存儲全部數據的例子。好比分佈式數據庫Datomic,基於不可變數據模型來存儲數據,從而簡化了設計。分佈式消息中間件Kafka,基於Log日誌,以追加append-only的方式來存儲消息。
查詢的本質
查詢是個什麼概念?Marz給查詢以下一個簡單的定義:
Query = Function(All Data)
該等式的含義是:查詢是應用於數據集上的函數。該定義看似簡單,卻幾乎囊括了數據庫和數據系統的全部領域:RDBMS、索引、OLAP、OLTP、MapReduce、EFL、分佈式文件系統、NoSQL等均可以用這個等式來表示。
讓咱們進一步深刻看一下函數的特性,從而挖掘函數自身的特色來執行查詢。 有一類稱爲Monoid特性的函數應用很是普遍。Monoid的概念來源於範疇學(Category Theory),其一個重要特性是知足結合律。如整數的加法就知足Monoid特性:
(a+b)+c=a+(b+c)
不知足Monoid特性的函數不少時候能夠轉化成多個知足Monoid特性的函數的運算。如多個數的平均值Avg函數,多個平均值無法直接經過結合來獲得最終的平均值,可是能夠拆成分母除以分子,分母和分子都是整數的加法,從而知足Monoid特性。
Monoid的結合律特性在分佈式計算中極其重要,知足Monoid特性意味着咱們能夠將計算分解到多臺機器並行運算,而後再結合各自的部分運算結果獲得最終結果。同時也意味着部分運算結果能夠儲存下來被別的運算共享利用(若是該運算也包含相同的部分子運算),從而減小重複運算的工做量。
有了上面對數據系統本質的探討,下面咱們來討論大數據系統的關鍵問題:如何實時地在任意大數據集上進行查詢?大數據再加上實時計算,問題的難度比較大。
最簡單的方法是,根據前述的查詢等式Query = Function(All Data)
,在全體數據集上在線運行查詢函數獲得結果。但若是數據量比較大,該方法的計算代價太大了,因此不現實。
Lambda架構經過分解的三層架構來解決該問題:Batch Layer,Speed Layer和Serving Layer。
理想狀態下,任何數據訪問均可以從表達式Query= function(all data)開始,可是,若數據達到至關大的一個級別(例如PB),且還須要支持實時查詢時,就須要耗費很是龐大的資源。一個解決方式是預運算查詢函數(precomputed query function)。書中將這種預運算查詢函數稱之爲Batch View(A),這樣當須要執行查詢時,能夠從Batch View中讀取結果。這樣一個預先運算好的View是能夠創建索引的,於是能夠支持隨機讀取(B)。因而系統就變成:
(A)batch view = function(all data)
(B)query = function(batch view)
在Lambda架構中,實現(A)batch view =function(all data)的部分稱之爲Batch Layer。Batch Layer的功能主要有兩點:
存儲數據集
根據前述對數據When&What特性的討論,Batch Layer採用不可變模型存儲全部的數據。由於數據量比較大,能夠採用HDFS之類的大數據儲存方案。若是須要按照數據產生的時間前後順序存放數據,能夠考慮如InfluxDB之類的時間序列數據庫(TSDB)存儲方案。
構建查詢View
上面說到根據等式Query = Function(All Data),在全體數據集上在線運行查詢函數獲得結果的代價太大。但若是咱們預先在數據集上計算並保存查詢函數的結果,查詢的時候就能夠直接返回結果(或經過簡單的加工運算就可獲得結果)而無需從新進行完整費時的計算了。這兒能夠把Batch Layer當作是一個數據預處理的過程。咱們把針對查詢預先計算並保存的結果稱爲View,View是Lambda架構的一個核心概念,它是針對查詢的優化,經過View便可以快速獲得查詢結果。
顯然,batch view是一個批處理過程,如採用Hadoop或spark支持的map-reduce方式。採用這種方式計算獲得的每一個view都支持再次計算,且每次計算的結果都相同。Batch Layer的工做能夠簡單的用以下僞碼錶示:
該工做看似簡單,實質很是強大。任何人爲或機器發生的錯誤,均可以經過修正錯誤後從新計算來恢復獲得正確結果。
對View的理解
View是一個和業務關聯性比較大的概念,View的建立須要從業務自身的需求出發。一個通用的數據庫查詢系統,查詢對應的函數變幻無窮,不可能窮舉。可是若是從業務自身的需求出發,能夠發現業務所須要的查詢經常是有限的。Batch Layer須要作的一件重要的工做就是根據業務的需求,考察可能須要的各類查詢,根據查詢定義其在數據集上對應的Views。
Batch Layer的Immutable data模型和Views
以下圖agent id=50023的人,在10:00:06分的時候,狀態是calling,在10:00:10的時候狀態爲waiting。在傳統的數據庫設計中,直接後面的紀錄覆蓋前面的紀錄,而在Immutable數據模型中,不會對原有數據進行更改,而是採用插入修改紀錄的形式更改歷史紀錄。
上文所說起的View是上圖中預先計算獲得的相關視圖,例如:2016-06-21當天全部上線的agent數,每條熱線、公司下上線的Agent數。根據業務須要,預先計算出結果。此過程至關於傳統數倉建模的應用層,應用層也是根據業務場景,預先加工出的view。
Batch Layer能夠很好的處理離線數據,但有不少場景數據不斷實時生成,而且須要實時查詢處理。Speed Layer正是用來處理增量的實時數據。
Speed Layer和Batch Layer比較相似,對數據進行計算並生成Realtime View,其主要區別在於:
綜上所訴,Speed Layer是Batch Layer在實時性上的一個補充。Speed Layer可總結爲:
(C)realtime view=function(realtime view,new data)
注意,realtime view是基於新數據和已有的realtime view。
Lambda架構將數據處理分解爲Batch Layer和Speed Layer有以下優勢:
如前所述,任何傳入查詢都必須經過合併來自批量視圖和實時視圖的結果來獲得答案,所以這些視圖須要知足Monoid的結合律特性。須要注意的一點是,實時視圖是之前的實時視圖和新數據增量的函數,所以可使用增量算法。批處理視圖是全部數據的函數,所以應該在那裏使用重算算法。
Lambda架構的Serving Layer用於響應用戶的查詢請求,合併Batch View和Realtime View中的結果數據集到最終的數據集。
這兒涉及到數據如何合併的問題。前面咱們討論了查詢函數的Monoid性質,若是查詢函數知足Monoid性質,即知足結合律,只須要簡單的合併Batch View和Realtime View中的結果數據集便可。不然的話,能夠把查詢函數轉換成多個知足Monoid性質的查詢函數的運算,單獨對每一個知足Monoid性質的查詢函數進行Batch View和Realtime View中的結果數據集合並,而後再計算獲得最終的結果數據集。另外也能夠根據業務自身的特性,運用業務自身的規則來對Batch View和Realtime View中的結果數據集合並。
綜上所訴,Serving Layer採用以下等式表示:
(D)query=function(batch view, realtime view)
上面分別討論了Lambda架構的三層:Batch Layer,Speed Layer和Serving Layer。總結下來,Lambda架構就是以下的三個等式:
batch view = function(all data) realtime view = function(realtime view, new data) query = function(batch view, realtime view)
下圖給出了Lambda架構的一個完整視圖和流程。
數據流進入系統後,同時發往Batch Layer和Speed Layer處理。Batch Layer以不可變模型離線存儲全部數據集,經過在全體數據集上不斷從新計算構建查詢所對應的Batch Views。Speed Layer處理增量的實時數據流,不斷更新查詢所對應的Realtime Views。Serving Layer響應用戶的查詢請求,合併Batch View和Realtime View中的結果數據集到最終的數據集。
下圖給出了Lambda架構中各組件在大數據生態系統中和阿里集團的經常使用組件。數據流存儲選用不可變日誌的分佈式系統Kafka、TT、Metaq;BatchLayer數據集的存儲選用Hadoop的HDFS或者阿里雲的ODPS;BatchView的加工採用MapReduce;BatchView數據的存儲採用Mysql(查詢少許的最近結果數據)、Hbase(查詢大量的歷史結果數據)。SpeedLayer採用增量數據處理Storm、Flink;RealtimeView增量結果數據集採用內存數據庫Redis。
另外一個實現版本:
根據batch layer的特色,具有存儲(HDFS)和計算(MapReduce)的Hadoop顯然是第一人選,而batch view 能夠是hadoop自己的hdfs 或者基於hdfs的所構建的相似hive那樣的倉庫,speed layer由於時效性的影響,採用實時流式處理系統,例如strom或者spark streaming, 而speed view 能夠存在HBase 或者其餘相似的Nosql數據庫。server layer 提供用戶查詢的方法,採用facebook 開源的Impala,統一入口查詢。或者本身實現hive和HBase統一查詢。這是兩年前的文章,當時spark 還沒那麼火,如今看來spark能夠直接做爲batch和speed層的替代者了。
Lambda架構是個通用框架,各個層選型時不要侷限時上面給出的組件,特別是對於View的選型。從我對Lambda架構的實踐來看,由於View是個和業務關聯性很是大的概念,View選擇組件時關鍵是要根據業務的需求,來選擇最適合查詢的組件。不一樣的View組件的選擇要深刻挖掘數據和計算自身的特色,從而選擇出最適合數據和計算自身特色的組件,同時不一樣的View能夠選擇不一樣的組件。
在過去Lambda數據架構成爲每個公司大數據平臺必備的架構,它解決了一個公司大數據批量離線處理和實時數據處理的需求。一個典型的Lambda架構以下:
數據從底層的數據源開始,通過各類各樣的格式進入大數據平臺,在大數據平臺中通過Kafka、Flume等數據組件進行收集,而後分紅兩條線進行計算。一條線是進入流式計算平臺(例如 Storm、Flink或者Spark Streaming),去計算實時的一些指標;另外一條線進入批量數據處理離線計算平臺(例如Mapreduce、Hive,Spark SQL),去計算T+1的相關業務指標,這些指標須要隔日才能看見。
Lambda架構經歷多年的發展,其優勢是穩定,對於實時計算部分的計算成本可控,批量處理能夠用晚上的時間來總體批量計算,這樣把實時計算和離線計算高峯分開,這種架構支撐了數據行業的早期發展,可是它也有一些致命缺點,並在大數據3.0時代愈來愈不適應數據分析業務的需求。缺點以下:
也就是因爲Lambda架構的以上侷限性,Kappa應運而生,它比Lambda架構更加靈活和精簡,具體將另文介紹。
Kappa架構: