流式處理storm介紹

Hadoop(大數據分析領域無可爭辯的王者)專注於批處理。這種模型對許多情形(比如爲網頁建立索引)已經足夠,但還存在其他一些使用模型,它們需要來自高度動態的來源的實時信息。爲了解決這個問題,就得藉助 Nathan Marz 推出的 Storm(現在在 Twitter 中稱爲 BackType)。Storm 不處理靜態數據,但它處理預計會連續的流數據。考慮到 Twitter 用戶每天生成 1.4 億條推文 (tweet),那麼就很容易看到此技術的巨大用途。

但 Storm 不只是一個傳統的大數據分析系統:它是複雜事件處理 (CEP) 系統的一個示例。CEP 系統通常分類爲計算和麪向檢測,其中每個系統都可通過用戶定義的算法在 Storm 中實現。舉例而言,CEP 可用於識別事件洪流中有意義的事件,然後實時地處理這些事件。

Nathan Marz 提供了在 Twitter 中使用 Storm 的大量示例。一個最有趣的示例是生成趨勢信息。Twitter 從海量的推文中提取所浮現的趨勢,並在本地和國家級別維護它們。這意味着當一個案例開始浮現時,Twitter 的趨勢主題算法就會實時識別該主題。這種實時算法在 Storm 中實現爲 Twitter 數據的一種連續分析。

什麼是 “大數據”?

大數據 指的是海量無法通過傳統方式管理的數據。互聯網範圍的數據正在推動能夠處理這類新數據的新架構和應用程序的創建。這些架構高度可擴展,且能夠跨無限多的服務器並行、高效地處理數據。

Storm 與傳統的大數據

Storm 與其他大數據解決方案的不同之處在於它的處理方式。Hadoop 在本質上是一個批處理系統。數據被引入 Hadoop 文件系統 (HDFS) 並分發到各個節點進行處理。當處理完成時,結果數據返回到 HDFS 供始發者使用。Storm 支持創建拓撲結構來轉換沒有終點的數據流。不同於 Hadoop 作業,這些轉換從不停止,它們會持續處理到達的數據。

大數據實現

Hadoop 的核心是使用 Java 語言編寫的,但支持使用各種語言編寫的數據分析應用程序。最新的應用程序的實現採用了更加深奧的路線,以充分利用現代語言和它們的特性。例如,位於伯克利的加利福尼亞大學 (UC) 的 Spark 是使用 Scala 語言實現的,而 Twitter Storm 是使用 Clojure(發音同 closure)語言實現的。

Clojure 是 Lisp 語言的一種現代方言。類似於 Lisp,Clojure 支持一種功能性編程風格,但 Clojure 還引入了一些特性來簡化多線程編程(一種對創建 Storm 很有用的特性)。Clojure 是一種基於虛擬機 (VM) 的語言,在 Java 虛擬機上運行。但是,儘管 Storm 是使用 Clojure 語言開發的,您仍然可以在 Storm 中使用幾乎任何語言編寫應用程序。所需的只是一個連接到 Storm 的架構的適配器。已存在針對 Scala、JRuby、Perl 和 PHP 的適配器,但是還有支持流式傳輸到 Storm 拓撲結構中的結構化查詢語言適配器。

Storm 的關鍵屬性

Storm 實現的一些特徵決定了它的性能和可靠性的。Storm 使用 ZeroMQ 傳送消息,這就消除了中間的排隊過程,使得消息能夠直接在任務自身之間流動。在消息的背後,是一種用於序列化和反序列化 Storm 的原語類型的自動化且高效的機制。

Storm 的一個最有趣的地方是它注重容錯和管理。Storm 實現了有保障的消息處理,所以每個元組都會通過該拓撲結構進行全面處理;如果發現一個元組還未處理,它會自動從噴嘴處重放。Storm 還實現了任務級的故障檢測,在一個任務發生故障時,消息會自動重新分配以快速重新開始處理。Storm 包含比 Hadoop 更智能的處理管理,流程會由監管員來進行管理,以確保資源得到充分使用。

Storm 模型

Storm 實現了一種數據流模型,其中數據持續地流經一個轉換實體網絡(參見 圖 1)。一個數據流的抽象稱爲一個,這是一個無限的元組序列。元組就像一種使用一些附加的序列化代碼來表示標準數據類型(比如整數、浮點和字節數組)或用戶定義類型的結構。每個流由一個惟一 ID 定義,這個 ID 可用於構建數據源和接收器 (sink) 的拓撲結構。流起源於噴嘴,噴嘴將數據從外部來源流入 Storm 拓撲結構中。

圖 1. 一個普通的 Storm 拓撲結構的概念性架構

一個普通的 Storm 拓撲結構的概念性架構圖

接收器(或提供轉換的實體)稱爲螺栓。螺栓實現了一個流上的單一轉換和一個 Storm 拓撲結構中的所有處理。螺栓既可實現 MapReduce 之類的傳統功能,也可實現更復雜的操作(單步功能),比如過濾、聚合或與數據庫等外部實體通信。典型的 Storm 拓撲結構會實現多個轉換,因此需要多個具有獨立元組流的螺栓。噴嘴和螺栓都實現爲 Linux 系統中的一個或多個任務。

