數據處理平臺架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

在今天的文章中,咱們將着重探討如何利用SMACK(即Spark、Mesos、Akka、Cassandra以及Kafka)堆棧構建可擴展數據處理平臺。雖然這套堆棧僅由數個簡單部分組成,但其可以實現大量不一樣系統設計。除了純粹的批量或者流處理機制以外,咱們亦可藉此實現複雜的Lambda以及Kappa架構。程序員

基於Mesos技術的數人云能夠快速部署和運行Spark、Akka、Cassandra以及Kafka,也歡迎你們在數人云上進行體驗和實踐,感覺它們強大功能帶來的便利。在本文開始闡述以前,讓咱們首先立足於已有生產項目經驗從設計與示例入手進行說明。shell

綜述

圖片描述
• Spark - 一套高速通用型引擎,用於實現分佈式大規模數據處理任務。數據庫

• Mesos - 集羣資源管理系統,可以立足於分佈式應用程序提供行之有效的資源隔離與共享能力。設計模式

• Akka - 一套用於在JVM之上構建高併發、分佈式及彈性消息驅動型應用程序的工具包與運行時。bash

• Cassandra - 一套分佈式高可用性數據庫,旨在跨越多座數據中心處理大規模數據。網絡

• Kafka - 一套高吞吐能力、低延遲、分佈式消息收發系統/提交日誌方案,旨在處理實時數據供給。架構

存儲層: Cassandra

圖片描述
Cassandra一直以其高可用性與高吞吐能力兩大特性而備受矚目,其同時可以處理極爲可觀的寫入負載並具有節點故障容錯能力。以CAP原則爲基礎,Cassandra可以爲業務運營提供可調整的一致性/可用性水平。併發

更有趣的是,Cassandra在處理數據時擁有線性可擴展能力(便可經過向集羣當中添加節點的方式實現負載增容)並可以提供跨數據中心複製(簡稱XDCR)能力。事實上,跨數據中心複製功能除了數據複製,同時也可以實現如下各種擴展用例:app

• 地理分佈式數據中心處理面向特定區域或者客戶周邊位置之數據。框架

• 在不一樣數據中心之間者數據遷移,從而實現故障後恢復或者將數據移動至新數據中心。

• 對運營工做負載與分析工做負載加以拆分。

但上述特性也都有着本身的實現成本,而對於Cassandra而言這種成本體現爲數據模型——這意味着咱們須要經過聚類對分區鍵及入口進行分組/分類,從而實現嵌套有序映射。如下爲簡單示例:
圖片描述

爲了獲取某一範圍內的特定數據,咱們必須指定全鍵,且不容許除列表內最後一列以外的其它任何範圍劃定得以執行。這種限制用於針對不一樣範圍進行多重掃描限定,不然其可能帶來隨機磁盤訪問並拖慢總體性能表現。這意味着該數據模型必須根據讀取查詢進行認真設計,從而限制讀取/掃描量——但這同時也會致使對新查詢的支持靈活性有所降低。

那麼若是咱們須要將某些表加入到其它表當中,又該如何處理?讓咱們考慮下一種場景:針對特定月份對所有活動進行整體訪問量計算。

圖片描述

在特定模型之下,實現這一目標的唯一辦法就是讀取所有活動、讀取所有事件、彙總各屬性值(其與活動id相匹配)並將其分配給活動。實現這類應用程序操做顯然極具挑戰,由於保存在Casandra中的數據總量每每很是龐大,內存容量根本不足以加以容納。所以咱們必須以分佈式方式對此類數據加以處理,而Spark在這類用例中將發揮重要做用。

處理層: Spark

圖片描述
Spark的抽象核心主要涉及RDD(即彈性分佈式數據集,一套分佈式元素集合)以及由如下四個主要階段構成的工做流:

• RDD操做(轉換與操做)以DAG(即有向無環圖)形式進行

• DAG會根據各任務階段進行拆分,並隨後被提交至集羣管理器

• 各階段無需混洗/從新分配便可與任務相結合

• 任務運行在工做程序之上,而結果隨後返回至客戶端

如下爲咱們如何利用Spark與Cassandra解決上述問題:

圖片描述

指向Cassandra的交互經過Spark-Cassandra-鏈接器負責執行,其可以讓整個流程變得更爲直觀且簡便。另有一個很是有趣的選項可以幫助你們實現對NoSQL存儲內容的交互——SparkSQL,其可以將SQL語句翻譯成一系列RDD操做。
圖片描述
經過幾行代碼,咱們已經可以實現原生Lambda設計——其複雜度顯然較高,但這一示例代表你們徹底有能力以簡單方式實現既定功能。

