storm入门基础实例(无可靠性保证实例)
本实例为入门篇无可靠性保证实例,关于storm的介绍,以及一些术语名词等,可以参考Storm介绍(一)、Storm介绍(二)。
本案例是基于storm0.9.3版本
1.案例结构
案例:Word Count案例
语句Spout --> 语句分隔Bolt --> 单词计数Bolt --> 上报Bolt
2.语句生成Spout - SentenceSpout
作为入门案例,我们直接从一个数组中不断读取语句,作为数据来源。
SentenceSpout不断读取语句将其作为数据来源,组装成单值tuple(键名sentence,键值为祖父穿格式的语句)向后发射。
{"sentence":"i am so shuai!"}
3.代码结构

话不多说,上代码:
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.generated.StormTopology;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields; public class WCTopologyDriver {
public static void main(String[] args) throws Exception {
//1.创建组件
SentenceSpout sentenceSpout = new SentenceSpout();
SplitSentenceBolt splitSentenceBolt = new SplitSentenceBolt();
WordCountBolt wordCountBolt = new WordCountBolt();
ReportBolt reportBolt = new ReportBolt(); //2.创建构建者
TopologyBuilder builder = new TopologyBuilder(); //3.向构建者描述拓扑结构
builder.setSpout("Sentence_Spout", sentenceSpout);
builder.setBolt("Split_Sentence_Bolt", splitSentenceBolt)
.shuffleGrouping("Sentence_Spout");
builder.setBolt(" ", wordCountBolt)
.fieldsGrouping("Split_Sentence_Bolt", new Fields("word"));
builder.setBolt("Report_Bolt", reportBolt)
.shuffleGrouping("Word_Count_Bolt"); //4.通过构建者创建拓扑
StormTopology topology = builder.createTopology(); //5.将拓扑提交到集群中运行
//Config conf = new Config();
//StormSubmitter.submitTopology("WC_Topology", conf, topology); //5.创建本地集群 模拟运行拓扑
LocalCluster cluster = new LocalCluster();
Config conf = new Config();
cluster.submitTopology("WC_Topology", conf, topology); Thread.sleep(10 * 1000);
cluster.killTopology("WC_Topology");
cluster.shutdown();
}
}
import java.util.Map; 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; public class SentenceSpout extends BaseRichSpout { private String [] sentences = {
"my name is park",
"i am so shuai",
"do you like me",
"are you sure you do not like me",
"ok i am sure"
}; private SpoutOutputCollector collector = null; /**
* 初始化的方法
* 当前组件初始化时 调用 执行初始化操作
* conf:代表当前topology相关配置信息
* context:代表上下文环境 可以用来获取 任务id 组件id 输入输出相关信息 等信息
* collector:代表发送者 可以用来发送 拓扑 可以在任何时候发送 此对象线程安全 可以放心的保存在类的内部作为类的成员
*/
@Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
this.collector = collector;
} /**
* storm会在一个单一线程中不停的调用此方法 要求发送tuple
* 如果有数据要发 直接发 如果没有数据要发 也不要阻塞这个方法 而是直接返回即可
* 如果真的没有数据要发送 最好睡上一个很短的时间 以便释放cpu 不至于浪费过多资源
*/
private int index = 0;
@Override
public void nextTuple() {
if(index < sentences.length){
collector.emit(new Values(sentences[index]));
index++;
}else{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
} /**
* 用来声明输出信息
* declarer:声明输出的流的编号 输出的tuple中的字段 以及是否是一个指向性的流
* 要注意 组件发送的tuple的结构 都要现在此方法中声明
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("sentence"));
} }
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 SplitSentenceBolt extends BaseRichBolt{ private OutputCollector collector = null; /**
* 初始化的方法
* 当前组件初始化时 调用 执行初始化操作
* conf:代表当前topology相关配置信息
* context:代表上下文环境 可以用来获取 任务id 组件id 输入输出相关信息 等信息
* collector:代表发送者 可以用来发送 拓扑 可以在任何时候发送 此对象线程安全 可以放心的保存在类的内部作为类的成员
*/
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} /**
* 对于输入的tuple 一个tuple触发一次此方法
* 在这个方法中对tuple进行处理
*/
@Override
public void execute(Tuple input) {
String sentence = input.getStringByField("sentence");
String [] words = sentence.split(" ");
for(String word : words){
collector.emit(new Values(word));
}
} /**
* 用来声明输出信息
* declarer:声明输出的流的编号 输出的tuple中的字段 以及是否是一个指向性的流
* 要注意 组件发送的tuple的结构 都要现在此方法中声明
*/
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
} }
import java.util.HashMap;
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 = null; @Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} private Map<String,Integer> map = new HashMap<>();
@Override
public void execute(Tuple input) {
String word = input.getStringByField("word");
map.put(word, map.containsKey(word) ? map.get(word)+1 : 1);
collector.emit(new Values(word,map.get(word)));
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word","count"));
} }
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.Tuple; public class ReportBolt extends BaseRichBolt { @Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) { } @Override
public void execute(Tuple input) {
String word = input.getStringByField("word");
int count = input.getIntegerByField("count");
System.out.println("--单词数量发生变化:"+word+"~"+count+"--");
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) { } }
运行结果:

