Kappa:比Lambda更好更靈活的實時處理架構

loveheping發表於2018-09-08

本篇文章中分析Lambda三層結構模型的適用場景,同時暴露出Lambda架構一個最明顯的問題:它需要維護兩套分別跑在批處理和實時計算系統上面的程式碼,而且這兩套程式碼需要產出一致的結果。根據對此缺點的分析,我們引出當時還在LinkedIn的大神Jay Kreps提出的Kappa架構,本文會對Kappa架構原理進行介紹,並討論兩個架構的優缺點,最後給出一個Kappa架構的案例分析。

對Lambda架構不熟悉或者希望瞭解Lambda架構應用案例的讀者,請回顧歷史文章中的《深入淺出解析大資料Lambda架構》一文。

Lambda架構回顧Lambda架構的核心思想是把大資料系統拆分成三層:Batch Layer,Speed Layer和Serving Layer。其中,Batch Layer負責資料集儲存以及全量資料集的預查詢。Speed Layer主要負責對增量資料進行計算,生成Realtime Views。Serving Layer用於響應使用者的查詢請求,它將Batch Views和Realtime Views的結果進行合併,得到最後的結果,返回給使用者。圖1給出了Lambda的整體架構圖:

Kappa架構上述提到,為了將批處理和實時處理相結合,Lambda設計了Batch Layer和Speed Layer兩層結構,分別用於批處理和實時計算,因此需要維護兩套分別跑在批處理和實時計算系統之上的程式碼。面對這個問題,有人會有這樣的疑問,為什麼不用流計算系統來進行全量資料處理從而去除Batch Layer這一層?

可能有這樣回答:流計算給人的印象是對一些流式的、臨時的資料進行計算,將結果儲存後就將原始資料丟棄了,因此它不適合用來處理歷史資料。其實這種答案並不完全正確,對於基於Lambda架構實現的Storm框架確實是這樣的,但對於後來出現的Spark並不是。

Storm是在2011年7月開源的,Spark是在2012年之後逐漸為人們所知的,因此在Nathan Marz設計Lambda架構的時候,當時還並沒有一個框架既可以用於離線處理,又可以進行實時計算。但隨著Spark技術的發展,這一想法成為了可能,Spark本身可以用於批處理,而構建在Spark之上的Spark Streaming又可以用於實時計算,因此利用一套系統來應對批處理和實時計算相結合的業務完全是可行的。

Kappa架構的核心思想包括以下三點:

  1. 用Kafka或者類似的分散式佇列系統儲存資料,你需要幾天的資料量就儲存幾天。

  2. 當需要全量重新計算時,重新起一個流計算例項,從頭開始讀取資料進行處理,並輸出到一個新的結果儲存中。

  3. 當新的例項做完後,停止老的流計算例項,並把老的一些結果刪除。

Kappa的架構圖如圖2所示:

和Lambda架構相比,在Kappa架構下,只有在有必要的時候才會對歷史資料進行重複計算,並且實時計算和批處理過程使用的是同一份程式碼。或許有些人會質疑流式處理對於歷史資料的高吞吐量會力不從心,但是這可以透過控制新例項的併發數進行改善。

上面架構圖中,新老例項使用了各自的結果儲存,這便於隨時進行回滾,更進一步,假如我們產出的是一些演算法模型之類的資料,使用者還可以同時對新老兩份資料進行效果驗證,做一些A/B test或者使用bandit演算法來最大限度的使用這些資料。

優缺點對比

對比項

Lam bda架構

Ka ppa架構

資料處理能力

可以處理超大規模的歷史資料

歷史資料處理的能力有限

機器開銷

批處理和實時計算需一直執行,機器開銷大

必要時進行全量計算,機器開銷相對較小

儲存開銷

只需要儲存一份查詢結果,儲存開銷較小

需要儲存新老例項結果,儲存開銷相對較大

開發、測試難易

程度

實現兩套程式碼,開發、測試難度較大

只需面對一個框架,開發、測試難度相對較小

運維成本

維護兩套系統,運維成本大

只需維護一個框架,運維成本小

表1 Lambda架構和Kappa架構優缺點對比

如上表所示,Kappa架構相對來說有更多的優點,目前也被更多的廠商用於構建商業專案。

第一,Lambda架構不僅需要維護兩套分別跑在批處理和實時計算系統上面的程式碼,還需要批處理和全量計算長時間保持執行;而Kappa架構只有在需要的時候才進行全量計算。

