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初探的更多相关文章

  1. Storm集成Siddhi

    <Siddhi初探>中我们介绍了Siddhi的基本使用方法,并表示我们将把Siddhi集成到Storm中作为流任务处理引擎.本文将用<Storm初探>中的例子讲解如何集成Sid ...

  2. Storm消息可靠处理机制

    在很多应用场景中,分布式系统的可靠性保障尤其重要.比如电商平台中,客户的购买请求需要可靠处理,不能因为节点故障等原因丢失请求:比如告警系统中,产生的核心告警必须及时完整的知会监控人员,不能因为网络故障 ...

  3. Storm构建分布式实时处理应用初探

    最近利用闲暇时间,又重新研读了一下Storm.认真对比了一下Hadoop,前者更擅长的是,实时流式数据处理,后者更擅长的是基于HDFS,通过MapReduce方式的离线数据分析计算.对于Hadoop, ...

  4. Storm构建分布式实时处理应用初探(转)

    最近利用闲暇时间,又重新研读了一下Storm.认真对比了一下Hadoop,前者更擅长的是,实时流式数据处理,后者更擅长的是基于HDFS,通过MapReduce方式的离线数据分析计算.对于Hadoop, ...

  5. 初探storm

    Storm入门之Storm示例及UI参数讲解 Storm UI REST API Storm 1.1.0 中文文档 Apache Storm 1.1.0 中文文档 | ApacheCN Storm U ...

  6. Storm之WordCount初探

    刚接触Strom,记录下执行过程 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <proj ...

  7. Storm on Yarn :原理分析+平台搭建

    Storm on YARN: Storm on YARN被视为大规模Web应用与传统企业应用之间的桥梁.它将Storm事件处理平台与YARN(Yet Another Resource Negotiat ...

  8. Apache Storm 的历史及经验教训——Nathan Marz【翻译】

    英文原文地址 中英文对照地址 History of Apache Storm and lessons learned --项目创建者 Nathan Marz Apache Storm 最近成为了ASF ...

  9. 从Apache Storm学到的经验教训 —— storm的由来(转)

    阅读目录 Storm来源 初探 再探 构建第一个版本 被Twitter收购 开源的Storm 发布之后 Storm的技术演进 构建开发者社区版 离开Twitter 提交到Apache Apache孵化 ...

随机推荐

  1. 用logstash,elasticSearch,kibana实现数据收集和统计分析工作

    原文链接:http://www.open-open.com/lib/view/open1448799635720.html 世界上的软件80%是运行在内网的,为了使得运行在客户端的软件有良好的体验,并 ...

  2. iOS开发过程中使用Core Data应避免的十个错误

    原文出处: informit   译文出处:cocoachina Core Data是苹果针对Mac和iOS平台开发的一个框架,主要用来储存数据.对很多开发者来说,Core Data比较容易入手,但很 ...

  3. Android Meterial Design Support Library

    extends:http://inthecheesefactory.com/blog/android-design-support-library-codelab At the moment I be ...

  4. ftok函数

    ftok函数 系统建立IPC通讯(消息队列.信号量和共享内存)时必须指定一个ID值.通常情况下,该id值通过ftok函数得到. ftok原型 头文件: #include <sys/types.h ...

  5. jsp页面中引入文件路径问题的解决方案(使用request获取项目路径)【原创】

    在项目页面中,总会引入一些js和css,相对路径or绝对路径的选择就显得至关重要了!下面是项目中遇到的问题和解决方案,做一下记录! 环境: myEclipse创建工程,使用jsp+css+js,项目目 ...

  6. centos6.9环境下JDK安装部署

    1.准备jdk安装文件: 这里我使用的是 jdk-7u79-linux-x64.tar.gz 2.在 /usr/local 目录下创建 sotfware目录,并上传JDK文件: 解压文件并修改文件夹为 ...

  7. 《机器学习实战》2.2.2分析数据:使用matplotlib创建散点图

    #输出散点图 def f(): datingDataMat,datingLabels = file2matrix("datingTestSet3.txt") fig = plt.f ...

  8. 【紫书】Quadtrees UVA - 297 四叉树涂色

    题意:前序遍历给出两个像素方块.求两个方块叠加后有几个黑色格子. 题解:每次读进来一个方块,就在二维数组上涂色.每次把白色涂黑就cnt++: 具体递归方法是以右上角坐标与边长为参数,每次通过几何规律往 ...

  9. Mysql 时间类型精度截取的bug

    mysql-connector-java版本升级出现的一次问题.涉及到了时间精度的截取和四舍五入. 首先了解一点,timestamp,datetime如果不指定精度,默认的精度是秒. 当mysql-c ...

  10. Kubernetes容器调度

    Kubernetes的调度器是Kubernetes众多组件的一部分,独立于API服务器之外.调度器本身是可插拔的,任何理解调度器和API服务器之间调用关系的工程师都可以编写定制的调度器.本文后面的介绍 ...