Storm学习

目录:

  1. Storm介绍
  2. Storm应用场景
  3. Storm安装 - 伪分布式安装
  4. Storm节点介绍
  5. Storm核心组件
  6. Storm开发
  7. Storm集群架构
  8. 工作流程
  9. Storm集群搭建
  10. 大数据平台技术衔接

 

一.Storm介绍

  • Storm最初由Nathan Marz和BackType的团队创建。BackType是一家社交分析公司。后来,Storm被收购,并通过Twitter开源。在短时间内,Apache Storm成为分布式实时处理系统的标准,允许您处理大量的数据,类似于Hadoop。Apache Storm是用Java和Clojure写的。它仍然是实时分析的领导者。
  • Apache Storm是一个分布式实时大数据处理系统。
  • Storm设计用于在容错和水平可扩展方法中处理大量数据。它是一个流数据框架,具有最高的摄取率。

好处:

  1. Storm是开源的,强大的,用户友好的。它可以用于小公司和大公司。
  2. Storm是容错的,灵活的,可靠的,并且支持任何编程语言
  3. 允许实时流处理。
  4. Storm是令人难以置信的快,因为它具有巨大的处理数据的力量。
  5. Storm可以通过线性增加资源来保持性能,即使在负载增加的情况下。它是高度可扩展的
  6. Storm在几秒钟或几分钟内执行数据刷新和端到端传送响应取决于问题。它具有非常低的延迟
  7. Storm有操作智能。
  8. Storm提供保证的数据处理,即使群集中的任何连接的节点死或消息丢失。

 

二.Storm应用场景

 

三.Storm安装:linux系统下安装

先看官方文档:http://storm.apache.org/,如下,所以需要先安装与Storm对应的zookeep、Java、python

安装步骤:

  1. 安装Java
  2. 安装ZooKeeper
  3. 安装python
    安装教程:http://www.runoob.com/python/python-install.html

    安装完成后,检验python是否安装成功:
  4. 注意:
    1. 如果执行 ./configure(检查编译环境)出现错误(包含很多no的情况),如下图,是因为没有安装插件,也可以提前执行
      yum install -y gcc-c++
      插件安装成功后,再次运行 ./configure
    2. 退出python,需要执行exit();
  5. 安装Apache Storm:参考storm安装及简单操作
    1. 下载strom
    2. 上传、解压
    3. 配置环境变量
    4. 修改conf/storm.yaml(storm是用 python写的,所以特别注意空格,配置文件中少了空格或者多了控制都会运行出错)
    5. storm.zookeeper.servers:
           - "127.0.0.1:"
      #
      # nimbus.seeds: ["host1","host2","host3"]
      nimbus.host:"127.0.0.1"
      # storm.zookeeper.port: 2181可写可不写,如果zookeeper端口不是2181就必须写了
      storm.zookeeper.port: 2181
      storm.local.dir: "xxxx/apache-storm-1.x.x"
      
      supervisor.slots.ports:
        - 6700
        - 6701
        - 6702
        - 6703
    6. 启动:先启动zookeeper,再启动storm
      启动storm(以下三步)
    7. 输入jps

 

四.Storm节点介绍

Storm组件介绍

  • Nimbus:主节点,用于相应分布在集群的节点分配任务和检测故障
  • Supervisor:工作节点,用于接听工作指派并基于要求运行工作进程。
  • Zookeeper:完成Supervisor和Nimbus之间协调的服务。

 

 

五.Storm核心组件

Apache Storm从一端读取​​实时数据的原始流,并将其传递通过一系列小处理单元,并在另一端输出处理/有用的信息。

下图描述了Apache Storm的核心组件
核心理念

