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. 添加Net4CollectionTypeFactory的原因

    .NET4.0已经实现了该功能 http://jahav.com/blog/nhibernate-using-net-4-iset/ NHibernate using .NET 4 ISet 0 Co ...

  2. 【CF932G】Palindrome Partition 回文自动机

    [CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...

  3. 【转】单片机中volatile定义的作用详解

    传送门:http://www.eeworld.com.cn/mcu/2011/0411/article_3928.html 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译 ...

  4. JAVAORM框架之Mybatis (Ibatis) 详解

    目录 Mybatis基础概念 Mybatis开放方式演进 Mybatis框架核心要点 关联查询 延迟加载(懒加载) 动态SQL Mybatis缓存 Mybatis逆向工程 PageHelper分页插件 ...

  5. 关注被关注表设计-UserFollowMapping

    -- ---------------------------- -- Table structure for UserFollowMapping -- ------------------------ ...

  6. Centralized Cache Management in HDFS

    Overview(概述) Centralized cache management in HDFS is an explicit caching mechanism that allows users ...

  7. svn冲突的解决

    svn文件冲突的解决 冲突后,会产生三个多余的文件. ①文件名.扩展名.mine 这是你的文件,在你更新你的工作副本之前存在于你的工作副本中--也就是说,没有冲突标志.这个文件 除了你的最新修改外没有 ...

  8. linux UVC and hardware viewer

    至于从哪个版本开始内核支持UVC,官方的话是“Linux 2.6.26 and newer includes the Linux UVC driver natively.” 1.查看摄像头ID: [r ...

  9. 洛谷P3806 点分治1 & POJ1741 Tree & CF161D Distance in Tree

    正解:点分治 解题报告: 传送门1! 传送门2! 传送门3! 点分治板子有点多,,,分开写题解的话就显得很空旷,不写又不太好毕竟初学还是要多写下题解便于理解 于是灵巧发挥压行选手习惯,开始压题解(bu ...

  10. 【python-opencv】15-图像阈值

    [微语]立志要如山,行道要如水.不如山,不能坚定,不如水,不能曲达 import cv2 as cv import numpy as np from matplotlib import pyplot ...