本实例为入门篇无可靠性保证实例,关于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入门基础实例(无可靠性保证实例)的更多相关文章

  1. Storm入门(七)可靠性机制代码示例

    一.关联代码 使用maven,代码如下. pom.xml  参考 http://www.cnblogs.com/hd3013779515/p/6970551.html MessageTopology. ...

  2. Vue入门系列(五)Vue实例详解与生命周期

    Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一)  http://www.cnblogs.com/gdsblog/p/78 ...

  3. Hibernate入门2.简单的项目开发实例

    Hibernate入门2.简单的项目开发实例 这一节通过一个简单的项目学习Hibernate项目的配置 代码下载 : 链接: http://pan.baidu.com/s/1zlgjl 密码: p34 ...

  4. 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息

    title: 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息 date: 2020-03-16 20:00:00 categories: python tags: crawler ...

  5. Atitit ACID解决方案2PC(两阶段提交)  跨越多个数据库实例的ACID保证

    Atitit ACID解决方案2PC(两阶段提交)  跨越多个数据库实例的ACID保证 1.1. ACID解决方案1 1.2. 数据库厂商在很久以前就认识到数据库分区的必要性,并引入了一种称为2PC( ...

  6. vim+makefile入门编辑,编译,差错实例

    vim+makefile入门编辑,编译,差错实例 vim makefile 编译 编写代码,一般在vim中编辑完后,输入:wq,在命令行下输入g++ hello.cc -o hello ,出现问题,打 ...

  7. 多例模式,保证实例的唯一性,仅适用于form窗体

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  8. Thinkphp+Ajax带关键词搜索列表无刷新分页实例

    Thinkphp+Ajax带关键词搜索列表无刷新分页实例,两个查询条件,分页和搜索关键字,懂的朋友还可以添加其他分页参数. 搜索#keyword和加载内容区域#ajax_lists <input ...

  9. Vue基础进阶 之 常用的实例属性

    Vue实例属性: vue实例直接调用的属性: 常用的实例属性: vm.$data:获取属性: vm.$el:获取实例挂载的元素: vm.$options:获取自定义选项/属性: vm.$refs:获取 ...

随机推荐

  1. ssh-keygen公钥进行免登

    A服务器地址:192.168.1.200,下面简称A B服务器地址:192.168.1.201,下面简称B 1.在A生成密钥对ssh-keygen -t rsa -P ""1执行上 ...

  2. react中的传参方式

    react是一个SPA模式,即组件嵌套租,在一个单页面的应用中组件间的数值传递是必不可少的,主要的传参方式大致有一下几种: 1,在挂载的地方给组件传参 ReactDOM.rander(<a na ...

  3. 小程序picker组件中的(普通选择器:mode = selector)

    本例代码借鉴官方picker案例: WXML: <picker bindchange="pickChange" value="{{index}}" ran ...

  4. Delphi indy线程控件TIdThreadComponent的使用

    当程序需要做耗时操作,例如访问数据库获取较多的数据.获取大文件MD5.网络访问数据量比较大.界面需要频繁刷新等等,都可以用线程来解决界面卡顿的问题,从而优化用户体验. 在知道TIdThreadComp ...

  5. DB2还原数据库备份

    用命令还原数据库备份 1.建立一个新的数据库db2 create db 数据库名 on 路径 using codeset GBK territory zh_CN 2.将需要恢复的数据库恢复得到这个新的 ...

  6. tpot ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

    机器学习训练的时候报出这个问题 是因为dataframe中的数据类型有一个是‘object’,把它转成int,或float 就行,如下 df['A'] = df['A‘].astype(int) 参考 ...

  7. JQuery案例二:实现全选、全不选和反选

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Python随笔--爬虫(下载妹子图片)

  9. Python36 二进制文件读写问题

    在Python36中写如下代码: __author__ = '-------'#-*- coding: utf-8 -*-import struct fo = open("myfile.tx ...

  10. Python处理数据库

    使用数据库驱动连接数据库 (Connection对象) 打开游标(Cursor对象),并通过它执行SQL语句(execute方法) 提交操作(commit()) 关闭连接(close()) ORM将表 ...