1.storm基本介绍

  0.storm是免费、开源、分布式、跨语言、可伸缩、低延迟、容错实时流计算系统。每个节点每秒处理百万元组

  1.流计算,动态数据。mr操作的数据都是静态数据,启动mr读取文件,olap离线计算。实时监控实施舆情调查需要通过storm

2.storm名词解释

  0.Tuple元组:storm中的主要数据结构,是一个有序元素列表,默认情况下,tuple支持所有的数据类型

  1.Stream流:是tuple元组的序列

  2.Spout:数据流的源头,一般 Spout 会从一个外部的数据源读取元组然后将他们发送到拓扑中,也可以读取kafka数据队列的消息。根据需求的不同,Spout 既可以定义为可靠的数据源,也可以定义为不可靠的数据源。一个可靠的 Spout能够在它发送的元组处理失败时重新发送该元组,以确保所有的元组都能得到正确的处理;相对应的,不可靠的 Spout 就不会在元组发送之后对元组进行任何其他的处理。一个 Spout可以发送多个数据流。

  3.Bolt:转接头,逻辑处理单元。spout传递数据给bolt,bolt来进行处理并且产生新的数据输出流。bolt可以执行过滤、聚合、连接和交互

  4.Topology:spout和bolt连接在一起形成了一个bolt,一个topology是一个有向图,顶点就是计算,边就是数据流

  5.Task:storm中的每个spout或者bolt都是一个task

3.storm和hadoop对比

  storm                  hadoop

实时流处理                  批处理

无状态                    有状态

使用zk协同的主从架构             无zk的主从架构

4.storm架构

  storm是可以容错的、快速的、没有单点故障的分布式应用

  1.Nimbus:master节点,核心组件,主要工作就是运行topology,分析拓扑并收集运行task,分发可用的task给supervisor,监控topology有没有失败,依靠zk监控top的运行状况

  2.Supervisor:worker节点,每个supervisor有多个worker进程,负责代理task给worker,worker孵化执行线程,最终运行task,

    storm使用内部消息系统在nimbus和supervisor之间进行通信

    接收nimbus指令,管理worker进程完成task的派发

  3.worker:执行特定的topology,worker本身不执行任务,而是孵化executors,让executors去执行任务

  4.Executor:本质上是由worker进程孵化出来的一个线程而已。executor运行的task都属于同一个spout或者bolt

  5.task:执行实际上的任务处理工作,或者是spout或者是bolt

5.storm的工作流程

  1.nimbus等待提交的top

  2.一旦拓扑提交,就会处理拓扑并且来收集所有任务

  3.nimbus分发任务给所有可用的suoervisor

  4.在特定时间间隔之内,所有的supervisor都会发送心跳给nimbus通知他们还活着

  5.当一个supervisor挂掉之后,他就不再发送新桃给nimbus,这个时候nimbus回分派任务到另外一个supervisor

  6.当nimbus本身挂掉之后,并不会影响supervisor继续执行自己的任务,但是不会接受新的任务

  7.task完成之后,supervisor回继续等待新的task,同时挂掉的nimbus可以通过监控工具自动重启

6.安装和配置storm

[s201 ~ s204]
1.jdk
2.tar
3.环境变量
4.验证安装
$>source /etc/profile
$>./storm version
5.分发安装文件到其他节点。

6.配置
[storm/conf/storm.yaml]
storm.local.dir: "/home/centos/storm"
storm.zookeeper.servers:
- "s202"
- "s203"

storm.zookeeper.port: 2181

### nimbus.* configs are for the master
nimbus.seeds : ["s201"]

### ui.* configs are for the master
ui.host: 0.0.0.0
ui.port: 8080

supervisor.slots.ports:
- 6700
- 6701
- 6702
- 6703
7.分发

8.启动进程
a)启动s201 nimbus进程
$>storm nimbus &

b)启动s202 ~ s204 supervisor进程
$>storm supervisor &

c)启动s201的ui进程
$>storm ui &

9.通过webui查看
http://s201:8080/

7.编程实现CallLog日志统计

--------------------------

0.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.it18zhang</groupId>
<artifactId>StormDemo</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>

</project>
1.创建Spout
package com.it18zhang.stormdemo;

