Storm(2015.08.12筆記)

2015.08.12Storm

 

一、Storm簡介

Storm是Twitter開源的一個類似於Hadoop的實時數據處理框架。

 

Storm能實現高頻數據和大規模數據的實時處理。

官網資料顯示storm的一個節點在1秒鐘能夠處理100萬個100字節的消息([email protected]的CPU,24GB的內存)

(storm +kafka+flume)

 

 

二、HADOOP與STORM比較

數據來源:HADOOP處理的是HDFS上TB級別的數據(歷史數據),STORM是處理的是實時新增的某一筆數據(實時數據);

 

處理過程:HADOOP是分MAP階段和REDUCE階段,STORM是由用戶定義處理流程,流程中可以包含多個步驟,每個步驟可以是數據源(SPOUT)或處理邏輯(BOLT);

 

是否結束:HADOOP最後是要結束的,STORM是沒有結束狀態,到最後一步時,就停在那,直到有新數據進入時再從頭開始;

 

處理速度:HADOOP是以處理HDFS上大量數據爲目的,處理速度慢,STORM是隻要處理新增的某一筆數據即可,可以做到很快;

 

適用場景:HADOOP是在要處理批量數據時用的,不講究時效性,STORM是要處理某一新增數據時用的,要講時效性;

 

 

 

 

package storm;

 

import java.util.Map;

 

import backtype.storm.Config;

import backtype.storm.LocalCluster;

import backtype.storm.spout.SpoutOutputCollector;

import backtype.storm.task.OutputCollector;

import backtype.storm.task.TopologyContext;

import backtype.storm.topology.OutputFieldsDeclarer;

import backtype.storm.topology.TopologyBuilder;

import backtype.storm.topology.base.BaseRichBolt;

import backtype.storm.topology.base.BaseRichSpout;

import backtype.storm.tuple.Fields;

import backtype.storm.tuple.Tuple;

import backtype.storm.tuple.Values;

 

/**

* 數據累加的操作,spout產生數據(在這裏自己產生),bolt對數據累加求和

* @author Administrator

*

*/

public class LocalStormTopology {//都在一個類裏面實現,需要寫一個靜態name類

    public static class DataSourceSpout extends BaseRichSpout{//spout繼承BaseRichSpout類,它有3個未實現的方法

        private Map conf;//第一個未實現的方法。不知道會不會用上,先保存

        private TopologyContext context;

        private SpoutOutputCollector collector;

          

        

        /**

         * 本實例運行的是被調用一次,只能執行一次。

         */

        public void open(Map conf, TopologyContext context,

                SpoutOutputCollector collector) {//第一個未實現的方法,本實例運行時被調用一次,Map conf配置參數,可以獲取topology的配置信息,TopologyContext理解爲Topology的上下文,collector,發射器,將spout產生的數據發射出去

            this.conf = conf;

            this.context = context;

            this.collector = collector;

        }

        /**

         * 死循環的調用,心跳

         */

        int i=0;

        public void nextTuple() {//第二個未實現的方法,程序運行過程中不斷被調用,調用此方法會不斷產生數據

            System.out.println("spout:"+i);//打印每次產生的數據

            this.collector.emit(new Values(i++));//將產生的數據發射出去,發射需要emit這個方法,接受的是tuple,是list類型,tuple裏面放的是列表的數據,裏面是封裝了列表;storm裏面封裝了一個values類,new Values相當於一個tuple,直接將i傳進去,點進去,他繼承了ArrayList,相當於創建了一個list,往list裏面添加一個元素,每次都會發送數據,所以i++,每次遞增加一

            try {

                Thread.sleep(1000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

        /**

         * declarer方法的意思是聲明輸出的內容

         */

        public void declareOutputFields(OutputFieldsDeclarer declarer) {//第三個未實現的方法,spout只管發射數據,不指定目標,需要指定發射數據的的名稱,bolt讀取有標示的數據

            declarer.declare(new Fields("num"));//declare方法接受參數fields,就new一個Fields,Fileds可接受一個可變參數(3個點)或者傳一個list列表,需要指定一個字段名稱,自定義爲num。前面tuple封裝了一個數據,這裏對應也是一個字段,如果前面發射兩個參數(i++,i+2),這裏就指定2個字段('num''num'),bolt可通過num(num2)字段獲取i++數據(i+2)。spout發射的數據與字段num做了關聯

        }

    }

    

    //寫一個靜態name類,也要實現3個未實現的方法

    

    public static class Sumbolt extends BaseRichBolt{

        private Map stormConf;

        private TopologyContext context;

        private OutputCollector collector;

        public void prepare(Map stormConf, TopologyContext context,

                OutputCollector collector) {//第一個未實現的方法

            this.stormConf = stormConf;

            this.context = context;

            this.collector = collector;//只會用到這個

        }

        int sum = 0;

        public void execute(Tuple input) {//這個方法,bolt也有個死循環,不斷讀取數據,每次獲取的也是一個Tuple

            //input.getInteger(0);//通過get方法Integer傳遞的是參數,獲取的數據是列表的腳標,獲取的是list的元素,不建議使用這種方式。

            Integer value = input.getIntegerByField("num");//因爲之前已經指定了num字段,所以通過num字段獲取i++的值,使用declare方法指定的字段

            sum+=value;//因爲bolt需要對獲取的字段的值累加求和

            System.out.println("sum:"+sum);//直接將sum打印出來,打印每次累加求和的結果

            //this.collector.emit(tuple);

        }

 

        public void declareOutputFields(OutputFieldsDeclarer declarer) {

            //因爲這個bolt已經是最後一個bolt,bolt不需要往外發射數據,這裏不需要定義字段

        }

    }

      

      

    

    //需要topology。main函數將spout和bolt組裝在一起

    public static void main(String[] args) {

        TopologyBuilder topologyBuilder = new TopologyBuilder();//先new TopologyBuilder,

        topologyBuilder.setSpout("spout_id", new DataSourceSpout());//首先設置spout,id簡單自定義爲spout_id,後面需要具體指定spout類

        topologyBuilder.setBolt("bolt_id", new Sumbolt()).shuffleGrouping("spout_id");//需要將spout和bolt連接起來,bolt接spout,在bolt調用一個方法shuffleGrouping(指定'spout_id')

        

        LocalCluster localCluster = new LocalCluster();//組裝後需要運行,在本地運行,造一個本地的軌道

        localCluster.submitTopology("topology", new Config(), topologyBuilder.createTopology());//第一個是topology的名稱,第二個是配置參數是map結構,storm提供了一個配置類,new Config(點進去,繼承了HashMap),後面需要一個storm Topology,我們指定爲topologyBuilder.createTopology()

    }

 

}

 

 

 

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