lambda架構簡介

1.Lambda架構背景介紹

Lambda架構是由Storm的做者Nathan Marz提出的一個實時大數據處理框架。Marz在Twitter工做期間開發了著名的實時大數據處理框架Storm,Lambda架構是其根據多年進行分佈式大數據系統的經驗總結提煉而成。算法

Lambda架構的目標是設計出一個能知足實時大數據系統關鍵特性的架構,包括有:高容錯、低延時和可擴展等。Lambda架構整合離線計算和實時計算,融合不可變性(Immunability),讀寫分離和複雜性隔離等一系列架構原則,可集成Hadoop,Kafka,Storm,Spark,Hbase等各種大數據組件。數據庫

2.大數據系統的關鍵特性

Marz認爲大數據系統應具備如下的關鍵特性:網絡

  • Robust and fault-tolerant(容錯性和魯棒性):對大規模分佈式系統來講,機器是不可靠的,可能會當機,可是系統須要是健壯、行爲正確的,即便是遇到機器錯誤。除了機器錯誤,人更可能會犯錯誤。在軟件開發中不免會有一些Bug,系統必須對有Bug的程序寫入的錯誤數據有足夠的適應能力,因此比機器容錯性更加劇要的容錯性是人爲操做容錯性。對於大規模的分佈式系統來講,人和機器的錯誤天天均可能會發生,如何應對人和機器的錯誤,讓系統可以從錯誤中快速恢復尤爲重要。架構

  • Low latency reads and updates(低延時):不少應用對於讀和寫操做的延時要求很是高,要求對更新和查詢的響應是低延時的。app

  • Scalable(橫向擴容):當數據量/負載增大時,可擴展性的系統經過增長更多的機器資源來維持性能。也就是常說的系統須要線性可擴展,一般採用scale out(經過增長機器的個數)而不是scale up(經過加強機器的性能)。框架

  • General(通用性):系統須要可以適應普遍的應用,包括金融領域、社交網絡、電子商務數據分析等。分佈式

  • Extensible(可擴展):須要增長新功能、新特性時,可擴展的系統能以最小的開發代價來增長新功能。函數

  • Allows ad hoc queries(方便查詢):數據中蘊含有價值,須要可以方便、快速的查詢出所須要的數據。oop

  • Minimal maintenance(易於維護):系統要想作到易於維護,其關鍵是控制其複雜性,越是複雜的系統越容易出錯、越難維護。性能

  • Debuggable(易調試):當出問題時,系統須要有足夠的信息來調試錯誤,找到問題的根源。其關鍵是可以追根溯源到每一個數據生成點。

3.數據系統的本質

爲了設計出能知足前述的大數據關鍵特性的系統,咱們須要對數據系統有本質性的理解。咱們可將數據系統簡化爲:

數據系統 = 數據 + 查詢

從而從數據和查詢兩方面來認識大數據系統的本質。

3.1.數據的本質

3.1.1.數據的特性:When & What

咱們先從「數據」的特性談起。數據是一個不可分割的單位,數據有兩個關鍵的性質:When和What。

  • When是指數據是與時間相關的,數據必定是在某個時間點產生的。好比Log日誌就隱含着按照時間前後順序產生的數據,Log前面的日誌數據必定先於Log後面的日誌數據產生;消息系統中消息的接受者必定是在消息的發送者發送消息後接收到的消息。相比於數據庫,數據庫中表的記錄就丟失了時間前後順序的信息,中間某條記錄多是在最後一條記錄產生後發生更新的。對於分佈式系統,數據的時間特性尤爲重要。分佈式系統中數據可能產生於不一樣的系統中,時間決定了數據發生的全局前後順序。好比對一個值作算術運算,先+2,後*3,與先*3,後+2,獲得的結果徹底不一樣。數據的時間性質決定了數據的全局發生前後,也就決定了數據的結果。

  • What是指數據的自己。因爲數據跟某個時間點相關,因此數據的自己是不可變的(immutable),過往的數據已經成爲事實(Fact),你不可能回到過去的某個時間點去改變數據事實。這也就意味着對數據的操做其實只有兩種:讀取已存在的數據和添加更多的新數據。採用數據庫的記法,CRUD就變成了CR,Update和Delete本質上實際上是新產生的數據信息,用C來記錄。

3.1.2.數據的存儲:Store Everything Rawly and Immutably

根據上述對數據本質特性的分析,Lamba架構中對數據的存儲採用的方式是:數據不可變,存儲全部數據。