import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.IRichSpout;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
* Spout类,负责产生数据流
*/
public class CallLogSpout implements IRichSpout{

//Spout输出收集器
private SpoutOutputCollector collector;

//是否完成
private boolean completed = false;

//上下文
private TopologyContext context;

//随机发生器
private Random randomGenerator = new Random();

//
private Integer idx = 0;

public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
this.context = context;
this.collector = collector;
}

public void close() {
}

public void activate() {
}

public void deactivate() {

}

/**
* 下一个元组
*/
public void nextTuple() {
if (this.idx <= 1000) {
List<String> mobileNumbers = new ArrayList<String>();
mobileNumbers.add("1234123401");
mobileNumbers.add("1234123402");
mobileNumbers.add("1234123403");
mobileNumbers.add("1234123404");

Integer localIdx = 0;
while (localIdx++ < 100 && this.idx++ < 1000) {
//取出主叫
String caller = mobileNumbers.get(randomGenerator.nextInt(4));
//取出被叫
String callee = mobileNumbers.get(randomGenerator.nextInt(4));
while (caller == callee) {
//重新取出被叫
callee = mobileNumbers.get(randomGenerator.nextInt(4));
}
//模拟通话时长
Integer duration = randomGenerator.nextInt(60);

//输出元组
this.collector.emit(new Values(caller, callee, duration));
}
}
}

public void ack(Object msgId) {

}

public void fail(Object msgId) {

}

/**
* 定义输出的字段名称
*/
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("from", "to", "duration"));
}

public Map<String, Object> getComponentConfiguration() {
return null;
}
}

2.创建CreatorBolt
package com.it18zhang.stormdemo;

import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.IRichBolt;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;

import java.util.Map;

/**
* 创建CallLog日志的Bolt
*/
public class CallLogCreatorBolt implements IRichBolt {
//
private OutputCollector collector;

public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector ;
}

public void execute(Tuple tuple) {
//处理通话记录
String from = tuple.getString(0);
String to = tuple.getString(1);
Integer duration = tuple.getInteger(2);
//产生新的tuple
collector.emit(new Values(from + " - " + to, duration));
}

public void cleanup() {

}

/**
* 设置输出字段的名称
*/
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("call", "duration"));
}

public Map<String, Object> getComponentConfiguration() {
return null;
}
}

3.创建CounterBolt
package com.it18zhang.stormdemo;

import org.apache.storm.task.IBolt;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.IRichBolt;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;

import java.util.HashMap;
import java.util.Map;

/**
* 通话记录计数器Bolt
*/
public class CallLogCounterBolt implements IRichBolt{

Map<String, Integer> counterMap;
private OutputCollector collector;

public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.counterMap = new HashMap<String, Integer>();
this.collector = collector;
}

public void execute(Tuple tuple) {
String call = tuple.getString(0);
Integer duration = tuple.getInteger(1);

if (!counterMap.containsKey(call)) {
counterMap.put(call, 1);
} else {
Integer c = counterMap.get(call) + 1;
counterMap.put(call, c);
}
collector.ack(tuple);
}

public void cleanup() {
for (Map.Entry<String, Integer> entry : counterMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}

public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("call"));
}

public Map<String, Object> getComponentConfiguration() {
return null;
}
}

4.App
package com.it18zhang.stormdemo;

import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;

/**
* App
*/
public class App {
public static void main(String[] args) throws InterruptedException {
TopologyBuilder builder = new TopologyBuilder();
//设置Spout
builder.setSpout("spout", new CallLogSpout());
//设置creator-Bolt
builder.setBolt("creator-bolt", new CallLogCreatorBolt()).shuffleGrouping("spout");
//设置counter-Bolt
builder.setBolt("counter-bolt", new CallLogCounterBolt()).fieldsGrouping("creator-bolt", new Fields("call"));

Config conf = new Config();
conf.setDebug(true);

LocalCluster cluster = new LocalCluster();
cluster.submitTopology("LogAnalyserStorm", conf, builder.createTopology());
Thread.sleep(10000);

//停止集群
cluster.shutdown();
}
}

5.在生产环境的集群上部署storm top
a)修改提交方式
[App.java]
public static void main(String[] args) throws Exception {
TopologyBuilder builder = new TopologyBuilder();
//设置Spout
builder.setSpout("spout", new CallLogSpout());
//设置creator-Bolt
builder.setBolt("creator-bolt", new CallLogCreatorBolt()).shuffleGrouping("spout");
//设置counter-Bolt
builder.setBolt("counter-bolt", new CallLogCounterBolt()).fieldsGrouping("creator-bolt", new Fields("call"));

Config conf = new Config();
conf.setDebug(true);

/**
* 本地模式storm
*/
// LocalCluster cluster = new LocalCluster();
// cluster.submitTopology("LogAnalyserStorm", conf, builder.createTopology());
// Thread.sleep(10000);
StormSubmitter.submitTopology("mytop", conf, builder.createTopology());
}
b)导入jar包.
maven ...

c)在centos上运行top
$>storm jar xxx.jar com.it18zhang.stormdemo.App

8.使用storm流计算实现wordCount

  1.spout

  1. package com.it18zhang.wc;
  2.  
  3. import com.it18zhang.util.Util;
  4. import org.apache.storm.spout.SpoutOutputCollector;
  5. import org.apache.storm.task.TopologyContext;
  6. import org.apache.storm.topology.IRichSpout;
  7. import org.apache.storm.topology.OutputFieldsDeclarer;
  8. import org.apache.storm.tuple.Fields;
  9. import org.apache.storm.tuple.Values;
  10.  
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.Random;
  15.  
  16. /**
  17. * Created by stone on 2018/8/18.
  18. */
  19. public class WordCountSpount implements IRichSpout {
  20. private TopologyContext context;
  21. private SpoutOutputCollector collector;
  22. private Random r = new Random();
  23. private List<String> stats;
  24.  
  25. public void open(Map map, TopologyContext context, SpoutOutputCollector collector) {
  26. Util.sendToClient(this,"open()",);
  27. this.context = context;
  28. this.collector = collector;
  29. stats = new ArrayList<String>();
  30. stats.add("hello world tom");
  31. stats.add("hello world tomas");
  32. stats.add("hello world tomasLee");
  33. stats.add("hello world tomson");
  34.  
  35. }
  36.  
  37. public void close() {
  38.  
  39. }
  40.  
  41. public void activate() {
  42.  
  43. }
  44.  
  45. public void deactivate() {
  46.  
  47. }
  48.  
  49. public void nextTuple() {
  50. Util.sendToClient(this,"nextTuple()",);
  51. String line =stats.get(r.nextInt());
  52. collector.emit(new Values(line));
  53. }
  54.  
  55. public void ack(Object o) {
  56.  
  57. }
  58.  
  59. public void fail(Object o) {
  60.  
  61. }
  62.  
  63. public void declareOutputFields(OutputFieldsDeclarer declarer) {
  64. //声明字段
  65. declarer.declare(new Fields("line"));
  66. }
  67.  
  68. public Map<String, Object> getComponentConfiguration() {
  69. return null;
  70. }
  71. }

  2.splitBolt

 

  1. package com.it18zhang.wc;
  2.  
  3. import com.it18zhang.util.Util;
  4. import org.apache.storm.task.OutputCollector;
  5. import org.apache.storm.task.TopologyContext;
  6. import org.apache.storm.topology.IRichBolt;
  7. import org.apache.storm.topology.OutputFieldsDeclarer;
  8. import org.apache.storm.tuple.Fields;
  9. import org.apache.storm.tuple.Tuple;
  10. import org.apache.storm.tuple.Values;
  11.  
  12. import java.util.Map;
  13.  
  14. /**
  15. * Created by stone on 2018/8/18.
  16. */
  17. public class SplitBolt implements IRichBolt {
  18. private TopologyContext context;
  19. private OutputCollector collector;
  20. public void prepare(Map map, TopologyContext context, OutputCollector collector) {
  21. Util.sendToClient(this,"prepare()",);
  22. this.context=context;
  23. this.collector=collector;
  24. }
  25.  
  26. public void execute(Tuple tuple) {
  27. Util.sendToClient(this,"execute()",);
  28. String line =tuple.getString();
  29. String[] arr = line.split(" ");
  30. for(String s:arr){
  31. collector.emit(new Values(s,));
  32.  
  33. }
  34. }
  35.  
  36. public void cleanup() {
  37.  
  38. }
  39.  
  40. public void declareOutputFields(OutputFieldsDeclarer declarer) {
  41. declarer.declare(new Fields("word","count"));
  42. }
  43.  
  44. public Map<String, Object> getComponentConfiguration() {
  45. return null;
  46. }
  47. }

  3.counterBolt

 

  1. package com.it18zhang.wc;
  2.  
  3. import com.it18zhang.util.Util;
  4. import org.apache.storm.task.OutputCollector;
  5. import org.apache.storm.task.TopologyContext;
  6. import org.apache.storm.topology.IRichBolt;
  7. import org.apache.storm.topology.OutputFieldsDeclarer;
  8. import org.apache.storm.tuple.Fields;
  9. import org.apache.storm.tuple.Tuple;
  10.  
  11. import java.util.HashMap;
  12. import java.util.Map;
  13.  
  14. import static java.lang.System.out;
  15.  
  16. /**
  17. * Created by stone on 2018/8/18.
  18. */
  19. public class CountBolt implements IRichBolt {
  20. private Map<String,Integer> map;
  21. private TopologyContext context;
  22. private OutputCollector collector;
  23. public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
  24. Util.sendToClient(this,"prepare()",);
  25. this.context=context;
  26. this.collector=collector;
  27. map= new HashMap<String,Integer>();
  28. }
  29.  
  30. public void execute(Tuple tuple) {
  31. Util.sendToClient(this,"execute("+tuple.toString()+")",);
  32. String word = tuple.getString();
  33. Integer count = tuple.getInteger();
  34. if(!map.containsKey(word)){
  35. map.put(word,);
  36. }
  37. else{
  38. map.put(word,map.get(word) + count);
  39. }
  40. }
  41.  
  42. public void cleanup() {
  43. for(Map.Entry entry:map.entrySet()){
  44. out.println(entry.getKey()+":"+entry.getValue());
  45. }
  46. }
  47.  
  48. public void declareOutputFields(OutputFieldsDeclarer declarer) {
  49. declarer.declare(new Fields("word","count"));
  50. }
  51.  
  52. public Map<String, Object> getComponentConfiguration() {
  53. return null;
  54. }
  55. }

  4.App

  1. package com.it18zhang.wc;
  2.  
  3. import com.it18zhang.stormDemo.CallLogBolt;
  4. import com.it18zhang.stormDemo.CallLogCounterBolt;
  5. import org.apache.storm.Config;
  6. import org.apache.storm.LocalCluster;
  7. import org.apache.storm.StormSubmitter;
  8. import org.apache.storm.topology.TopologyBuilder;
  9. import org.apache.storm.tuple.Fields;
  10.  
  11. /**
  12. * Created by stone on 2018/8/18.
  13. */
  14. public class App {
  15. public static void main(String[] args) throws Exception {
  16. TopologyBuilder builder = new TopologyBuilder();
  17. //设置spout
  18. builder.setSpout("wcspout",new WordCountSpount()).setNumTasks();
  19. //设置bolt
  20. builder.setBolt("split-bolt",new SplitBolt()).shuffleGrouping("wcspout").setNumTasks();//通过shuffle的方式随机发送过去
  21. //设置counterBolt
  22. builder.setBolt("counter-bolt",new CountBolt()).fieldsGrouping("split-bolt",new Fields("word")).setNumTasks();//按照字段来进行分组
  23.  
  24. Config conf = new Config();
  25. conf.setDebug(true);
  26.  
  27. //LocalCluster cluster = new LocalCluster();
  28.  
  29. //cluster.submitTopology("wordCount",conf,builder.createTopology());
  30. //Thread.sleep(20000);
  31. //cluster.shutdown();
  32. StormSubmitter.submitTopology("mytop1", conf, builder.createTopology());
  33. }
  34. }