Storm核心概念

  1. Spout(数据源)
    1. Spout是Topology中的消息生产者即tuple的创造者
    2. 流的源。通常,Storm从原始数据源(如Twitter Streaming API,Apache Kafka队列,Kestrel队列等)接受输入数据。否则,您可以编写spouts以从数据源读取数据。
    3. “ISpout”是实现spouts的核心接口,一些特定的接口是IRichSpout,BaseRichSpout,KafkaSpout等。
    4. 可以发射多个流。
  2. Stream(被处理的数据)
    • Storm核心的抽象概念是“流”。流是一个分布式 并行创建和处理的连续元组(tuple)。
    • 流是元组的无序序列。
    • 消息流Tuple中的每个字段都有一个名字,并且不同Tuple对应的字段类型必须相同。
    • 每个消息流在定义时都会分配一个ID。
  3. Tuple(数据单元)
    1. Tuple是Storm中的主要数据结构,并且是Storm中使用的最简单单元、数据模型和元组。
    2. 它是有序元素的列表。默认情况下,Tuple支持所有数据类型。通常,它被建模为一组逗号分隔的值,并传递到Storm集群。
  4. Bolt(处理者)
    1. Bolts是逻辑处理单元,接收Spout发出元组Tuple后处理数据的组件,所有的消息处理逻辑都封装在Bolt中。Bolt负责处理数据流并产生新的输出流。
    2. Bolts可以执行过滤,聚合,加入,与数据源和数据库交互的操作。Bolts接收数据并发射到一个或多个Bolts。
    3. “IBolt”是实现Bolts的核心接口。一些常见的接口是IRichBolt,IBasicBolt等。
  5. Topology(是由Stream Grouping连接起来的Spout和Bolt节点网络)
    1. Spouts和Bolts连接在一起,形成拓扑结构。实时应用程序逻辑在Storm拓扑中指定。简单地说,拓扑是有向图,其中顶点是计算,边缘是数据流。
    2. 简单拓扑从spouts开始。Spouts将数据发射到一个或多个Bolts。Bolt表示拓扑中具有最小处理逻辑的节点,并且Bolts的输出可以发射到另一个Bolts作为输入。
    3. Storm保持拓扑始终运行,知道杀掉它。Apache Storm的主要工作是运行拓扑,并在给定时间运行任意数量的拓扑。
  6. Task(运行Spout和Bolt的线程)
    1. Task是运行Spout或Bolt的单元,Storm执行的每个Spout和Bolt称为“任务”。
    2. 在0.8及之后的版本中,Task不再与物理线程对应,同一个Spou/Bout的Task可能会共享一个物理线程,该线程称为Executor。
    3. 每一个Spout或Bolt都是通过集群中的许多任务来执行的。每一个任务相当于一个执行线程,可以通过TopologyBuilder的setSpout方法与setBolt方法为每个Spout与Bolt设置并行数,即任务数。
  7. Worker(运行这些线程的进程)
    1. Worker(工作者进程)是一个Java进程,执行拓扑的一部分任务。一个Worker进程执行一个Topology的子集,它会启动一个或者多个Executor线程来执行一个Topology的组件(Spout或Bolt)。因此,拓扑在执行时,可以跨一个或多个Worker。
    2. 不会出现一个Worker同时为多个Topology服务的情况。
  8. Stream Grouping(规则了Bolt接收何种类型数据作为输入):数据流从Spouts流到Bolts,或从一个Bolts流到另一个Bolts。流分组控制元组在拓扑中的路由方式,并帮助我们了解拓扑中的元组流。有六个内置分组,如下所述。
    1. 随机分组:在随机分组中,相等数量的元组随机分布在执行Bolts的所有工人中。下图描述了结构。
      随机分组
    2. 字段分组:元组中具有相同值的字段组合在一起,其余的元组保存在外部。然后,具有相同字段值的元组被向前发送到执行Bolts的同一进程。例如,如果流由字段“字”分组,则具有相同字符串“Hello”的元组将移动到相同的工作者。下图显示了字段分组的工作原理。
      现场分组
    3. 全局分组:所有流分配到Bolt的同一个任务。就是分配给ID最小的Task。
      全球分组
    4. 所有分组:所有分组将每个元组的单个副本发送到接收Bolts的所有实例。这种分组用于向Bolts发送信号。所有分组对于连接操作都很有用。
      所有分组
    5. 无分组:流不关心哪个Bolt会收到它的Tuple。
    6. 直接分组:元组生产者决定元组由哪个元组消费者接收。

 

六.Storm集群架构

Apache Storm的主要亮点是,它是一个容错,快速,没有“单点故障”(SPOF)分布式应用程序。我们可以根据需要在多个系统中安装Apache Storm,以增加应用程序的容量。

让我们看看Apache Storm集群如何设计和其内部架构。下图描述了集群设计。
动物园管理员框架

Apache Storm有两种类型的节点,Nimbus(主节点)和Supervisor(工作节点)。Nimbus是Apache Storm的核心组件。Nimbus的主要工作是运行Storm拓扑。Nimbus分析拓扑并收集要执行的任务。然后,它将任务分配给可用的supervisor。

Supervisor将有一个或多个工作进程。Supervisor将任务委派给工作进程。工作进程将根据需要产生尽可能多的执行器并运行任务。Apache Storm使用内部分布式消息传递系统来进行Nimbus和管理程序之间的通信。