經過採用不可變方式存儲全部的數據,能夠有以下好處:

  • 簡單。採用不可變的數據模型,存儲數據時只須要簡單的往主數據集後追加數據便可。相比於採用可變的數據模型,爲了Update操做,數據一般須要被索引,從而能快速找到要更新的數據去作更新操做。

  • 應對人爲和機器的錯誤。前述中提到人和機器天天均可能會出錯,如何應對人和機器的錯誤,讓系統可以從錯誤中快速恢復極其重要。不可變性(Immutability)和從新計算(Recomputation)則是應對人爲和機器錯誤的經常使用方法。採用可變數據模型,引起錯誤的數據有可能被覆蓋而丟失。相比於採用不可變的數據模型,由於全部的數據都在,引起錯誤的數據也在。修復的方法就能夠簡單的是遍歷數據集上存儲的全部的數據,丟棄錯誤的數據,從新計算獲得Views(View的概念參考4.1.2)。從新計算的關鍵點在於利用數據的時間特性決定的全局次序,依次順序從新執行,必然能獲得正確的結果。

當前業界有不少採用不可變數據模型來存儲全部數據的例子。好比分佈式數據庫Datomic,基於不可變數據模型來存儲數據,從而簡化了設計。分佈式消息中間件Kafka,基於Log日誌,以追加append-only的方式來存儲消息。

3.2.查詢

查詢是個什麼概念?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特性意味着咱們能夠將計算分解到多臺機器並行運算,而後再結合各自的部分運算結果獲得最終結果。同時也意味着部分運算結果能夠儲存下來被別的運算共享利用(若是該運算也包含相同的部分子運算),從而減小重複運算的工做量。 
Monoid

4.Lambda架構

有了上面對數據系統本質的探討,下面咱們來討論大數據系統的關鍵問題:如何實時地在任意大數據集上進行查詢?大數據再加上實時計算,問題的難度比較大。

最簡單的方法是,根據前述的查詢等式Query = Function(All Data),在全體數據集上在線運行查詢函數獲得結果。但若是數據量比較大,該方法的計算代價太大了,因此不現實。

Lambda架構經過分解的三層架構來解決該問題:Batch Layer,Speed Layer和Serving Layer。 
Lamba架構

4.1.Batch Layer

Batch Layer的功能主要有兩點:

  • 存儲數據集
  • 在數據集上預先計算查詢函數,構建查詢所對應的View

4.1.1.儲存數據集

根據前述對數據When&What特性的討論,Batch Layer採用不可變模型存儲全部的數據。由於數據量比較大,能夠採用HDFS之類的大數據儲存方案。若是須要按照數據產生的時間前後順序存放數據,能夠考慮如InfluxDB之類的時間序列數據庫(TSDB)存儲方案。

4.1.2.構建查詢View

上面說到根據等式Query = Function(All Data),在全體數據集上在線運行查詢函數獲得結果的代價太大。但若是咱們預先在數據集上計算並保存查詢函數的結果,查詢的時候就能夠直接返回結果(或經過簡單的加工運算就可獲得結果)而無需從新進行完整費時的計算了。這兒能夠把Batch Layer當作是一個數據預處理的過程。咱們把針對查詢預先計算並保存的結果稱爲View,View是Lamba架構的一個核心概念,它是針對查詢的優化,經過View便可以快速獲得查詢結果。 
Batch Layer 
若是採用HDFS來儲存數據,咱們就可使用MapReduce來在數據集上構建查詢的View。Batch Layer的工做能夠簡單的用以下僞碼錶示: 
Batch Layer Code 
該工做看似簡單,實質很是強大。任何人爲或機器發生的錯誤,均可以經過修正錯誤後從新計算來恢復獲得正確結果。

對View的理解: 
View是一個和業務關聯性比較大的概念,View的建立須要從業務自身的需求出發。一個通用的數據庫查詢系統,查詢對應的函數變幻無窮,不可能窮舉。可是若是從業務自身的需求出發,能夠發現業務所須要的查詢經常是有限的。Batch Layer須要作的一件重要的工做就是根據業務的需求,考察可能須要的各類查詢,根據查詢定義其在數據集上對應的Views。

4.2.Speed Layer

Batch Layer能夠很好的處理離線數據,但有不少場景數據不斷實時生成,而且須要實時查詢處理。Speed Layer正是用來處理增量的實時數據。

Speed Layer和Batch Layer比較相似,對數據進行計算並生成Realtime View,其主要區別在於:

  • Speed Layer處理的數據是最近的增量數據流,Batch Layer處理的全體數據集

  • Speed Layer爲了效率,接收到新數據時不斷更新Realtime View,而Batch Layer根據全體離線數據集直接獲得Batch View。

