一、Storm 理论基础
1、Storm是什么
Storm是一个开源的分布式实时计算系统,可以简单、可靠的处理大量的数据流。被称作“实时的hadoop”。
2、什么场景可以使用Storm
Storm有很多使用场景:如实时分析,在线机器学习,持续计算, 分布式RPC,ETL等等。Storm支持水平扩展,具有高容错性,保证每个消息都会得到处理,而且处理速度很快(在一个小集群中,每个结点每秒可以处理 数以百万计的消息)。Storm的部署和运维都很便捷,而且更为重要的是可以使用任意编程语言来开发应用。
3、Storm有哪些特点
编程模型简单:类似于MapReduce降低了并行批处理复杂性,Storm降低了进行实时处理的复杂性。
高可靠性:Storm可以保证spout发出的每条消息都能被“完全处理”,这也是直接区别于其他实时系统的地方
高容错性:如果在消息处理过程中出了一些异常,Storm会重新安排这个出问题的处理单元。Storm保证一个处理单元永远运行(除非你显式杀掉这个处理单元)。
可扩展:计算是在多个线程、进程和服务器之间并行进行的。
4、storm 中的相关概念总结
名称 | 描述 |
---|---|
Topologies | 拓扑,也俗称一个任务 |
Spouts | 拓扑的消息源 |
Bolts | 拓扑的处理逻辑单元 |
tuple | 消息元组 |
Streams | 流 |
Stream groupings | 流的分组策略 |
Tasks | 任务处理单元 |
Executor | 工作线程 |
Workers | 工作进程 |
Configuration | topology的配置 |
5、storm 和hadoop 的比较
Hadoop 在本质上是一个批处理系统,数据被引入 Hadoop 文件系统 (HDFS) 并分发到各个节点进行处理。当处理完成时,结果数据返回到 HDFS 供始发者使用。Hadoop的高吞吐,海量数据处理的能力使得人们可以方便地处理海量数据。但是,Hadoop的缺点也和它的优点同样鲜明——延迟大,响应缓慢,运维复杂。Storm就是为了弥补Hadoop的实时性为目标而被创造出来。Storm 支持创建拓扑结构来转换没有终点的数据流。不同于 Hadoop 作业,这些转换从不停止,它们会持续处理到达的数据。
其中storm 和 hadoop 中各个进程之间的对比总结如下:
- Topology 与 Mapreduce
一个关键的区别是: 一个MapReduce job最终会结束, 而一个topology永远会运行(除非你手动kill掉) - Nimbus 与 ResourManager
在Storm的集群里面有两种节点: 控制节点(master node)和工作节点(worker node)。控制节点上面运行一个叫Nimbus后台程序,它的作用类似Hadoop里面的JobTracker。Nimbus负责在集群里面分发代码,分配计算任务给机器, 并且监控状态。 - Supervisor (worker进程)与NodeManager(YarnChild)
每一个工作节点上面运行一个叫做Supervisor的节点。Supervisor会监听分配给它那台机器的工作,根据需要启动/关闭工作进程。每一个工作进程执行一个topology的一个子集;一个运行的topology由运行在很多机器上的很多工作进程组成。
二、Storm的体系架构
Storm 整体体系架构图如下:
或许你在看完上图的体系架构还是会感觉到比较困惑,别急,下面就让我们来看看Storm中的各个组件之间的关系是是怎么样的,在你了解了各个组件之间的关系后,就会对上述架构有更加深入的理解了。
1、Storm中的Nimbus和Supervisor
在storm中Nimbus和Supervisor的关系图如下:
通过上图我们了解到Nimbus和Supervisor之间的所有协调工作都是通过Zookeeper集群完成。同时,Nimbus进程和Supervisor进程都是快速失败(fail-fast)和无状态的。所有的状态要么在zookeeper里面, 要么在本地磁盘上。这也就意味着你可以用kill -9来杀死Nimbus和Supervisor进程, 然后再重启它们,就好像什么都没有发生过。这个设计使得Storm异常的稳定。
2、Storm中的Topologies
一个topology是spouts和bolts组成的图, 通过stream groupings将图中的spouts和bolts连接起来,如下图:
3、Storm中的Stream
源源不断传递的tuple就组成了stream。是Storm中对数据进行的抽象,它是时间上无界的tuple元组序列。 而这些tuple序列会以一种分布式的方式并行地创建和处理。
4、Storm中的Spouts
消息源spout是Storm里面一个topology里面的消息生产者,一般来说消息源会从一个外部源读取数据并且向topology里面发出消息:tuple。需要注意的是Spouts可以是可靠的也可以是不可靠的:如果这个tuple没有被storm成功处理,可靠的消息源spouts可以重新发射一个tuple, 但是不可靠的消息源spouts一旦发出一个tuple就不能重发了;
消息源可以发射多条消息流stream:
使用OutputFieldsDeclarer.declareStream来定义多个stream,
然后使用SpoutOutputCollector来发射指定的stream。
5、Storm中的Bolts
所有的消息处理逻辑被封装在bolts里面。Bolts可以做很多事情:过滤,聚合,查询数据库等等。同时,Bolts可以简单的做消息流的传递,也可以通过多级Bolts的组合来完成复杂的消息流处理;比如求TopN、聚合操作等(如果要把这个过程做得更具有扩展性那么可能需要更多的步骤)
- Bolts可以发射多条消息流:
使用OutputFieldsDeclarer.declareStream定义stream;
使用OutputCollector.emit来选择要发射的stream; - Bolts的主要方法是execute,:
它以一个tuple作为输入,使用OutputCollector来发射tuple;
通过调用OutputCollector的ack方法,以通知这个tuple的发射者spout; - Bolts一般的流程:
处理一个输入tuple, 发射0个或者多个tuple, 然后调用ack通知storm自己已经处理过这个tuple了;
6、Storm中的Stream groupings
定义一个topology的关键一步是定义每个bolt接收什么样的流作为输入。stream grouping就是用来定义一个stream应该如何分配数据给bolts;
Storm里面有7种类型的stream grouping:
- Shuffle Grouping——随机分组,随机派发stream里面的tuple,保证每个bolt接收到的tuple数目大致相同; Fields Grouping——按字段分组,比如按userid来分组, 具有同样userid的tuple会被分到相同的Bolts里的一个task,而不同的userid则会被分配到不同的bolts里的task;
AllGrouping——广播发送,对于每一个tuple,所有的bolts都会收到;Global Grouping——全局分组, 这个tuple被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task;
Non Grouping——不分组,这个分组的意思是说stream不关心到底谁会收到它的tuple。目前这种分组和Shuffle grouping是一样的效果, 有一点不同的是storm会把这个bolt放到这个bolt的订阅者同一个线程里面去执行; Direct
Grouping——直接分组, 这是一种比较特别的分组方法,用这种分组意味着消息的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为Direct Stream的消息流可以声明这种分组方法。而且这种消息tuple必须使用emitDirect方法来发射。消息处理者可以通过TopologyContext来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id);Local or shuffle grouping——如果目标bolt有一个或者多个task在同一个工作进程中,tuple将会被随机发生给这些tasks。否则,和普通的Shuffle
Grouping行为一致。
7、Storm中的Workers
一个topology可能会在一个或者多个worker(工作进程)里面执行。每个worker是一个物理JVM并且执行整个topology的一部分;比如,对于并行度是300的topology来说,如果我们使用50个工作进程来执行,那么每个工作进程会处理其中的6个tasks。除此之外,Storm会尽量均匀的工作分配给所有的worker。
8、Storm中的Tasks
每一个spout和bolt会被当作很多task在整个集群里执行。在storm0.8之后,task不再与物理线程对应,同一个spout/bolt的task可能会共享一个物理线程,该线程称为executor,每一个executor对应到一个线程,在这个线程上运行多个task。
为了直观展示worker 、executor 和task 三者之间的关系,其结构图如下:
备注:可以调用TopologyBuilder类的setSpout和setBolt来设置并行度(也就是有多少个task)
三、Storm 的安装部署
步骤一 zookeeper 的安装配置,请参考:http://blog.csdn.net/u010330043/article/details/51209939
步骤二 上传storm的安装包,解压
步骤三 修改配置文件storm.yaml
//所使用的zookeeper集群主机
storm.zookeeper.servers:
- "cs0"
- "cs1"
- "cs2"
//nimbus所在的主机名
nimbus.host: "cs0"
//supervisor.slots.ports表示supervisor节点的槽数,就是最多能跑几个worker进程
supervisor.slots.ports
-6701
-6702
-6703
-6704
-6705
步骤四 启动zkServer nimbus,supervisor和ui几个服务
//启动zkServer
zkServer.sh start
zkServer.sh status #查看zkserver是否成功启动
//在nimbus主机上,启动nimbus和ui
nohup ./storm nimbus&
nohup ./storm ui&
//在supervisor主机上启动supervisor
nohup ./storm supervisor&