9.设置topology的并发程度和任务

配置并发度

1.设置worker数据:conf.setNumWorkers(1);

2.设置并发暗示:

  1. TopologyBuilder builder = new TopologyBuilder();
    //设置spout的并发暗示
    builder.setSpout("wcspout",new WordCountSpount(),3).setNumTasks(2);
    //设置split-bolt的并发暗示
  1. builder.setBolt("split-bolt",new SplitBolt(),4).shuffleGrouping("wcspout").setNumTasks(3);//通过shuffle的方式随机发送过去
    //设置counterBolt
    builder.setBolt("counter-bolt",new CountBolt(),5).fieldsGrouping("split-bolt",new Fields("word")).setNumTasks(4);//按照字段来进行分组
  2. 3.设置任务个数
    4.并发度等于所有任务个数的总和

storm复习笔记的更多相关文章

  1. Java基础复习笔记系列 九 网络编程

    Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...

  2. Java基础复习笔记系列 八 多线程编程

    Java基础复习笔记系列之 多线程编程 参考地址: http://blog.csdn.net/xuweilinjijis/article/details/8878649 今天的故事,让我们从上面这个图 ...

  3. Java基础复习笔记系列 七 IO操作

    Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...

  4. Java基础复习笔记系列 五 常用类

    Java基础复习笔记系列之 常用类 1.String类介绍. 首先看类所属的包:java.lang.String类. 再看它的构造方法: 2. String s1 = “hello”: String ...

  5. Java基础复习笔记系列 四 数组

    Java基础复习笔记系列之 数组 1.数组初步介绍? Java中的数组是引用类型,不可以直接分配在栈上.不同于C(在Java中,除了基础数据类型外,所有的类型都是引用类型.) Java中的数组在申明时 ...

  6. Storm学习笔记 - 消息容错机制

    Storm学习笔记 - 消息容错机制 文章来自「随笔」 http://jsynk.cn/blog/articles/153.html 1. Storm消息容错机制概念 一个提供了可靠的处理机制的spo ...

  7. Storm学习笔记 - Storm初识

    Storm学习笔记 - Storm初识 1. Strom是什么? Storm是一个开源免费的分布式计算框架,可以实时处理大量的数据流. 2. Storm的特点 高性能,低延迟. 分布式:可解决数据量大 ...

  8. Java基础复习笔记基本排序算法

    Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...

  9. Angular复习笔记7-路由(下)

    Angular复习笔记7-路由(下) 这是angular路由的第二篇,也是最后一篇.继续上一章的内容 路由跳转 Web应用中的页面跳转,指的是应用响应某个事件,从一个页面跳转到另一个页面的行为.对于使 ...

