大數據開發實戰:Storm流計算開發


    Storm是一個分布式、高容錯、高可靠性的實時計算系統,它對於實時計算的意義相當於Hadoop對於批處理的意義。Hadoop提供了Map和Reduce原語。同樣,Storm也對數據的實時處理提供了簡單的

  spout和bolt原語。Storm集群表面上看和Hadoop集群非常像,但Hadoop上面運行的是MapReduce的Job,而Storm上面運行的是topology(拓撲),它們非常不一樣,比如一個MapReduce的Job最終會結束,

  而一個Storm topology永遠運行(除非顯式殺掉它)

  1、Storm集群的整體架構

   

  2、Storm關鍵概念

    topology

      一個事實應用程序在Storm中稱為一個拓撲(topology), Storm中的拓撲類似於Hadoop的MapReduce任務,不同之處是,一個MapReduce任務總會運行完成,而拓撲如果不顯式結束則一直運行。

    一個Storm拓撲一般由一個或者多個spout(負責發送消息)以及一個或者多個bol(負責處理消息)做組成。

    tuple

      Storm處理的基本消息單元為tuple(元組),Tuple是一個明明值列表,元組中的字段可以是任何類型的對象。Storm用元組作為其數據模型,元組支持所有基本類型、字符串和字節數組作為字段值,

    只要實現類型的序列化接口,就可以使用該類型的對象。元組是一個值的列表。

    

      流(Stream)在Storm中是一個核心抽象概念。一個流是由無數個元組序列構成,這些元組並行、分布式的被創建和執行。在stream的許多元組中,Streams被定義為以Fields區域命名的一種模式。

    默認情況下,元組支持:Integers,longs,shorts,bytes,strings,doubles,floats,booleans,and byte arrays.

      每一個Stream在聲明的時候都會賦予一個id,單個Stream--spouts和bolts,可以使用OutputFieldsDeclarer的convenience方法聲明一個stream.而不用指定一個id,但是這種方法會給一個模式的id:  default。

    spout

      spout(噴口)是topology的流的來源,是一個topology中產生源數據流的組件。通常情況下,spout會從外表數據源(例如kafak隊列或Tiwitter API)中讀取數據,然后轉為為topology 內部的源數據。

    spout可以是可靠是,也可以是不可靠的。如果Storm處理元組失敗,可靠的spout能夠重新發射,不可靠的spout無法重新發射已經發出的元組。spout是一個主動的角色,其接口中有一個nextTuple()函數,

    Storm框架會不停的調用此函數,用戶只要在其中生成源數據即可。

      spout可以發出超過一個的流。為此,使用OutputFieldsDeclarer類的declareStream方法來聲明多個流,使用SpoutOutputCollector類的emit執行方法來進行流的提交。

      spout的主要方法是nextTuple(),nextTuple()會發出一個新的tuple到拓撲,如果沒有新的元組發出,則簡單地返回。nextTuple()方法不阻止任何的spout的實現,因為stream在同一個線程調用所有

    spout方法。

      spout的其它主要方法是ack()和fail(). 當Storm監測到一個tuple從spout發出時,ack()和fail()會被調用,要么成功完成通過拓撲,要么未能完成。ack()和fail()僅被可靠的spout調用。IRichSpout是 spout

    必須實現的接口。

    bolt

      拓撲中所有處理邏輯都在bolt(螺栓)中完成,bolt是流的處理節點,從一個拓撲接收數據后執行進行出來的 組件。bolt可以完成過濾(filter)、業務處理。連接運算(join)、連接與訪問數據庫的等任何操作。

    bolt是一個被動的角色,其接口中只有一個execute()方法,此方法在接收到消息后會被調用,用戶可以在其中執行自己希望的操作。

      bolt可以完成簡單的流的轉換,而完成復雜的流的轉換通常需要多個步驟,因此需要多個bolt。此外,bolt也可以發出超過一個的流。

      bolt的主要方法是execute()方法,該方法將一個元組作為輸入。bolt使用 OutputCollector對象發射新tuple。bolt必須為他們處理的每個元組調用OutputCollector類的ack()方法,以便Storm只是什么

    時候元組會完成。

    流分組

      定義一個topology的步驟之一是定義每個bolt接收什么樣的流作為輸入。流分組(stream grouping)用來定義一個Strream應該如何分配數據給bolts上的多個任務。

      在Storm中,有8種內置流分組方式,通過實現CustomStreamGrouping接口,用戶可以實現自己的流分組方式。

      shuffle grouping(隨機分組):這種方式會隨機分發tuple給bolt的各個任務,每個bolt實例接收相同數量的tuple。

      fields grouping(字段分組):根據指定字段的值進行分組,例如,一個數據流根據“word”字段進行分組,所有具有相同"word"字段值的(tuple)會路由到同一個(bolt)的task中。

      all grouping(全復制分組):將所有的tuple復制后分發給所有bolt task, 每個訂閱數據流的task都會接收到所有的tuple的一份備份。

      globle grouping(全局分組):這種分組方式將所有的tuples路由到唯一的任務上,Storm按照最小的taskID來接收數據的task,注意,當使用全局分組方式時,設置bolt的task並發度是沒有意義的(spout並發有意義),

      因為所有的tuple都轉發到一個task上了,此外,因為所有的tuple都轉發到一個JVM實例上,可能會引起Storm集群中某個JVM或服務器出現性能瓶頸或崩潰。

      none grouping(不分組):在功能上和隨機分組相同,是為將來預留的。

      direct grouping(指向性分組):數據源會調用emitDirect()方法來判斷一個tuple應該由哪個Storm組件來接收。

      local or shuffle grouping(本地或隨機分組):和隨機分組類似,但是會將tuple分發給同一個worker內的bolt task(如果workder內有接收數據的bolt task),其它情況下,則采用隨機分組的方式。本地或隨機分組取決於

      topology的並發度,可以減少網絡傳輸,從而提高topology性能。

      partial key grouping:與按字段分組類似,根據指定字段的一部分進行分組分發,能夠很好的實現負載均衡,將元組發送給下游的bolt對應的任務,特別是存在數據傾斜的情況下,使用partial key grouping能夠很好的 

      提高資源利用率。

 

   3、Storm並發

      Storm集群中真正運行topology的主要有三個實體:worker(工作進程),executor(線程)和task(任務)。

 

    參考資料:《離線和實時大數據開發實戰》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM