1. 程式人生 > >storm教程(二):Storm Topology元件和Storm資料來源和輸出選擇

storm教程(二):Storm Topology元件和Storm資料來源和輸出選擇

Storm Topology元件

前面的章節已經提到過,Storm叢集中的任務稱之為Topology。
對比Hadoop中的MapReduce job,mapper用於從資料來源中獲取資料,經過簡單處理,以一定的格式傳遞給reducer,reducer負責後續處理。
類似的,Topology任務也要從資料來源中獲取資料,然後進行後續處理。在Topology中從外部資料來源獲取資料的元件,稱之為Spout,處理資料的元件,稱之為bolt。一個Topology就是由一個或者多個的Spout和Bolt組成。
對於如下:
資料獲取 資料處理
Hadoop Mapper Reducer
Storm Spout Bolt
小貼士:Storm中有一些術語(不是全部),是按照氣象術語來命名的。例如Storm是暴風雨,spout是龍捲風的意思,bolt是雷電的意思,nimbus是雨雲的意思。

接下來,我們從簡單到複雜逐步分析一個Topology的組成。
1、最簡單的Topology:1個Spout,1個Bolt
這裡寫圖片描述
Topology:在這個Topology中,我們看到一個Spout和一個Bolt。在Topology中,我們將Spout和Bolt稱之為元件(Components)。一個Topology中,必須同時存在Spout和Bolt,Spout和Bolt數量可以隨意。最簡單的就是如上圖,一個Topology中只有一個Spout和一個Bolt。要提醒的是:Topology的元件目前只有Spout和Bolt,沒有其他元件。所以以後提到一個Topology的元件的時候,其實也就是指的是Spout或者Bolt。

Stream:我們已經知道Spout是從外部資料來源中獲取資料,以一定的格式將資料傳遞給Bolt處理。從Spout中源源不斷的給Bolt傳遞資料,形成的這個資料通道我們稱之為Stream(流)。因為Strom是一個實時計算的流式處理框架,其不是像hadoop那樣,一次性處理一大批的資料(批處理),Storm是不斷從外部資料來源中獲取最新的資料,然後將新的資料傳遞給Bolt處理(增量處理)。這樣不斷的獲取與傳輸就形成了這個資料流通道就稱之為Stream,如上圖的虛線所示。

Tuple:Tuple這個概念在上面沒有明顯的標記出來,其實Stream的最小組成單元。上圖中的Steam是一條虛線,我們可以將虛線中的每一個小線段”-“看成一個Tuple。因為Storm的Spout需要源源不斷的向Bolt傳送資料,每一次傳送的資料我們稱之為一個Tuple,也就是說,Stream流實際上就是通過這些源源不斷的Tuple組成。在Storm官網上有這樣一句話” A stream is an unbounded sequence of tuples …”,unbounded的意思其實就是說,Spout是源源不斷的傳送Tuple給Bolt的,我們不知道什麼時候會停止傳送Tuple,因此當然是無邊界的。

2、稍微複雜的Topology:1個Spout、多個Bolt
這裡寫圖片描述

Topology:在這個Topology中,我們有一個spout和3個bolt。從資料流向中,我們可以看出,spout可以將資料傳遞給多個bolt,bolt還能將資料傳遞給下一級bolt。我們知道Bolt在Topology中的作用是處理器,也就是說Bolt是負責處理資料的。對於同一條資料,我們可能會挖掘出不同方面的資訊。以中間的並列的2個Bolt為例,Spout可以將資料同時傳送給2個Bolt,這兩個Bolt分別從不同的方便來分析這條資料。我們還可以看到,位於中上方的Bolt還將資料傳遞給了下一級Bolt,這樣的原因是,有的時候,我們對於資料的分析必須是一步一步的,後一步的分析必須建立在之前分析的基礎上。

Stream:在上圖中,我們標記出了3個Stream。在Topology中,Spout與Bolt,Bolt與Bolt之間的資料通道都是一個流。圖上分別用Stream1,Stream2、Stream3標記出。這三個流有什麼區別和聯絡嗎?必須的。我們已經知道,Stream都是由Tuple組成的,而Tuple是有資料格式的,在同一個流中,Tuple的資料格式應該都是一樣的;不同流中的資料格式可能相同,也可能不同。舉例來說,假設我們這裡的Spout每次都是將相同的資料傳送給中間的2個Bolt進行處理,那麼Stream1和Stream2中Tuple的資料格式都是一樣的。前一個Bolt處理完還要將資料傳遞給下一級Bolt,處理完後的資料可能是另外一種格式。這時Stream3資料流中的資料格式可能與Stream1和Stream2就是不同的了。

