天天看點

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

在今天的文章中,我們将着重探讨如何利用<b>smack</b>(即<b>spark、mesos、akka、cassandra</b>以及<b>kafka</b>)堆棧建構可擴充資料處理平台。雖然這套堆棧僅由數個簡單部分組成,但其能夠實作大量不同系統設計。除了純粹的批量或者流處理機制之外,我們亦可借此實作複雜的lambda以及kappa架構。 在本文開始闡述之前,讓我們首先立足于已有生産項目經驗從設計與示例入手進行說明。
資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

• <b>spark</b> - 一套高速通用型引擎,用于實作分布式大規模資料處理任務。

• <b>mesos</b> - 叢集資源管理系統,能夠立足于分布式應用程式提供行之有效的資源隔離與共享能力。

• <b>akka</b> - 一套用于在jvm之上建構高并發、分布式及彈性消息驅動型應用程式的工具包與運作時。

• <b>cassandra</b> - 一套分布式高可用性資料庫,旨在跨越多座資料中心處理大規模資料。

• <b>kafka</b> - 一套高吞吐能力、低延遲、分布式消息收發系統/送出日志方案,旨在處理實時資料供給。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

<b>cassandra</b>一直以其<b>高可用性</b>與<b>高吞吐能力</b>兩大特性而備受矚目,其同時能夠處理極為可觀的寫入負載并具備節點故障容錯能力。以<b>cap原則</b>為基礎,<b>cassandra</b>能夠為業務營運提供可調整的一緻性/可用性水準。

更有趣的是,<b>cassandra</b>在處理資料時擁有線性可擴充能力(即可通過向叢集當中添加節點的方式實作負載增容)并能夠提供跨資料中心複制(簡稱<b>xdcr</b>)能力。事實上,跨資料中心複制功能除了資料複制,同時也能夠實作以下各類擴充用例:

• 地理分布式資料中心處理面向特定區域或者客戶周邊位置之資料。

• 在不同資料中心之間者資料遷移,進而實作故障後恢複或者将資料移動至新資料中心。

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

但上述特性也都有着自己的實作成本,而對于<b>cassandra</b>而言這種成本展現為資料模型——這意味着我們需要通過聚類對分區鍵及入口進行分組/分類,進而實作嵌套有序映射。以下為簡單示例:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

為了擷取某一範圍内的特定資料,我們必須指定全鍵,且不允許除清單内最後一列之外的其它任何範圍劃定得以執行。這種限制用于針對不同範圍進行多重掃描限定,否則其可能帶來随機磁盤通路并拖慢整體性能表現。這意味着該資料模型必須根據讀取查詢進行認真設計,進而限制讀取/掃描量——但這同時也會導緻對新查詢的支援靈活性有所下降。

那麼如果我們需要将某些表加入到其它表當中,又該如何處理?讓我們考慮下一種場景:針對特定月份對全部活動進行總體通路量計算。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

在特定模型之下,實作這一目标的惟一辦法就是讀取全部活動、讀取全部事件、彙總各屬性值(其與活動id相比對)并将其配置設定給活動。實作這類應用程式操作顯然極具挑戰,因為儲存在<b>casandra</b>中的資料總量往往非常龐大,記憶體容量根本不足以加以容納。是以我們必須以分布式方式對此類資料加以處理,而<b>spark</b>在這類用例中将發揮重要作用。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

<b>spark</b>的抽象核心主要涉及<b>rdd</b>(即<b>彈性分布式資料集</b>,一套分布式元素集合)以及由以下四個主要階段構成的工作流:

• rdd操作(轉換與操作)以dag(即有向無環圖)形式進行

• dag會根據各任務階段進行拆分,并随後被送出至叢集管理器

• 各階段無需混洗/重新配置設定即可與任務相結合

• 任務運作在工作程式之上,而結果随後傳回至用戶端

以下為我們如何利用<b>spark</b>與<b>cassandra</b>解決上述問題:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

指向<b>cassandra</b>的互動通過<b>spark-cassandra-連接配接器</b>負責執行,其能夠讓整個流程變得更為直覺且簡便。另有一個非常有趣的選項能夠幫助大家實作對<b>nosql</b>存儲内容的互動——<b>sparksql</b>,其能夠将sql語句翻譯成一系列rdd操作。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

通過幾行代碼,我們已經能夠實作<b>原生lambda設計</b>——其複雜度顯然較高,但這一示例表明大家完全有能力以簡單方式實作既定功能。

