Storm初探
Storm是一种分布式流式处理技术,这一点和Spark与Hadoop的批处理特性有明显的区别。
在数据连续产生,响应时延要求较低的场景中,Storm具有Spark不可比拟的优势。
网络性能监控系统中,Storm可以在秒级Dashboard监控,分钟级告警监控中大显生手。
学习任何技术,首先从Hello Wold开始,Storm也不例外,下面代码实现了这样一个例子:
(1) NamesReader Spout读取一行名字字符串,发送给NameSpliter;
(2) NameSpliter Bolt按照空格分割名字字符串,每个名字发送给HelloWorld;
(3) HelloWorld Bolt打印Hello world + 名字。
注:Spout是Storm有向网络的起始节点,Bolt是Storm有向网络的其他节点。数据在Storm有向网络中流动,节点则可以对流经的数据进行处理。
1、 名字字符串读取Spout
package com.coshaho.learn.storm; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields; /**
*
* NamesReaderSpout.java Create on 2017年6月4日 下午10:57:32
*
* 类功能说明: 读取名字列表并派发
*
* Copyright: Copyright(c) 2013
* Company: COSHAHO
* @Version 1.0
* @Author coshaho
*/
public class NamesReaderSpout implements IRichSpout
{
private static final long serialVersionUID = 1L;
private SpoutOutputCollector collector; @SuppressWarnings("rawtypes")
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector)
{
this.collector = collector;
} public void nextTuple()
{
List<Object> list = new ArrayList<Object>();
try
{
Thread.sleep(5 * 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println();
list.add("刘备 关羽 张飞");
// 第一个参数是传递的业务数据,第二个参数是消息标识,用于追踪消息是否正确处理
this.collector.emit(list, "stream");
list.clear();
list.add("曹操 郭嘉 荀彧");
this.collector.emit(list, "stream"); } public void declareOutputFields(OutputFieldsDeclarer declarer)
{
// 必须设置,否则topo启动失败,names对应传递消息第一个元素,即list(0)
declarer.declare(new Fields("names"));
} public void close() {
// TODO Auto-generated method stub
} public void activate() {
// TODO Auto-generated method stub
} public void deactivate() {
// TODO Auto-generated method stub
} public void ack(Object msgId) {
// TODO Auto-generated method stub
} public void fail(Object msgId) {
// TODO Auto-generated method stub
} public Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return null;
}
}
2、 名字字符串分割Bolt
package com.coshaho.learn.storm; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple; /**
*
* NamesSpliterBolt.java Create on 2017年6月4日 下午10:58:08
*
* 类功能说明: 名字列表按空格分割
*
* Copyright: Copyright(c) 2013
* Company: COSHAHO
* @Version 1.0
* @Author coshaho
*/
public class NamesSpliterBolt implements IRichBolt
{
private static final long serialVersionUID = 1L;
private OutputCollector collector; @SuppressWarnings("rawtypes")
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector)
{
this.collector = collector;
} public void execute(Tuple input)
{
// 打印线程号用于追踪Storm的分配策略
Thread current = Thread.currentThread();
String names = input.getString(0);
System.out.println("准备拆分" + names + "。当前线程号是" + current.getId() + "。");
List<Tuple> inputList = new ArrayList<Tuple>();
inputList.add(input);
String[] nameArray = names.split(" ");
for(String name : nameArray)
{
List<Object> splitList = new ArrayList<Object>();
splitList.add(name);
collector.emit(inputList, splitList);
}
collector.ack(input);
} public void declareOutputFields(OutputFieldsDeclarer declarer)
{
// 必须设置,否则topo启动失败
declarer.declare(new Fields("name"));
} public void cleanup() {
// TODO Auto-generated method stub
} public Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return null;
}
}
3、 HelloWorld Bolt
package com.coshaho.learn.storm; import java.util.Map; import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Tuple; /**
*
* HelloWorldBolt.java Create on 2017年6月4日 下午10:58:26
*
* 类功能说明: Storm Hello World
*
* Copyright: Copyright(c) 2013
* Company: COSHAHO
* @Version 1.0
* @Author coshaho
*/
public class HelloWorldBolt implements IRichBolt
{
private static final long serialVersionUID = 1L;
private OutputCollector collector; @SuppressWarnings("rawtypes")
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector)
{
this.collector = collector;
} public void execute(Tuple input)
{
// 打印线程号用于追踪Storm的分配策略
Thread current = Thread.currentThread();
String name = input.getString(0);
System.out.println("你好," + name + "。欢迎来到Storm世界。当前线程号是" + current.getId() + "。");
collector.ack(input);
} public void cleanup() {
// TODO Auto-generated method stub
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
// TODO Auto-generated method stub
} public Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return null;
}
}
4、 Storm TOPO网络任务启动
package com.coshaho.learn.storm; import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields; public class StormTest
{
public static void main(String[] args) throws InterruptedException
{
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("names-reader", new NamesReaderSpout());
// 启动两个名字分割Task,名字列表随机分配给一个Task
builder.setBolt("names-spliter", new NamesSpliterBolt(), 2)
.shuffleGrouping("names-reader");
// 启动两个Hello World Task,相同名字发送到同一个Task
builder.setBolt("hello-world", new HelloWorldBolt(), 2)
.fieldsGrouping("names-spliter", new Fields("name")); Config conf = new Config();
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("storm-test", conf, builder.createTopology());
}
}
5、 执行结果
准备拆分刘备 关羽 张飞。当前线程号是85。
你好,刘备。欢迎来到Storm世界。当前线程号是79。
你好,关羽。欢迎来到Storm世界。当前线程号是81。
你好,张飞。欢迎来到Storm世界。当前线程号是81。
准备拆分曹操 郭嘉 荀彧。当前线程号是87。
你好,荀彧。欢迎来到Storm世界。当前线程号是79。
你好,曹操。欢迎来到Storm世界。当前线程号是81。
你好,郭嘉。欢迎来到Storm世界。当前线程号是81。 准备拆分刘备 关羽 张飞。当前线程号是87。
准备拆分曹操 郭嘉 荀彧。当前线程号是85。
你好,荀彧。欢迎来到Storm世界。当前线程号是79。
你好,曹操。欢迎来到Storm世界。当前线程号是81。
你好,郭嘉。欢迎来到Storm世界。当前线程号是81。
你好,刘备。欢迎来到Storm世界。当前线程号是79。
你好,关羽。欢迎来到Storm世界。当前线程号是81。
你好,张飞。欢迎来到Storm世界。当前线程号是81。
6、 maven依赖
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>0.9.2-incubating</version>
</dependency>
Storm初探的更多相关文章
- Storm集成Siddhi
<Siddhi初探>中我们介绍了Siddhi的基本使用方法,并表示我们将把Siddhi集成到Storm中作为流任务处理引擎.本文将用<Storm初探>中的例子讲解如何集成Sid ...
- Storm消息可靠处理机制
在很多应用场景中,分布式系统的可靠性保障尤其重要.比如电商平台中,客户的购买请求需要可靠处理,不能因为节点故障等原因丢失请求:比如告警系统中,产生的核心告警必须及时完整的知会监控人员,不能因为网络故障 ...
- Storm构建分布式实时处理应用初探
最近利用闲暇时间,又重新研读了一下Storm.认真对比了一下Hadoop,前者更擅长的是,实时流式数据处理,后者更擅长的是基于HDFS,通过MapReduce方式的离线数据分析计算.对于Hadoop, ...
- Storm构建分布式实时处理应用初探(转)
最近利用闲暇时间,又重新研读了一下Storm.认真对比了一下Hadoop,前者更擅长的是,实时流式数据处理,后者更擅长的是基于HDFS,通过MapReduce方式的离线数据分析计算.对于Hadoop, ...
- 初探storm
Storm入门之Storm示例及UI参数讲解 Storm UI REST API Storm 1.1.0 中文文档 Apache Storm 1.1.0 中文文档 | ApacheCN Storm U ...
- Storm之WordCount初探
刚接触Strom,记录下执行过程 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <proj ...
- Storm on Yarn :原理分析+平台搭建
Storm on YARN: Storm on YARN被视为大规模Web应用与传统企业应用之间的桥梁.它将Storm事件处理平台与YARN(Yet Another Resource Negotiat ...
- Apache Storm 的历史及经验教训——Nathan Marz【翻译】
英文原文地址 中英文对照地址 History of Apache Storm and lessons learned --项目创建者 Nathan Marz Apache Storm 最近成为了ASF ...
- 从Apache Storm学到的经验教训 —— storm的由来(转)
阅读目录 Storm来源 初探 再探 构建第一个版本 被Twitter收购 开源的Storm 发布之后 Storm的技术演进 构建开发者社区版 离开Twitter 提交到Apache Apache孵化 ...
随机推荐
- TX失败策略2
自从有了人类,就有了智慧和精神.但总有一些思想家跳出来说人定胜天的理论,这是一种严重的误导.人类社会和自然界一样,遵守统一的自然定律.人就像不能改变物理定律一样改社会定律.更不可能因片面的社会现象遮盖 ...
- Mongoose学习参考资料
我们学习node操作mongodb数据库时,可能经常要用到MongoDB 数据库的模型工具Mongoose,下面是我整理的一些学习资料: 番外篇之——使用 Mongoose:https://githu ...
- 'cmd' 不是内部或外部命令,也不是可运行的程序 或批处理文件.
添加path内容: %SystemRoot%\system32; %SystemRoot%; %SystemRoot%\System32\Wbem;
- ztree学习---将默认勾选的展开
这里只给出前台页面上的代码,数据可以从后台获取,注意,在封装数据的时候,注意:Id(节点的id,可以是数字也可以是字符串) , pid(父亲节点的id) , name(节点名称)不能少 . html页 ...
- git 提示:fatal: remote origin already exists. 错误解决
今天git连接远程库的时候出现fatal: remote origin already exists. 这个错误 大概是之前连接过别的库吧 然后我们的解决办法就是删除之前的连接 1.删除git远程仓库 ...
- java.sql.SQLException:The Network Adapter could not establish the connection
数据库连不上了,可能数据断了或者修改IP了
- MTU-TCP/IP协议栈-linux kernel-TCP丢包重传-UDP高性能-AI- ip数据报 tcp数据报
1.IP协议首部 TCP报文段的首部 UDP分组结构 ip数据报 tcp数据报 UDP校验 w 报文长度该字段指定UDP报头和数据总共占用的长度.可能的最小长度是8字节,因为UDP报头已经占用了 ...
- 杭电oj题目分类
基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058.1 ...
- 洛谷P4437 排列 [HNOI/AHOI2018] 贪心
正解:贪心 解题报告: 传送门! 发现做题龟速,,,所以懒得写题目大意辣自己get一下QAQ 首先看到ai<=n,又当ai=j时j在i的前面,所以就变成对于每个点i有一个约束,即要求第ai个节点 ...
- java进程和线程的区别
什么是进程,什么是线程系统要做一件事,运行一个任务,所有运行的任务通常就是一个程序:每个运行中的程序就是一个进程,这一点在任务管理器上面可以形象的看到.当一个程序运行时,内部可能会包含多个顺序执行流, ...