storm : 暴风雨
免费开源实时流计算系统
storm是一个分布式的,可靠的,容错的数据流处理系统。
暴风雨的世界
应用实例:计算数字之和,1+2+3+....+n
思路:一个spout输出数字,一个bolt求和
环境准备
jdk1.7以上的oracle jdk
idea
maven3.x
zookeeper
添加依赖
<!-- https://mvnrepository.com/artifact/org.apache.storm/storm-core -->
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>2.1.0</version>
<scope>${provided.scope}</scope>
</dependency>
创建maven Java项目
https://github.com/apache/storm/blob/v2.1.0/examples/storm-starter/pom.xml
https://github.com/apache/storm/blob/v2.1.0/DEVELOPER.md
http://storm.apache.org/releases/2.1.0/Maven.html
代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gavin</groupId>
<artifactId>storm_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.2.3</version>
<scope>provided</scope>
</dependency>-->
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-client</artifactId>
<version>2.1.0</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-starter</artifactId>
<version>2.1.0</version>
</dependency>-->
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建Topology
package com.gavn;/**
* Created by Administrator on 2020\5\24 0024.
*/
import org.apache.storm.Config;
import org.apache.storm.ILocalCluster;
import org.apache.storm.LocalCluster;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.thrift.TException;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import java.util.Map;
/**
* @Author : 小小小海文
* @CreatDate :2020\5\24 0024
* @Description :
*/
public class LocalSumStormTopology {
public static class DatasourceSpout extends BaseRichSpout {
private SpoutOutputCollector spoutOutputCollector;
/**
* 初始化
* 只执行一次
* @param conf
* @param context
* @param collector 发射器
*/
public void open(Map<String, Object> conf, TopologyContext context, SpoutOutputCollector collector) {
this.spoutOutputCollector = collector;
}
private int num = 0;
/**
* 死循环,一直执行
*/
public void nextTuple() {
this.spoutOutputCollector.emit(new Values(num++));
Utils.sleep(1000);
}
/**
* 定义输出字段名字
* @param declarer
*/
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("num"));
}
}
public static class SumSpot extends BaseRichBolt{
/**
* 初始化
* @param topoConf
* @param context
* @param collector 发射器
*/
public void prepare(Map<String, Object> topoConf, TopologyContext context, OutputCollector collector) {
}
int sum = 0;
/**
* 死循环,一直执行
* @param input
*/
public void execute(Tuple input) {
Integer num = input.getIntegerByField("num");
sum += num;
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}
public static void main(String[] args) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("DataSourceSpout",new DatasourceSpout());
builder.setBolt("SumBolt",new SumSpot()).shuffleGrouping("DataSourceSpout");
try (LocalCluster cluster = new LocalCluster()) {
//Interact with the cluster...
cluster.submitTopology("",new Config(),builder.createTopology());
} catch (TException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
作业
准备一个纯文本文件,用一个spout读取文本,第一个bolt标准化单词,第二个bolt为单词计数。
工作流程
它会把工作任务委托给不同类型的组价,每个组件负责处理一项简单特定的任务。Storm集群的输入流由一个被称作spout的组件管理,spout把数据传递给bolt,bolt要么把数据保存到某种存储器,要么把数据传递给其它的bolt。
一个storm集群就是在一连串的bolt之间转换spout传过来的数据。
示例:
用一个spout读取一个文件。文本行被spout传递给一个bolt,再被bolt按单词切割。单词流又被传给另一个bolt,第二个bolt为某些名词库里面的名词计数加1。通过数据库随时查看结果。
特点
无状态,集群状态在zookeeper中保存
每秒每节点百万tuples(元组)
使用任何语言开发。支持phython、ruby、JavaScript
可扩展、可靠、快速、事务性、容错、开发简单
核心接口
ISpout接口
接收消息并将数据发送到Topology中去处理
Storm会跟踪Spout发出去的tuple的有向图
Storm会给出ACK和failed和ToNextSpout
IComponent接口
用于使用java API定义topology
为可能的组件提供公用方法
IBolt接口
接收tuple,输出tuple。业务逻辑(filter、join等)处理单元。
IBolt生命周期:
客户端创建IBolt,被序列化到拓扑Topology中,提交到Nimbus中,分发到worker中,worker反序列化,调用prepare方法,执行Ibolt的逻辑,处理tuple
操作模式
本地模式
storm拓扑结构运行在本地计算机的单一JVM中。
远程模式
也称作生产模式。由许多运行在不同机器上的流程组成。
没有调试信息。
应用场景
实时分析
在线机器学习
连续计算
分布式RPC,ETL
频繁的CPU密集型操作并行化
核心概念
tuple:元组
Stream:流,一系列tuple
Spout:水龙头,龙卷,storm的数据源。读取原始数据为bolt提供数据。
Bolt: 雷电,转接头。从spout或其它bolt接受数据,并处理数据,处理结果可作为bolt的数据源或最终结果。过滤、聚合、连接数据源、与数据源交互。
Topology:拓扑,storm的一个任务单元。有向图,顶点是计算,边是数据流
tasks:任务。spout与bolt的执行过程
workers:工作节点。storm在worker之间均衡分发任务,监听job,启动或停止进程
storm grouping :控制tuple如何进行路由。
内置4个分组策略
架构
Nimbus
雨云
master node 。一个守护进程。负责给工作节点分发任务,并监控故障。
运行topology, 分析top,收集执行的task,分发给supervisor
supervisor
work node
有多个处理进程
多语言
创建拓扑
使用其它语言实现Spout和bolt
覆盖ShellBolt 和ShellSpout