storm入门程序单词计数

storm入门程序单词计数

1.创建maven,java工程导入依赖

<dependencies>
          <dependency>
            <groupId>org.apache.storm</groupId>
            <artifactId>storm-core</artifactId>
            <version>1.1.1</version>
            <scope>provided</scope>
        </dependency>
  </dependencies>

在本地运行时<scope>provided</scope>注释掉,集群运行不注释,不然会冲突。

2.开发spout,随机选择一些单词发送到下一个bolt

package cn.itcast.storm.wordcount;

import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;

import java.util.Map;
import java.util.Random;

public class RandomSpout extends BaseRichSpout{

// spout  随机发送   hello  world ,   hello  kafka  ,  storm  hadoop ,  hive  storm
    //  单词切割bolt  按照空格进行切割  hello  1
    // 单词计数bolt   Map<String,Integer >  map  = new  HashMap<String,Integer>();
    private  SpoutOutputCollector collector;
    private String[]  arrays;
    private Random random;
    /**
     * 这个方法就是一个初始化的方法,只会被调用一次
     * @param conf
     * @param context
     * @param collector
     */
    @Override
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
        this.collector = collector;
        arrays = new String[]{"hello  world","hello  kafka","storm  hadoop","hive  storm"};
    }

    /**
     * nextTuple  这个方法会反复被storm框架进行调用,所有的数据发送都封装到这个方法里面来
     */
    @Override
    public void nextTuple() {
        try {
            random = new Random();
            //限制random取值范围
            int index = random.nextInt(arrays.length);
            //取出来一条数据
            String sentence = arrays[index];
            //通过collector来调用emit方法进行我们的数据发送
            collector.emit(new Values(sentence));
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * declareOutputFields  为我们发送的数据指定一个字段,方便我们下面取数据,下面的bolt就可以通过这个字段来进行获取数据
     * @param declarer
     */
    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("sentence"));
    }
}

3.开发SplitBolt 将英文句子切割成一个个的单词

package cn.itcast.storm.wordcount;

import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;

/**
 * 千万不要继承  BaseRicheBolt  有可能会出现内存的溢出
 */
public class SplitBolt extends BaseBasicBolt {


    /**
     * 这个execute方法也会被storm框架不断的调用,用于处理我们的数据
     * tuple:里面包含一些信息,包括我们发送的数据也在tuple里面
     * @param input
     * @param collector
     */
    @Override
    public void execute(Tuple input, BasicOutputCollector collector) {
        //获取我们发送的数据过来
        String sentence = input.getStringByField("sentence");
        String[] split = sentence.split("  "); //storm    hadoop    ==>  storm 1   hadoop  1
        if(split.length >0){
            //循环获取我们的单词
            for (String words : split) {
                //注意我这里发了两个数据
                collector.emit(new Values(words,1));
            }
        }
    }

    /**
     * declareOutputFields  为我们发送的数据指定一个字段,方便我们下面取数据,下面的bolt就可以通过这个字段来进行获取数据
     * @param declarer
     */
    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("words","num"));
    }
}

4.开发计数器CountBolt

package cn.itcast.storm.wordcount;

import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Tuple;

import java.util.HashMap;
import java.util.Map;

public class CountBolt extends BaseBasicBolt {

    private HashMap<String,Integer> hashMap;


    /**
     * 这个就是初始化的方法
     * @param stormConf
     * @param context
     */
    @Override
    public void prepare(Map stormConf, TopologyContext context) {
        hashMap = new HashMap<String,Integer>();
        super.prepare(stormConf, context);

    }

    /**
     * 这个execute方法会被storm框架不断的调用
     * @param input
     * @param collector
     */
    @Override
    public void execute(Tuple input, BasicOutputCollector collector) {
        //获取我们的单词
        String words = input.getStringByField("words");
        //获取我们单词的次数
        Integer num = input.getIntegerByField("num");
        //搞hashMap存起来,进行累加
        //判断hashMap当中有没有这个单词作为key,如果有,直接取出来,加一次再存进去,如果没有直接存进去,次数为1
        if(hashMap.containsKey(words)){
            //存在,先取出来,然后再存进去
            hashMap.put(words,hashMap.get(words)+num);
        }else{
            //不存在
            hashMap.put(words,num);
        }
        System.out.println(hashMap);

    }

    /**
     * 如果没有继续要处理的bolt,这个方法里面的内容就不要写了
     *
     * @param declarer
     */
    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {

    }

5.组装程序向storm集群进行提交

package cn.itcast.storm.wordcount;

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.StormSubmitter;
import org.apache.storm.generated.AlreadyAliveException;
import org.apache.storm.generated.AuthorizationException;
import org.apache.storm.generated.InvalidTopologyException;
import org.apache.storm.generated.StormTopology;
import org.apache.storm.topology.TopologyBuilder;

public class WordCountTopology {



    public static void main(String[] args) throws Exception {
        TopologyBuilder builder = new TopologyBuilder();
        //设置我们的数据源,也就是我们的spout
        builder.setSpout("randomSpout",new RandomSpout(),3);
        //通过executor来设置我们的线程的数量  wrods   1
        builder.setBolt("splitBolt",new SplitBolt(),3).localOrShuffleGrouping("randomSpout");//通过shuffleGrouping来进行分组,表示我们通过什么分组策略来接收上一个组件的数据
        //通过executor来设置我们的线程的数量
        builder.setBolt("countBolt",new CountBolt(),3).localOrShuffleGrouping("splitBolt");
        //设置Storm集群的一些配置
        Config config =new Config();
        /**
         * storm提交有两种运行模式,一种集群提交,还有一种本地运行模式,就是模拟我们的集群模式运行,方便我们的调试
         */
        //判断,如果这个程序跟的参数大于0,我们就认为是集群提交模式,否则就是本地运行模式
        if(args.length > 0){
            //通过workders来设置我们的进程的数量
            config.setNumWorkers(2);
            config.setDebug(false);
            //通过StormSubmitter来进行提交我们的storm的程序
            StormTopology topology = builder.createTopology();
            StormSubmitter.submitTopology(args[0],config,topology);
        }else{
            //storm运行的是本地模式,方便我们的测试与调试
            config.setDebug(true);
            LocalCluster cluster = new LocalCluster();
            //本地模式提交我们的storm代码
            cluster.submitTopology("wordCount",config,builder.createTopology());
        }
    }
}

喜欢就点赞评论+关注吧

这里写图片描述

感谢阅读,希望能帮助到大家,谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值