组件描述
Nimbus(主节点)Nimbus是Storm集群的主节点。集群中的所有其他节点称为工作节点。主节点负责在所有工作节点之间分发数据,向工作节点分配任务和监视故障。
Supervisor(工作节点)遵循指令的节点被称为Supervisors。Supervisor有多个工作进程,它管理工作进程以完成由nimbus分配的任务。
Worker process(工作进程)工作进程将执行与特定拓扑相关的任务。工作进程不会自己运行任务,而是创建执行器并要求他们执行特定的任务。工作进程将有多个执行器。
Executor(执行者)执行器只是工作进程产生的单个线程。执行器运行一个或多个任务,但仅用于特定的spout或bolt。
Task(任务)任务执行实际的数据处理。所以,它是一个spout或bolt。
ZooKeeper framework(ZooKeeper框架)

Apache的ZooKeeper的是使用群集(节点组)自己和维护具有强大的同步技术共享数据之间进行协调的服务。Nimbus是无状态的,所以它依赖于ZooKeeper来监视工作节点的状态。

ZooKeeper的帮助supervisor与nimbus交互。它负责维持nimbus,supervisor的状态。

Storm是无状态的。即使无状态性质有它自己的缺点,它实际上帮助Storm以最好的可能和最快的方式处理实时数据。

Storm虽然不是完全无状态的。它将其状态存储在Apache ZooKeeper中。由于状态在Apache ZooKeeper中可用,故障的网络可以重新启动,并从它离开的地方工作。通常,像monit这样的服务监视工具将监视Nimbus,并在出现任何故障时重新启动它。

Apache Storm还有一个称为Trident拓扑的高级拓扑,它具有状态维护,并且还提供了一个高级API,如Pig。我们将在接下来的章节中讨论所有这些功能。

 

七.Storm工作流程

一个工作的Storm集群应该有一个Nimbus和一个或多个supervisors。另一个重要的节点是Apache ZooKeeper,它将用于nimbus和supervisors之间的协调。

Apache Storm的工作流程:

  1. 最初,nimbus将等待“Storm拓扑”提交给它。
  2. 一旦提交拓扑,它将处理拓扑并收集要执行的所有任务和任务将被执行的顺序。
  3. 然后,nimbus将任务均匀分配给所有可用的supervisors。
  4. 在特定的时间间隔,所有supervisor将向nimbus发送心跳以通知它们仍然运行着。
  5. 当supervisor终止并且不向心跳发送心跳时,则nimbus将任务分配给另一个supervisor。
  6. 当nimbus本身终止时,supervisor将在没有任何问题的情况下对已经分配的任务进行工作。
  7. 一旦所有的任务都完成后,supervisor将等待新的任务进去。
  8. 同时,终止nimbus将由服务监控工具自动重新启动。
  9. 重新启动的网络将从停止的地方继续。同样,终止supervisor也可以自动重新启动。由于网络管理程序和supervisor都可以自动重新启动,并且两者将像以前一样继续,因此Storm保证至少处理所有任务一次。
  10. 一旦处理了所有拓扑,则网络管理器等待新的拓扑到达,并且类似地,管理器等待新的任务。

默认情况下,Storm集群中有两种模式:

  • 本地模式 -此模式用于开发,测试和调试,因为它是查看所有拓扑组件协同工作的最简单方法。在这种模式下,我们可以调整参数,使我们能够看到我们的拓扑如何在不同的Storm配置环境中运行。在本地模式下,storm拓扑在本地机器上在单个JVM中运行。
    LocalCluster cluster=new LocalCluster();
  • 生产模式(分布式模式) - 在这种模式下,我们将拓扑提交到工作Storm集群,该集群由许多进程组成,通常运行在不同的机器上。如在storm的工作流中所讨论的,工作集群将无限地运行,直到它被关闭。
    StormSubmitter.submitTopology("xxx",conf,builder.createTopology());

八.Storm开发

练习.统计单词

 