類MapReduce解決方案:拉近處理與數據間的距離

Spark-Cassandra鏈接器擁有數據位置識別能力,並會從集羣內距離最近的節點處讀取數據,從而最大程度下降數據在網絡中的傳輸需求。爲了充分發揮Spark-C*鏈接器的數據位置識別能力,你們應當讓Spark工做程序與Cassandra節點並行協做。
圖片描述
除了Spark與Cassandra的協做以外,咱們也有理由將運營(或者高寫入強度)集羣同分析集羣區分開來,從而保證:

• 不一樣集羣可以獨立進行規模伸縮

• 數據由Cassandra負責複製,而無需其它機制介入

• 分析集羣擁有不一樣的讀取/寫入負載模式

• 分析集羣可以容納額外數據(例如詞典)與處理結果

• Spark對資源的影響只侷限於單一集羣當中

下面讓咱們再次回顧Spark的應用程序部署選項:
圖片描述
目前咱們擁有三種主要集羣資源管理器選項可供選擇:

• 單獨使用Spark——Spark做爲主體,各工做程序以獨立應用程序的形式安裝並執行(這明顯會增長額外資源負擔,且只支持爲每工做程序分配靜態資源)

• 若是你們已經擁有Hadoop生態系統,那麼YARN絕對是個不錯的選項

• Mesos自誕生之初就在設計中考慮到對集羣資源的動態分配,並且除了Hadoop應用程序以外,同時也適合處理各種異構工做負載

Mesos架構

圖片描述
Mesos集羣由各主節點構成,它們負責資源供應與調度,而各從節點則實際承擔任務執行負載。在HA模式當中,咱們利用多個主ZooKeeper節點負責進行主節點選擇與服務發現。Mesos之上執行的各應用程序被稱爲「框架(Framework)」,並利用API處理資源供應及將任務提交至Mesos。整體來說,其任務執行流程由如下幾個步驟構成:

• 從節點爲主節點提供可用資源

• 主節點向框架發送資源供應

• 調度程序迴應這些任務及每任務資源需求

• 主節點將任務發送至從節點

將Spark、Mesos以及Cassandra加以結合

正如以前所提到,Spark工做程序應當與Cassandra節點協做,從而實現數據位置識別能力以下降網絡流量與Cassandra集羣負載。下圖所示爲利用Mesos實現這一目標的可行部署場景示例:

圖片描述

• Mesos主節點與ZooKeeper協做

• Mesos從節點與Cassandra節點協做,從而爲Spark提供更理想的數據位置

• Spark二進制文件部署至所有工做節點當中,而spark-env.sh則配置以合適的主端點及執行器jar位置

• Spark執行器JAR被上傳至S3/HDFS當中

根據以上設置流程Spark任務可利用簡單的spark-submit調用從任意安裝有Spark二進制文件並上傳有包含實際任務邏輯jar的工做節點被提交至集羣中。
圖片描述
因爲現有選項已經可以運行Docker化Spark,所以咱們沒必要將二進制文件分發至每一個單一集羣節點當中。

按期與長期運行任務之執行機制

每套數據處理系統早晚都要面對兩種必不可少的任務運行類別:按期批量匯聚型按期/階段性任務以及以數據流處理爲表明的長期任務。這兩類任務的一大主要要求在於容錯能力——各任務必須始終保持運行,即便集羣節點發生故障。Mesos提供兩套出色的框架以分別支持這兩種任務類別。

Marathon是一套專門用於實現長期運行任務高容錯性的架構,且支持與ZooKeeper相配合之HA模式。其可以運行Docker並提供出色的REST API。如下shell命令示例爲經過運行spark-submit實現簡單任務配置:

圖片描述
Chronos擁有與Marathon相同的特性,但其設計目標在於運行按期任務,並且整體而言其分佈式HA cron支持任務圖譜。如下示例爲利用簡單的bash腳本實現S3壓縮任務配置:
圖片描述
目前已經有多種框架方案可供選擇,或者正處於積極開發當中以對接各種系統中所普遍採用的Mesos資源管理功能。下面列舉其中一部分典型表明:

• Hadoop

• Cassandra

• Kafka

• Myriad: YARN on Mesos

• Storm

• Samza

數據提取