<b>spark-cassandra連接配接器</b>擁有資料位置識别能力,并會從叢集内距離最近的節點處讀取資料,進而最大程度降低資料在網絡中的傳輸需求。為了充分發揮<b>spark-c*連接配接器</b>的資料位置識别能力,大家應當讓<b>spark</b>工作程式與<b>cassandra</b>節點并行協作。 

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

除了<b>spark</b>與<b>cassandra</b>的協作之外,我們也有理由将營運(或者高寫入強度)叢集同分析叢集區分開來,進而保證:

• 不同叢集能夠獨立進行規模伸縮

• 資料由<b>cassandra</b>負責複制,而無需其它機制介入

• 分析叢集擁有不同的讀取/寫入負載模式

• 分析叢集能夠容納額外資料(例如詞典)與處理結果

• <b>spark</b>對資源的影響隻局限于單一叢集當中

下面讓我們再次回顧<b>spark</b>的應用程式部署選項:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

目前我們擁有三種主要叢集資料總管選項可供選擇:

• 單獨使用<b>spark——spark</b>作為主體,各工作程式以獨立應用程式的形式安裝并執行(這明顯會增加額外資源負擔,且隻支援為每工作程式配置設定靜态資源)

• 如果大家已經擁有<b>hadoop</b>生态系統,那麼<b>yarn</b>絕對是個不錯的選項

• <b>mesos</b>自誕生之初就在設計中考慮到對叢集資源的動态配置設定,而且除了<b>hadoop</b>應用程式之外,同時也适合處理各類異構工作負載

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

<b>mesos</b>叢集由各主節點構成,它們負責資源供應與排程,而各從節點則實際承擔任務執行負載。在<b>ha模式</b>當中,我們利用多個主<b>zookeeper</b>節點負責進行主節點選擇與服務發現。<b>mesos</b>之上執行的各應用程式被稱為“架構(framework)”,并利用api處理資源供應及将任務送出至<b>mesos</b>。總體來講,其任務執行流程由以下幾個步驟構成:

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

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

• 排程程式回應這些任務及每任務資源需求

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

正如之前所提到,<b>spark</b>工作程式應當與<b>cassandra</b>節點協作,進而實作資料位置識别能力以降低網絡流量與<b>cassandra</b>叢集負載。下圖所示為利用<b>mesos</b>實作這一目标的可行部署場景示例:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

• <b>mesos</b>主節點與<b>zookeeper</b>協作

• <b>mesos</b>從節點與<b>cassandra</b>節點協作,進而為spark提供更理想的資料位置

• <b>spark</b>二進制檔案部署至全部工作節點當中,而<b>spark-env.sh</b>則配置以合适的主端點及執行器jar位置

• <b>spark</b>執行器<b>jar</b>被上傳至<b>s3/hdfs</b>當中

根據以上設定流程<b>spark</b>任務可利用簡單的<b>spark-submit</b>調用從任意安裝有<b>spark</b>二進制檔案并上傳有包含實際任務邏輯jar的工作節點被送出至叢集中。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

由于現有選項已經能夠運作<b>docker化spark</b>,是以我們不必将二進制檔案分發至每個單一叢集節點當中。

每套資料處理系統遲早都要面對兩種必不可少的任務運作類别:定期批量彙聚型定期/階段性任務以及以資料流處理為代表的長期任務。這兩類任務的一大主要要求在于容錯能力——各任務必須始終保持運作,即使叢集節點發生故障。<b>mesos</b>提供兩套出色的架構以分别支援這兩種任務類别。

<b>marathon</b>是一套專門用于實作長期運作任務高容錯性的架構,且支援與<b>zookeeper</b>相配合之ha模式。其能夠運作<b>docker</b>并提供出色的<b>rest api</b>。以下<b>shell</b>指令示例為通過運作<b>spark-submit</b>實作簡單任務配置:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

<b>chronos</b>擁有與<b>marathon</b>相同的特性,但其設計目标在于運作定期任務,而且總體而言其分布式<b>ha cron</b>支援任務圖譜。以下示例為利用簡單的<b>bash</b>腳本實作<b>s3</b>壓縮任務配置: 

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

目前已經有多種架構方案可供選擇,或者正處于積極開發當中以對接各類系統中所廣泛采用的<b>mesos</b>資源管理功能。下面列舉其中一部分典型代表:

• hadoop

• cassandra

• kafka

• myriad: yarn on mesos

• storm

• samza

到目前為止可謂一切順利:存儲層已經設計完成,資源管理機制設定妥當,而各任務亦經過配置。接下來惟一要做的就是資料處理工作了。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