详细步骤:

  1. 下载驱动包
  2. 创建项目,项目结构
  3. 在pom.xml中添加依赖包
        <dependency>
        	<groupId>org.apache.storm</groupId>
        	<artifactId>storm-core</artifactId>
        	<version>1.0.3</version>
        </dependency>
  4. 编写代码
    1. WordSpout.java
      package com.yiguang.storm.stormTest;
      
      import java.util.Map;
      import java.util.Random;
      
      import org.apache.storm.spout.SpoutOutputCollector;
      import org.apache.storm.task.TopologyContext;
      import org.apache.storm.topology.OutputFieldsDeclarer;
      import org.apache.storm.topology.base.BaseRichSpout;
      import org.apache.storm.tuple.Fields;
      import org.apache.storm.tuple.Values;
      
      public class WordSpout extends BaseRichSpout{
      	
      	private SpoutOutputCollector collector;
      	//定义一个全部的初始值
      	String[] init_data={"hello java","hello scala","hello storm"};
      
      	public void nextTuple() {
      		//1.拿到数据
      		String init_datum=init_data[new Random().nextInt(init_data.length)];
      		//2.拆分
      		String[] split=init_datum.split(" ");
      		//3.将拆分的东西发送到bolt
      		for(String str:split) {
      			collector.emit(new Values(str));
      		}
      	}
      	
      	/*在执行整个程序的时候,用于初始化方法
      	只执行一次*/
      	public void open(Map map, TopologyContext togologyContext, SpoutOutputCollector spoutOutputCollector) {
      		this.collector=spoutOutputCollector;
      		
      	}
      	//定义发射出去的Tuple的字段名是什么
      	public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
      		outputFieldsDeclarer.declare(new Fields("word"));
      		
      	}
      	
      }
      

       

    2. WordBolt.java
      import java.util.HashMap;
      import java.util.Map;
      
      import org.apache.storm.task.OutputCollector;
      import org.apache.storm.task.TopologyContext;
      import org.apache.storm.topology.OutputFieldsDeclarer;
      import org.apache.storm.topology.base.BaseRichBolt;
      import org.apache.storm.tuple.Fields;
      import org.apache.storm.tuple.Tuple;
      import org.apache.storm.tuple.Values;
      
      public class WordBolt extends BaseRichBolt{
      	
      	Map<String,Long> resultMap;
      	OutputCollector collector;
      
      	public void execute(Tuple tuple) {
      		//1.拿到每一个tuple --> 值列表(多个值)
      		//拿到自己想要的值
      		String word=tuple.getStringByField("word");
      		//2.处理
      		//将拿到的值放在map中
      		//放进去之前先判断该map中是否已经存在该key
      		if(resultMap.get(word)!=null) {
      			resultMap.put(word, resultMap.get(word)+1L);
      		}else {
      			resultMap.put(word, 1L);
      		}
      		
      		//3.发射
      		collector.emit(new Values(resultMap));
      		
      	}
      
      	public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
      		resultMap=new HashMap<String,Long>();
      		collector=outputCollector;
      		
      		
      	}
      
      	public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
      		outputFieldsDeclarer.declare(new Fields("resultMap"));
      		
      	}
      	
      }

       

    3. PrintBolt.java
      
      import java.util.Map;
      
      import org.apache.storm.task.OutputCollector;
      import org.apache.storm.task.TopologyContext;
      import org.apache.storm.topology.OutputFieldsDeclarer;
      import org.apache.storm.topology.base.BaseRichBolt;
      import org.apache.storm.tuple.Tuple;
      
      public class PrintBolt extends BaseRichBolt{
      
      	public void execute(Tuple tuple) {
      		//1.拿到传递过来的值
      		Map<String,Long> resultMap=(Map<String,Long>)tuple.getValueByField("resultMap");
      		//2.处理
      		for(String key:resultMap.keySet()) {
      			System.out.println(key+"-------------"+resultMap.get(key));
      		}
      	}
      
      	public void prepare(Map arg0, TopologyContext arg1, OutputCollector arg2) {
      		// TODO Auto-generated method stub
      		
      	}
      
      	public void declareOutputFields(OutputFieldsDeclarer arg0) {
      		// TODO Auto-generated method stub
      		
      	}
      
      }
      

       

    4.  WordTopolgy.java
      import java.util.HashMap;
      
      import org.apache.storm.LocalCluster;
      import org.apache.storm.shade.org.jgrapht.traverse.TopologicalOrderIterator;
      import org.apache.storm.topology.TopologyBuilder;
      
      public class WordTopology {
      	public static void main(String[] args) {
      		//1.调用主的api
      		TopologyBuilder builder=new TopologyBuilder();
      		//2.builder关联spout和bolt
      		builder.setSpout("mySpout",new WordSpout());
      		builder.setBolt("myBolt",new WordBolt()).shuffleGrouping("mySpout");
      		builder.setBolt("myPrintBolt",new PrintBolt()).shuffleGrouping("myBolt");
      		//3.发布到本地
      		LocalCluster local=new LocalCluster();
      		local.submitTopology("helloStorm", new HashMap(), builder.createTopology());
      	}
      }

       

  5. 运行WordTopolgy.java
    可能会返回

    重新以管理员运行eclipse
    运行成功之后,会一直运行,不停的进行计算

 

七.Storm集群搭建

详细步骤:使用3台虚拟机进行集群搭建

  1. 安装Java
  2. 安装zookeeper
  3. 安装python
  4. 安装storm
    1. 下载、上传、解压、安装、配置环境变量
    2. 修改配置文件
    3. 启动zookeeper,再启动storm
    4. 在web中访问strom
    5. 修改【六.Storm开发的项目】的main方法,然后将此项目打包成jar包,再storm中发布
      1. 修改:发布到集群
      2. 打包
      3. 发布

        结果:
    6. 结果

 

八.大数据平台技术衔接

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值