Lambda架構將數據處理分解爲Batch Layer和Speed Layer有以下優勢:

  • 容錯性。Speed Layer中處理的數據也不斷寫入Batch Layer,當Batch Layer中從新計算的數據集包含Speed Layer處理的數據集後,當前的Realtime View就能夠丟棄,這也就意味着Speed Layer處理中引入的錯誤,在Batch Layer從新計算時均可以獲得修正。這點也能夠當作是CAP理論中的最終一致性(Eventual Consistency)的體現。 
    Speed Layer

  • 複雜性隔離。Batch Layer處理的是離線數據,能夠很好的掌控。Speed Layer採用增量算法處理實時數據,複雜性比Batch Layer要高不少。經過分開Batch Layer和Speed Layer,把複雜性隔離到Speed Layer,能夠很好的提升整個系統的魯棒性和可靠性。

4.3.Serving Layer

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

5.Big Picture

上面分別討論了Lambda架構的三層:Batch Layer,Speed Layer和Serving Layer。下圖給出了Lambda架構的一個完整視圖和流程。 
Big Picture

數據流進入系統後,同時發往Batch Layer和Speed Layer處理。Batch Layer以不可變模型離線存儲全部數據集,經過在全體數據集上不斷從新計算構建查詢所對應的Batch Views。Speed Layer處理增量的實時數據流,不斷更新查詢所對應的Realtime Views。Serving Layer響應用戶的查詢請求,合併Batch View和Realtime View中的結果數據集到最終的數據集。

5.1.Lambda架構組件選型

下圖給出了Lambda架構中各個層經常使用的組件。數據流存儲可選用基於不可變日誌的分佈式消息系統Kafka;Batch Layer數據集的存儲可選用Hadoop的HDFS,或者是阿里雲的ODPS;Batch View的預計算能夠選用MapReduce或Spark;Batch View自身結果數據的存儲可以使用MySQL(查詢少許的最近結果數據),或HBase(查詢大量的歷史結果數據)。Speed Layer增量數據的處理可選用Storm或Spark Streaming;Realtime View增量結果數據集爲了知足實時更新的效率,可選用Redis等內存NoSQL。 
Component

5.2.Lambda架構組件選型原則

Lambda架構是個通用框架,各個層選型時不要侷限時上面給出的組件,特別是對於View的選型。從我對Lambda架構的實踐來看,由於View是個和業務關聯性很是大的概念,View選擇組件時關鍵是要根據業務的需求,來選擇最適合查詢的組件。不一樣的View組件的選擇要深刻挖掘數據和計算自身的特色,從而選擇出最適合數據和計算自身特色的組件,同時不一樣的View能夠選擇不一樣的組件。

6.Lambda架構 vs. Event Sourcing vs. CQRS

在Lambda架構身上能夠看到不少現有設計思想和架構的影子,如Event Sourcing和CQRS,這兒咱們把它們和Lambda架構作一結合對比,從而去更深刻的理解Lambda架構。

6.1.事件溯源(Event Sourcing)vs. Lambda架構

事件溯源(Event Sourcing)是由大名鼎鼎的Martin Flower大叔提出來的架構模式。Event Sourcing本質上是一種數據持久化的方式,它將引起變化的事件(Event)自己存儲下來。相比於傳統數據是持久化方式,存儲的是事件引起的結果,而非事件自己,這樣咱們在保存結果的同時,實際上失去了追溯致使結果緣由的機會。

這兒能夠看到Lambda架構中數據集的存儲和Event Sourcing中的思想是徹底一致的,本質都是採用不可變的數據模型存儲引起變化的事件而非變化產生的結果。從而在發生錯誤的時候,可以追本溯源,找到發生錯誤的根源,經過從新計算丟棄錯誤的信息來恢復系統,達到系統的容錯性。

6.2.CQRS vs. Lambda架構

CQRS (Command Query Responsibility Segregation)將對數據的修改操做和查詢操做分離,其本質和Lambda架構同樣,也是一種形式的讀寫分離。在Lambda架構中,數據以不可變的方式存儲下來(寫操做),轉換成查詢所對應的Views,查詢從View中直接獲得結果數據(讀操做)。

讀寫分離將讀和寫兩個視角進行分離,帶來的好處是複雜性的隔離,從而簡化系統的設計。相比於傳統作法中的將讀和寫操做放在一塊兒的處理方式,對於讀寫操做業務很是複雜的系統,只會使系統變得異常複雜,難以維護。 
CQRS

7.總結

本文介紹了Lambda架構的基本概念。Lambda架構經過對數據和查詢的本質認識,融合了不可變性(Immunability),讀寫分離和複雜性隔離等一系列架構原則,將大數據處理系統劃分爲Batch Layer, Speed Layer和Serving Layer三層,從而設計出一個能知足實時大數據系統關鍵特性(如高容錯、低延時和可擴展等)的架構。Lambda架構做爲一個通用的大數據處理框架,能夠很方便的集成Hadoop,Kafka,Storm,Spark,Hbase等各種大數據組件。

 

原文地址:http://www.javashuo.com/article/p-bvgmiuqx-kx.html

相關文章
相關標籤/搜索