随机推荐

  1. C++入门经典-例5.17-右值引用的定义

    1:右值引用的定义: 类型 && i=被引用的对象: 左值与右值的区别在于,右值是临时变量,例如,函数的返回值,并且无法被改变. 当右值引用被初始化后,临时变量消失. 代码如下: // ...

  2. 使用 sed 命令查找和替换文件中的字符串的 16 个示例

    当你在使用文本文件时,很可能需要查找和替换文件中的字符串.sed 命令主要用于替换一个文件中的文本.在 Linux 中这可以通过使用 sed 命令和 awk 命令来完成. 在本教程中,我们将告诉你使用 ...

  3. 源码编译apache出错

    报错信息如下 exports.c:1572: error: redefinition of `ap_hack_apr_allocator_create' exports.c:177: error: ` ...

  4. 搭建jenkins集群node结点

    配置结点 首先,需要在jenkins的系统设置中新增一个结点 系统管理 -> 节点管理 -> New Node 配置Remote root directory最好和主jenkins的路径一 ...

  5. csp2019 Emiya家今天的饭题解

    qwq 由于窝太菜了,实在是不会,所以在题解的帮助下过掉了这道题. 写此博客来整理一下思路 正文 传送 简化一下题意:现在有\(n\)行\(m\)列数,选\(k\)个数的合法方案需满足: 1.一行最多 ...

  6. leetcode 34在排序数组中查找元素的第一个和最后一个位置

    class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { ve ...

  7. mysql允许外网访问 和修改mysql 账号密码

    mysql的root账户,我在连接时通常用的是localhost或127.0.0.1,公司的测试服务器上的mysql也是localhost所以我想访问无法访问,测试暂停. 解决方法如下: 1,修改表, ...

  8. Java关键字之static的典型用法分析

    static关键字是java中非常重要的一个关键字,用的好的话可以提高程序的运行性能,优化程序结构.接下来我们来总结一下static关键字及其用法.1.static变量 static变量也称作静态变量 ...

  9. 系统分析与设计HW9

    使用 ECB 实现 make reservation 用例的详细设计(包含用例简介,顺序图,类图) 用例简介: 搜索酒店 1.1 选择城市 1.2 选择日期 生成订单 2.1 选择酒店 2.2 选择日 ...

  10. Nginx负载均衡服务器实现会话粘贴的几种方式

    1. 使用Nginx 的ip_hash作为负载均衡服务并支持Session sticky 2. 使用nginx sticky第三方模块实现基于cookie的负载均衡 3.使用nginx的map指令根据 ...