补充,以下是本文案例用到的jar包,由于太大,没有上传,下载0.9.3的storm源码,解压后文件夹中的lib下的所有jar包:
storm入门基础实例(无可靠性保证实例)的更多相关文章
- Storm入门(七)可靠性机制代码示例
一.关联代码 使用maven,代码如下. pom.xml 参考 http://www.cnblogs.com/hd3013779515/p/6970551.html MessageTopology. ...
- Vue入门系列(五)Vue实例详解与生命周期
Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一) http://www.cnblogs.com/gdsblog/p/78 ...
- Hibernate入门2.简单的项目开发实例
Hibernate入门2.简单的项目开发实例 这一节通过一个简单的项目学习Hibernate项目的配置 代码下载 : 链接: http://pan.baidu.com/s/1zlgjl 密码: p34 ...
- 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息
title: 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息 date: 2020-03-16 20:00:00 categories: python tags: crawler ...
- Atitit ACID解决方案2PC(两阶段提交) 跨越多个数据库实例的ACID保证
Atitit ACID解决方案2PC(两阶段提交) 跨越多个数据库实例的ACID保证 1.1. ACID解决方案1 1.2. 数据库厂商在很久以前就认识到数据库分区的必要性,并引入了一种称为2PC( ...
- vim+makefile入门编辑,编译,差错实例
vim+makefile入门编辑,编译,差错实例 vim makefile 编译 编写代码,一般在vim中编辑完后,输入:wq,在命令行下输入g++ hello.cc -o hello ,出现问题,打 ...
- 多例模式,保证实例的唯一性,仅适用于form窗体
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- Thinkphp+Ajax带关键词搜索列表无刷新分页实例
Thinkphp+Ajax带关键词搜索列表无刷新分页实例,两个查询条件,分页和搜索关键字,懂的朋友还可以添加其他分页参数. 搜索#keyword和加载内容区域#ajax_lists <input ...
- Vue基础进阶 之 常用的实例属性
Vue实例属性: vue实例直接调用的属性: 常用的实例属性: vm.$data:获取属性: vm.$el:获取实例挂载的元素: vm.$options:获取自定义选项/属性: vm.$refs:获取 ...
随机推荐
- idea函数被调用
打开一个复杂的程序或者项目进行分析的时候,我们就需要知道一个方法在哪里被调用,用于迅速厘清代码逻辑.操作如下:选中函数,右键,点击Find Usages. 如图: 操作简单,但右键还是没有快捷键方便. ...
- 2015-11-03 ado.net3
DataReader和DateSet区别: 1. DataReader是一行一行的读,且只能向前读.DateSet是一次性读取出来放到内存中,所以,DataReader读取速度更快,占用内存更低. 2 ...
- VS2013中调驱动
https://msdn.microsoft.com/en-us/library/windows/hardware/jj200334(v=vs.85).aspx 需要注意的就是 debugport:n ...
- [NOIP2013D1]
T1 Problem 洛谷 Solution 感觉我写的也不是正解... 我是先找出每个循环节的长度l...然后用快速幂求出10 ^ k % l的值.. Code #include<cmath& ...
- docker 下安装gitlab
1.找到docker镜像 docker search gitlab 2.下载gitlab镜像 docker pull gitlab/gitlab-ce/ 3.通常会将 GitLab 的配置 (etc ...
- centos7搭建时间服务器
时区概念 GMT.UTC.CST.DST UTC:整个地球分为二十四个时区,每个时区都有自己的本地时间,在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时间(UTC:Univers ...
- 第2次作业 -- 熟悉 JUnit 测试
2.1 Mooctest 使用心得 Mooctest很方便,可以即时测评自己写的测试代码,获得覆盖率和报告,不需要自己安装配置环境 而且安装配置插件的环境也很简单,可以专注于测试本身 2.2 Juni ...
- Unity资源内存管理--webstream控制
一 使用前提 1,需要使用资源热更新 2,使用Assetbundle资源热更(AssetBundle是产生webstream的元凶) 二 为什么要用AssetBundle AssetBundle本质上 ...
- 使用PuTTY软件远程登录root被拒:access denied
PuTTY是一个Telnet.SSH.rlogin.纯TCP以及串行接口连接软件. 使用PuTTY软件远程登录root时,提示:ACCESS DENIED,很有可能是由sshd的默认配置造成的. 可以 ...
- [c++]关于strcpy函数溢出解决方案
必须包含的头文件:<string.h> 可改写成安全函数strcpy_s 找到[项目属性],点击[C++]里的[预处理器],对[预处理器]进行编辑,在里面加入一段代码:_CRT_SECUR ...