第二,Kappa架構下可以啟動很多個例項進行重複計算,因此在需要對一些演算法模型進行調優時,Kappa架構下只需要更改一套系統的引數即可,並且允許對新老資料進行效果比對;但是在Lambda架構下,需要同時更改流計算系統演算法模型和批處理系統演算法模型,調參過程相對比較複雜。

第三,從使用者開發、測試和運維的角度來看,Kappa架構下,開發人員只需要面對一個框架,開發、測試和運維的難度都會相對較小,這是個非常重要的優點。

如何選擇

從上述的優缺點對比來看,業務需求、開發測試難易程度和運維成本為三個主要的框架選擇考慮因素,而機器開銷和儲存開銷,雖然存在一定差別,但是差別不是很大,所以這裡我們也主要從業務需求,開發測試難易程度和運維成本三方面來考慮如何對上述兩個架構做出選擇。

業務需求

使用者需要根據自己的業務需求來選擇架構,如果所需要處理的歷史資料規模較大,比如某省智慧交通系統幾年達TB級的資料,那麼選擇Lambda架構可能較為合適;如果處理的資料量較小,比如分析某電商網站近30天的資料,那麼選擇Kappa架構可能更為合適。

開發測試難易程度

如果專案中需要頻繁的對演算法模型引數進行調優,Kappa架構要來的更為便捷;另外還有一個判定依據就是你設計的演算法是否同時適合批處理和實時計算,如果同一份程式碼可以很好地處理兩者,那麼可以選擇Kappa架構;但是針對某些複雜的案例,其實時計算的結果和批處理的結果是不同的,比如某些機器學習的應用,由批處理生成預測模型,再交由實時計算系統進行實時分析,那麼這種情況下,批處理層和實時計算層不能進行合併,因此應該選擇Lambda架構。

運維成本

Kappa架構的運維成本較低,比較適合技術人力資源有限的團隊或企業。

StreamSQL與Lambda架構Transwarp StreamSQL是星環科技專門為企業級使用者打造的流計算引擎,主要應用於實時性較強的應用場景。比如,金融行業需要對市場波動進行實時預警;銀行業務需要線上分析業務等。它對於SQL和PL/SQL的支援使得使用者可以透過SQL的方式實現複雜業務邏輯,大大降低了流應用開發的門檻,也使得基於一套SQL程式開發離線和實時業務成為可能。

圖3為利用Kafka和StreamSQL搭建的一個Kappa架構系統,並且對原有的Kappa架構的缺點做了改進。

StreamSQL每隔100ms會從Kafka訊息佇列中接收一批時序資料,如t0-tn時刻的資料,其中t0的資料為(0,1,2,3,4),t1的資料為(5,6,7,8,9)…。當前批次的資料會被對映成一張二維關係表,透過SQL進行變換並轉成記憶體列式儲存,變換後的資料會實時寫入Holodesk以持久化到SSD上,透過此方式永久保留或者保留最近一個月的資料。應用程式可以透過Inceptor SQL或者R語言對Holodesk中的列式資料進行統計分析。

StreamSQL對Kappa架構的改進之處,包括如下:

上述提到,原本的Kappa架構把歷史資料儲存在Kafka或類似的分散式訊息佇列,這樣的特性導致了一個缺點就是它只能儲存幾天或幾個月的資料,並且只能以流的形式儲存,因此對於歷史資料的處理能力有限;而StreamSQL支援輸出到多種格式,既允許輸出到Kafka,也可以將結果以各類格式(TEXT表、ORC表、Holodesk表、HBase表)儲存在Inceptor,實現更長期的儲存,因此它可以應對更大資料規模的業務需求。

StreamSQL支援在實時計算時或歷史資料分析時將流資料和Inceptor表的資料做關聯,大大增強了它的歷史資料處理能力。

StreamSQL另一特色功能就是它可以完美相容SQL標準和PL/SQL,使得使用者可以透過SQL的方式實現業務邏輯,極大降低了流應用開發的門檻。

StreamSQL還增加了Application管理的功能,執行時各個Application之間相互隔離並需要許可權驗證,很大程度上提高了系統的安全性和可用性。

Kappa架構案例分析下面我們以StreamSQL作為流處理引擎來搭建一個基於Kappa架構的智慧交通系統,並對其中的套牌車輛實時預警業務場景進行詳細的資料流分析,架構圖如圖4所示:

當前端卡口將監控到的車輛資訊接入Kafka分散式訊息佇列後,匯流排會對這些資料進行歸類分揀,分發給不同的服務叢集,比如實時入庫服務叢集、未年檢車監控服務叢集等。

假設部分資料被送入到了違法車輛監控服務叢集中,該叢集其中一個業務是對車輛進行套牌分析。前面的章節提到Kappa架構方便進行演算法模型的調優,下面我們來看一下具體是怎麼做的。

首先,假如我們建立了一個UDF函式DectectCloneVehicle(param1, param2),用於檢查待檢測牌照是否為套牌車輛。該UDF接收兩個輸入引數:當兩輛相同牌照的車直線距離超過param1公里且出現時間低於param2分鐘時,則被視為套牌車。該函式有兩種返回結果:如果是套牌車則輸出1,否則輸出0。

假設我們起初設定的套牌分析策略是,如果某兩輛相同牌照的車直線距離超過20公里,出現時間小於2分鐘, 那麼判定該車牌被套牌。啟動一個Stream Job例項,並按照該策略進行分析的StreamSQL語句如下:

CREATE STREAM vehicle_stream1(license STRING, location STRING, time TIMESTAMP)  ROW FORMAT DELIMITED FIELDS TERMINATED BY ','  TBLPROPERTIES ("topic"=fakeLicense", kafka.zookeeper"="172.16.1.128:2181",  "timefield"="time", "timeformat"="yyyy-MM-dd HH-mm-ss.SSS);  CREATE TABLE clone_vehicle_result_app1(license STRING,location STRING, time TIMESTAMP);  INSERT INTO clone_vehicle_result_app1  SELECT DetectCloneVehicle(20, 2) as cloned  FROM vehicle_stream1  HAVING cloned>0;

但是透過實踐並且考慮到一些現實情況(如直線距離是否合理,當前路段高速類路段多還是低速路段多等),我們發現如果按照此引數執行檢測,套牌排查效率會很低。假如把套牌車輛的判定標準調整為:直線距離超過10公里,出現時間小於5分鐘的兩輛相同牌照的車,效率就會有極大幅度的提升。現在重新啟動一個Stream Job例項,執行如下的StreamSQL語句:

  1. CREATE STREAM vehicle_stream 2 (license STRING, location STRING, time TIMESTAMP) 

  2.  

  3. ROW FORMAT DELIMITED FIELDS TERMINATED BY  ','  

  4.  

  5. TBLPROPERTIES ( "topic" =fakeLicense ", kafka.zookeeper" = "172.16.1.128:2181"

  6.  

  7. "timefield" = "time" "timeformat" ="yyyy-MM-dd HH-mm-ss.SSS); 

  8.  

  9. CREATE TABLE clone_vehicle_result_app 2 (license STRING,location STRING, time TIMESTAMP); 

  10.  

  11. INSERT INTO clone_vehicle_result_app 2  

  12.  

  13. SELECT DetectCloneVehicle( 10 5 ) as cloned 

  14.  

  15. FROM vehicle_stream 2  

  16.  

  17. HAVING cloned> ;

該Stream Job的效率高於之前所選用的引數,這樣我們就進行了一步UDF模型引數的調優。所以在做實際分析時,業務執行效率的提升不能單純的依靠系統提供的最佳化幫助,使用者需要能夠根據所採用的架構和所處理的問題、應用的模型方法,結合實際外部限制選擇最有效的模型引數。

結語Lambda架構和Kappa架構是常用的兩個大資料系統架構,它們都意在解決批處理和實時計算相結合的問題。對於Lambda架構,如何簡化其開發方式,降低運維成本,是一件值得考慮和繼續研究的事情。Kappa架構非常顯著的改進了Lambda需要維護兩套系統的缺點,但是在做服務選型的時候,僅僅使用開源Spark和Kafka接合還並不能設計出非常好的業務方案。

為此,星環科技基於Kappa的架構設計了StreamSQL,透過高效的效能處理、HA保證、統一的SQL程式設計、允許流上資料和歷史資料關聯等創新技術,有效的解決了Kappa對一些複雜場景處理能力不足的問題,是一個理想的構建Kappa系統的服務元件。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31511218/viewspace-2213827/,如需轉載,請註明出處,否則將追究法律責任。

相關文章