可使用 Storm 爲詞頻輕鬆地實現 MapReduce 功能。如 圖 2 中所示,噴嘴生成文本數據流,螺栓實現 Map 功能(令牌化一個流的各個單詞)。來自 “map” 螺栓的流然後流入一個實現 Reduce 功能的螺栓中(以將單詞聚合到總數中)。

圖 2. MapReduce 功能的簡單 Storm 拓撲結構

MapReduce 功能的簡單 Storm 拓撲結構圖

請注意,螺栓可將數據傳輸到多個螺栓,也可接受來自多個來源的數據。Storm 擁有流分組 的概念,流分組實現了混排 (shuffling)(隨機但均等地將元組分發到螺栓)或字段分組(根據流的字段進行流分區)。還存在其他流分組,包括生成者使用自己的內部邏輯路由元組的能力。

但是,Storm 架構中一個最有趣的特性是有保障的消息處理。Storm 可保證一個噴嘴發射出的每個元組都會處理;如果它在超時時間內沒有處理,Storm 會從該噴嘴重放該元組。此功能需要一些聰明的技巧來在拓撲結構中跟蹤元素,也是 Storm 的重要的附加價值之一。

除了支持可靠的消息傳送外,Storm 還使用 ZeroMQ 最大化消息傳送性能(刪除中間排隊,實現消息在任務間的直接傳送)。ZeroMQ 合併了擁塞檢測並調整了它的通信,以優化可用的帶寬。

Storm 示例演示

現在讓我們通過實現一個簡單的 MapReduce 拓撲結構的代碼(參見 清單 1),看一下 Storm 示例。這個示例使用了來自 Nathan 的 Storm 入門工具包(可從 GitHub 獲取)(參見 參考資料 獲取鏈接)的巧妙設計的字數示例。此示例演示了 圖 2 中所示的拓撲結構,它實現了一個包含一個螺栓的 map 轉換和包含一個螺栓的 reduce 轉換。

清單 1. 爲圖 2 中的 Storm 構建一個拓撲結構
  TopologyBuilder builder = new TopologyBuilder();
          
  builder.setSpout("spout", new RandomSentenceSpout(), 5);
          
  builder.setBolt("map", new SplitSentence(), 4)
           .shuffleGrouping("spout");
             
  builder.setBolt("reduce", new WordCount(), 8)
           .fieldsGrouping("map", new Fields("word"));
  
  Config conf = new Config();
  conf.setDebug(true);
  
  LocalCluster cluster = new LocalCluster();
  cluster.submitTopology("word-count", conf, builder.createTopology());
  
  Thread.sleep(10000);
  
  cluster.shutdown();

清單 1(添加了行號以供引用)首先使用 TopologyBuilder 聲明一個新拓撲結構。接下來在第 3 行,定義了一個噴嘴(名爲 spout),該噴嘴包含一個 RandomSentenceSpoutRandomSentenceSpout 類(也就是 nextTuple 方法)發出 5 個隨機句子的其中一個作爲它的數據。setSpout 方法末尾的 5 參數是一個並行性提示(或要爲此活動創建的任務數)。

在第 5 和 6 行。我定義了第一個螺栓(或算法轉換實體),在本例中爲 map(或 split)螺栓。這個螺栓使用 SplitSentence 令牌化輸入流並將其作爲輸出的各個單詞發出。請注意,第 6 行使用了 shuffleGrouping,它定義了對此螺栓(在本例中爲 “spout”)的輸入訂閱,還將流分組定義爲混排。這種混排分組意味着來自噴嘴的輸入將混排 或隨機分發給此螺栓中的任務(該螺栓已提示具有 4 任務並行性)。

在第 8 和 9 行,我定義了最後一個螺栓,這個螺栓實際上用於 reduce 元素,使用該元素的輸入作爲 map 螺栓。WordCount 方法實現了必要的字數統計行爲(將相似的單詞分組到一起,以維護總數),但不是混排的,所以它的輸出是一致的。如果有多個任務在實現 reduce 行爲,那麼您最終會得到分段的計數,而不是總數。

第 11 和 12 行創建和定義了一個配置對象並啓用了 Debug 模式。Config 類包含大量配置可能性(參見 參考資料,獲取有關 Storm 類樹的更多信息的鏈接)。

第 14 和 15 行創建了本地集羣(在本例中,用於定義本地模式的用途)。我定義了我的本地集羣、配置對象和拓撲結構的名稱(可通過 builder 類的 createTopology 元素獲取)。

最後,在第 17 行,Storm 休眠一段時間,然後在第 19 行關閉集羣。請記住,Storm 是一個持續運行的操作系統,所以任務可存在相當長時間,不斷處理它們訂閱的流上的新元組。

您可在 Storm 入門工具包中瞭解這個非常簡單的實現的更多信息,包括噴嘴和螺栓的細節。


摘自於使用 Twitter Storm 處理實時的大數據


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章