假定輸入資料将以極高速率湧來,這時端點要順利應對就需要滿足以下要求:

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

• 具備彈性

• 可輕松實作規模擴充

• 支援背壓

背壓能力并非必需,不過将其作為選項來應對負載峰值是個不錯的選擇。 <b>akka</b>能夠完美支援以上要求,而且基本上其設計目标恰好是提供這套功能集。下面來看<b>akka</b>的特性:

• jvm面向jvm的角色模型實作能力

• 基于消息且支援異步架構

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

• 可輕松由單一程序擴充至裝置叢集

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

• 不僅是并發架構:akka-http、akka-stream以及akka-persistence

以下簡要示例展示了三個負責處理<b>json httprequest</b>的角色,它們将該請求解析為域模型例類,并将其儲存在<b>cassandra</b>當中:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

看起來隻需幾行代碼即可實作上述目标,不過利用<b>akka</b>向<b>cassandra</b>當中寫入原始資料(即事件)卻有可能帶來以下問題:

• <b>cassandra</b>的設計思路仍然偏重高速傳遞而非批量處理,是以必須對輸入資料進行預彙聚。

• 彙聚/彙總所帶來的計算時間會随着資料總量的增長而逐漸加長。

• 由于采用無狀态設計模式,各角色并不适合用于執行彙聚任務。

• 微批量機制能夠在一定程度上解決這個難題。

• 仍然需要為原始資料提供某種可靠的緩沖機制

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

為了保留輸入資料并對其進行預彙聚/處理,我們也可以使用某種類型的分布式送出日志機制。在以下用例中,消費程式将批量讀取資料,對其進行處理并将其以預彙聚形式儲存在<b>cassandra</b>當中。該示例說明了如何利用<b>akka-http</b>通過<b>http</b>将<b>json</b>資料釋出至<b>kafka</b>當中:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

盡管<b>akka</b>也能夠用于消耗來自<b>kafka</b>的流資料,但将<b>spark</b>納入生态系統以引入<b>spark streaming</b>能夠切實解決以下難題:

• 其支援多種資料源

• 提供“至少一次”語義

• 可在配合kafka direct與幂等存儲實作“僅一次”語義

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

以下代碼示例闡述了如何利用<b>spark streaming</b>消費來自<b>kinesis</b>的事件流:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

通常來講,故障設計是任何系統當中最為枯燥的部分,但其重要性顯然不容質疑——當資料中心不可用或者需要對崩潰狀況加以分析時,盡可能保障資料免于丢失可謂至關重要。

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

那麼為什麼要将資料存儲在<b>kafka/kinesis</b>當中?截至目前,<b>kinesis</b>仍然是惟一在無需備份的情況下能夠確定全部處理結果丢失後保留資料的解決方案。雖然<b>kafka</b>也能夠支援資料長期保留,但硬體持有成本仍是個需要認真考慮的問題,因為s3存儲服務的使用成本要遠低于支援kafka所需要的大量執行個體——另外,s3也提供非常理想的服務水準協定。

除了備份能力,恢複/更新檔安裝政策還應當考慮到前期與測試需求,進而保證任何與資料相關的問題能夠得到迅速解決。程式員們在彙聚任務或者重複資料删除操作中可能不慎破壞計算結果,是以修複這類錯誤的能力就變得非常關鍵。簡化這類操作任務的一種簡便方式在于在資料模型當中引入幂等機制,這樣同一操作的多次重複将産生相同的結果(例如sql更新屬于幂等操作,而計數遞增則不屬于)。

以下示例為spark任務讀取s3備份并将其載入至cassandra:

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

利用<b>smack</b>建構資料平台頂層設計

資料處理平台架構中的SMACK組合:Spark、Mesos、Akka、Cassandra以及Kafka

縱觀全文,<b>smack</b>堆棧的卓越能力包括:

• 簡明的工具儲備以解決範圍極廣的各類資料處理場景

• 軟體方案久經考驗且擁有廣泛普及度,背後亦具備強大的技術社群

• 易于實作規模伸縮與資料複制,且提供較低延遲水準

• 統一化叢集管理以實作異構負載

• 可面向任意應用程式類型的單一平台

• 面向不同架構設計(批量、流資料、lambda、kappa)的實作平台

• 出色的産品釋出速度(例如用于mvp驗證)

翻譯原文位址:http://blog.dataman-inc.com/untitled-23/

英文原文位址:http://datastrophic.io/data-processing-platforms-architectures-with-spark-mesos-akka-cassandra-and-kafka/

繼續閱讀