到目前爲止可謂一切順利:存儲層已經設計完成,資源管理機制設置穩當,而各任務亦通過配置。接下來唯一要作的就是數據處理工做了。
圖片描述
假定輸入數據將以極高速率涌來,這時端點要順利應對就須要知足如下要求:

• 提供高吞吐能力/低延遲

• 具有彈性

• 可輕鬆實現規模擴展

• 支持背壓

背壓能力並不是必需,不過將其做爲選項來應對負載峯值是個不錯的選擇。
Akka可以完美支持以上要求,並且基本上其設計目標剛好是提供這套功能集。下面來看Akka的特性:

• JVM面向JVM的角色模型實現能力

• 基於消息且支持異步架構

• 強制執行非共享可變狀態

• 可輕鬆由單一進程擴展至設備集羣

• 利用自上而下之監督機制實現角色層級

• 不只是併發框架:akka-http、akka-stream以及akka-persistence

如下簡要示例展現了三個負責處理JSON HttpRequest的角色,它們將該請求解析爲域模型例類,並將其保存在Cassandra當中:
圖片描述
看起來只需幾行代碼便可實現上述目標,不過利用Akka向Cassandra當中寫入原始數據(即事件)卻有可能帶來如下問題:

• Cassandra的設計思路仍然偏重高速交付而非批量處理,所以必須對輸入數據進行預匯聚。

• 匯聚/彙總所帶來的計算時間會隨着數據總量的增加而逐步加長。

• 因爲採用無狀態設計模式,各角色並不適合用於執行匯聚任務。

• 微批量機制可以在必定程度上解決這個難題。

• 仍然須要爲原始數據提供某種可靠的緩衝機制

Kafka充當輸入數據之緩衝機制

圖片描述
爲了保留輸入數據並對其進行預匯聚/處理,咱們也可使用某種類型的分佈式提交日誌機制。在如下用例中,消費程序將批量讀取數據,對其進行處理並將其以預匯聚形式保存在Cassandra當中。該示例說明了如何利用akka-http經過HTTP將JSON數據發佈至Kafka當中:

圖片描述

數據消費:Spark Streaming

儘管Akka也可以用於消耗來自Kafka的流數據,但將Spark歸入生態系統以引入Spark Streaming可以切實解決如下難題:

• 其支持多種數據源

• 提供「至少一次」語義

• 可在配合Kafka Direct與冪等存儲實現「僅一次」語義

圖片描述
如下代碼示例闡述瞭如何利用Spark Streaming消費來自Kinesis的事件流:

圖片描述

故障設計:備份與補丁安裝

一般來說,故障設計是任何系統當中最爲枯燥的部分,但其重要性顯然不容質疑——當數據中心不可用或者須要對崩潰情況加以分析時,儘量保障數據免於丟失可謂相當重要。
圖片描述

那麼爲何要將數據存儲在Kafka/Kinesis當中?截至目前,Kinesis仍然是唯一在無需備份的狀況下可以確保所有處理結果丟失後保留數據的解決方案。雖然Kafka也可以支持數據長期保留,但硬件持有成本還是個須要認真考慮的問題,由於S3存儲服務的使用成本要遠低於支持Kafka所須要的大量實例——另外,S3也提供很是理想的服務水平協議。

除了備份能力,恢復/補丁安裝策略還應當考慮到前期與測試需求,從而保證任何與數據相關的問題可以獲得迅速解決。程序員們在匯聚任務或者重複數據刪除操做中可能不慎破壞計算結果,所以修復這類錯誤的能力就變得很是關鍵。簡化這類操做任務的一種簡便方式在於在數據模型當中引入冪等機制,這樣同一操做的屢次重複將產生相同的結果(例如SQL更新屬於冪等操做,而計數遞增則不屬於)。

如下示例爲Spark任務讀取S3備份並將其載入至Cassandra:
圖片描述

宏觀構成

利用SMACK構建數據平臺頂層設計
圖片描述
縱觀全文,SMACK堆棧的卓越能力包括:

• 簡明的工具儲備以解決範圍極廣的各種數據處理場景

• 軟件方案久經考驗且擁有普遍普及度,背後亦具有強大的技術社區

• 易於實現規模伸縮與數據複製,且提供較低延遲水平

• 統一化集羣管理以實現異構負載

• 可面向任意應用程序類型的單一平臺

• 面向不一樣架構設計(批量、流數據、Lambda、Kappa)的實現平臺

• 出色的產品發佈速度(例如用於MVP驗證)

相關文章
相關標籤/搜索