3、複雜的Topology:多個Spout與多個Bolt
這裡寫圖片描述
Topology:這可以算得上一個比較複雜的Topology了,在圖中有2個Spout、4個Bolt。再次深入,我們發現一個Spout可以同時傳送資料到多個Bolt,形成多個數據流,例如Spout1。一個Bolt可以接受多個輸入,如bolt3、bolt4。事實上,一個Bolt也可以產生多個到下一級Bolt的資料流,在圖中並沒有體現出來。
我們在這裡主要介紹一下,什麼情況下一個Topology中會需要多個Spout。以一個實際案例,假設有一個移動醫療app。使用者可以在APP上進行問診,會有醫生來進行回答。這種情況下,醫生頭像在APP上顯示的位置必須是實時變化的,因為如果諮詢同一個醫生的使用者太多,後面的使用者就會排隊很長時間。因此,我們會使用Storm來實時計算醫生的權重,權重越高,說明這個醫生當前比較空閒,而權重越低,說明醫生越忙。APP會實時獲取醫生權重,將權重高的醫生,排在越前面。現在的問題就是如何計算醫生的權重,簡單說2個維度:問診量、排隊數。問診量表示的是當前醫生同時回答的病人的數量,排隊數是有幾個人在排隊。基本上問診量越低,排隊數越少,說明這個醫生越閒,權重應該就越高。在我們的Topology中,就可以用兩個Spout,一個用於從外部資料來源中獲取醫生的問診量,一個用於獲取排隊數。當然實際的情況比這個肯定複雜,這裡只是說明多個Spout在什麼情況下會使用到。

這裡寫圖片描述
DAG(有向無環圖)說明:
在storm中,spout和bolt、bolt與bolt之間的資料流向,將整合topology串起來了。在網上千篇一律的翻譯或者轉載的文章中,我們可能也看到了很多次DAG這個概念。其實DAG很簡單,有向無環圖,意思就是資料流是有方向的,但是不能形成一個環狀。如果形成了一個環狀,那麼意味著Bolt中的資料還可能傳給Spout,spout又要傳遞給Bolt。這就形成了一個死迴圈,Stream中的一個數據(Tuple)永遠也沒辦法處理完。
以下這個圖有2個環,不論是右上Bolt之間形成的環,還是右下Spout與Bout之間形成的環,都是不允許。

Storm資料來源和輸出選擇

這裡寫圖片描述
一、資料來源選擇:
1、實時性
我們已經不斷的提到Storm是一個實時計算框架。其不能一次性獲取所有的資料,進行分析處理。而是Spout不斷的從外部資料來源中獲取最新的資料,然後交給Bolt處理。這意味著,我們的Spout必須要不斷的檢測外部資料來源有沒有最新的資料,如果有新資料了,就獲取到最新的資料,然後交給Bolt處理。
2、容錯
而且我們還必須要考慮的是,如果如果一條資料處理失敗了,Spout必須還能再次獲取這條資料,否則計算出的結果的誤差就會比較大。
3、資料路由
我們已經知道一個Topology中可能會有多個Spout來從外部資料來源中獲取資料,假設我們有SPOUTA、SPOUTB、SPOUTC,那麼某些業務場景下,我們可能希望同一條資料,SPOUTA、SPOUTB、SPOUTC都能獲取到。在另外一些業務場景下,可能只希望SPOUTA獲取到這條資料。如果資料來源不支援路由,意味著,對於不同Topology,我們能需要開發不同的資料獲取機制。這無疑增大我們的開發量。

從以上簡單的幾個要求,我們可以發現,現有的JMS訊息機制,剛好滿足這個條件。主流的訊息中介軟體,如Kafka、RocketMq等。
因此,Storm的最佳資料來源,實際上就是訊息中介軟體。在本教程中,我們將使用阿里的RocketMq作為資料來源進行講解。不過,在剛開始時,我們會使用模擬的外部資料來源,來幫忙我們理解Topology的工作流程。等到熟悉之後,再使用RocketMq作為外部資料來源。
二、資料輸出目的地的選擇:
由於Storm本身是一個實時計算的框架,本身沒有提供儲存服務,大部分情況下,我們需要將計算出的結果儲存到持久化裝置中。
我們可以考慮Mysql、Hbase等任意可以持久儲存資料工具。當然,根據實際情況,如果Storm輸出的資料量比較大的話,我們還是會考慮Hbase,如果量比較小的話,我們可以使用Mysql。