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孵化 ...
随机推荐
- Cocoa Touch框架
iOS – Cocoa Touch简介: iOS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它更加专注于触摸的接口和优化.UIKit 为开发者提供了在 iOS ...
- iOS - UIEvent事件及UIResponder响应者
在iOS中不是所有的对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件,称之为响应者对象: UIApplication.UIViewController.UIView都继承自U ...
- 静态类(static)与java值传递、引用传递小测
java中都是值传递.直接上代码了: class TestStaticA { static { System.out.println("b"); } public TestStat ...
- 公司HBase基准性能测试之准备篇
本次测试主要评估线上HBase的整体性能,量化当前HBase的性能指标,对各种场景下HBase性能表现进行评估,为业务应用提供参考. 测试环境 测试环境包括测试过程中HBase集群的拓扑结构.以及需要 ...
- codeforces 883H - Palindromic Cut - [字符串处理]
题目链接:http://codeforces.com/problemset/problem/883/H Time limit: 3000 ms Memory limit: 262144 kB Koly ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- KMP算法小记
Knuth-Morris-Pratt算法: 转载来自http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_ ...
- Why is long2ip conversion important?
Frequently Asked Questions about Convert long to IP address https://long2ip.com/faq/ What is long2ip ...
- 异步通信----WebSocket
什么是WebSocket? WebSocket API是下一代客户端-服务器的异步通信方法.该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序.WebSocket目前 ...
- on条件与where条件的区别(转)
add by zhj: 以为一直以为on和where是等价于,直到看到这篇文章,并亲自测试,才知道原来他们的功能不一样. 可以这样理解:on是在生成连接表的起作用的,where是生成连接表之后对连接表 ...