下面我们再上一个统计单词数量的demo,这是上一个wordsum的延伸,帮助大家理解下
需求:统计文档特定单词出现的数量,这里为了简化不设外部数据源,直接用 String text[ ]数组当作数据源
环境 : eclipse mar
apache-storm-0.9.4
链接: 所有需要的jar都已经为大家准备好了放在lib下,大家下回去,使用时千万别忘了buildpath下,源码包一起提供,大家没事也可以跟进去看看 https://pan.baidu.com/s/1wWQq6ZzO5acHIAi4ivw-DQ
WordCountSpout编写如下
package com.zxy.spout; import java.util.Map; import java.util.Random; import backtype.storm.spout.SpoutOutputCollector; import backtype.storm.task.TopologyContext; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseRichSpout; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Values; import backtype.storm.utils.Utils; public class WordCountSpout extends BaseRichSpout { private Map map; private TopologyContext context; private SpoutOutputCollector collector; String text[]={ "你好 谢谢 再见", "哈哈 再见 吃饭", "再见 你好 睡觉", "上班 谢谢 辛苦", "开心" }; Random random=new Random(); @Override public void nextTuple() { Values line = new Values(text[random.nextInt(text.length)]); collector.emit(line); Utils.sleep(1000); System.err.println("splot----- emit------- "+line); } @Override public void open(Map map, TopologyContext context, SpoutOutputCollector collector) { this.map=map; this.context=context; this.collector=collector; } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("l")); } }
WordCountBolt编写如下
package com.zxy.bolt; import java.util.List; import java.util.Map; import backtype.storm.task.OutputCollector; import backtype.storm.task.TopologyContext; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseRichBolt; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; public class WordCountBolt extends BaseRichBolt { private OutputCollector collector; @Override public void execute(Tuple input) { //随机获取单行数据, //String line = input.getString(0); //也可以用下面的代码通过field获取,这里0是返回这个String的0号位置 String line=input.getStringByField("l"); //切分字符串单词 String[] words = line.split(" "); //向后发送tuple for(String word : words){ List w=new Values(word); collector.emit(w); } } @Override public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { this.collector=collector; } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("word")); } }
WordFinalBolt编写如下
package com.zxy.bolt; import java.util.HashMap; import java.util.Map; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.MAP; import backtype.storm.task.OutputCollector; import backtype.storm.task.TopologyContext; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseRichBolt; import backtype.storm.tuple.Tuple; public class WordFinalBolt extends BaseRichBolt { private OutputCollector collector; Map<String, Integer> map=new HashMap<String,Integer>(); @Override public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { this.collector=collector; } @Override public void execute(Tuple input) { int count =1; //获取切分后的每一个单词 String word = input.getStringByField("word"); if(map.containsKey(word)) { count=(int) map.get(word)+1; } map.put(word, count); //输出 System.err.println(word+"============="+count); } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { } }
Test编写如下
package com.zxy.text; import com.zxy.bolt.WordCountBolt; import com.zxy.bolt.WordFinalBolt; import com.zxy.spout.WordCountSpout; import backtype.storm.Config; import backtype.storm.LocalCluster; import backtype.storm.topology.TopologyBuilder; import backtype.storm.tuple.Fields; public class Test { public static void main(String[] args) { TopologyBuilder tb=new TopologyBuilder(); tb.setSpout("ws", new WordCountSpout()); tb.setBolt("wordcountbolt", new WordCountBolt(),3).shuffleGrouping("ws"); tb.setBolt("wc", new WordFinalBolt(),3).fieldsGrouping("wordcountbolt",new Fields("word") ); //本地模式,测试 LocalCluster localCluster = new LocalCluster(); localCluster.submitTopology("wordconut",new Config(), tb.createTopology()); } }
结果如下
splot----- emit------- [你好 谢谢 再见]
你好=============2
谢谢=============2
再见=============2
splot----- emit------- [你好 谢谢 再见]
哈哈=============1
吃饭=============1
再见=============3
splot----- emit------- [哈哈 再见 吃饭]
开心=============1
splot----- emit------- [开心]
上班=============1
谢谢=============3
辛苦=============1
splot----- emit------- [上班 谢谢 辛苦]
再见=============4
你好=============3
睡觉=============1
splot----- emit------- [再见 你好 睡觉]
再见=============5
你好=============4
睡觉=============2
splot----- emit------- [再见 你好 睡觉]
你好=============5
谢谢=============4
再见=============6
splot----- emit------- [你好 谢谢 再见]
再见=============7
你好=============6
睡觉=============3
splot----- emit------- [再见 你好 睡觉]
你好=============7
谢谢=============5
再见=============8
splot----- emit------- [你好 谢谢 再见]
上班=============2
谢谢=============6
辛苦=============2
splot----- emit------- [上班 谢谢 辛苦]
再见=============9
你好=============8
睡觉=============4
splot----- emit------- [再见 你好 睡觉]
再见=============10
你好=============9
睡觉=============5