storm笔记.docx
- 文档编号:2479569
- 上传时间:2022-10-30
- 格式:DOCX
- 页数:16
- 大小:411.45KB
storm笔记.docx
《storm笔记.docx》由会员分享,可在线阅读,更多相关《storm笔记.docx(16页珍藏版)》请在冰豆网上搜索。
storm笔记
Storm学习报告框架
目录
一、Storm产生的需求背景3
二、Storm组件及架构3
2.1Storm架构3
2.2Storm组件概念5
三、Storm的功能设计5
3.1StreamGrouping策略5
3.2保证数据不丢失6
3.2.1可靠性API7
3.2.2实现高效率可靠性8
3.3DRPC10
3.4事务性拓扑11
3.4.1API12
3.4.2事务机制原理分析12
3.5使用非java语言15
四、Storm的应用16
4.1阿里巴巴的Storm应用17
4.2智能交通17
4.3传染病预测17
4.4货物运输17
4.5中兴通讯“环宁护城河”系统17
4.6防灾预测系统18
五、总结18
1、Storm产生的需求背景
过去十几年里,对数据的处理主要使用MapReduce式的相关技术对海量数据离线处理,然而大规模实时数据处理已经越来越成为一种业务需求,特别是随着互联网的进一步发展,对实时分析、实时反馈、实时监控等交互需求日益强烈。
在Storm出现之前,你可能需要自己手动维护一个由消息队列和消息处理者所组成的实时处理网络,消息处理者从消息队列取出一个消息进行处理,更新数据库,发送消息给其它队列,但这样做有诸如代码不够健壮,伸缩性差等缺点。
Storm定义了实时计算的原语。
如同hadoop大大简化了并行批量数据处理,storm的这些原语大大简化了并行实时数据处理。
Storm的一些关键特性如图1.1所示。
图1.1Storm关键特性
2、Storm组件及架构
2.1Storm架构
storm的集群表面上看和hadoop的集群非常像,都是Master/Slaver结构。
但是在Hadoop上面你运行的是MapReduce的Job,而在Storm上面你运行的是Topology。
它们是非常不一样的,图2.1显示Storm的结构图和图2.2的Hadoop架构图。
图2.1Storm架构图
由图可知,Storm的master是nimbus,Slaver是supervisor,主从节点之间依靠Zookeeper连接协调。
图2.2Hadoop架构图
从图中看出,Hadoop的结构主要分为mapreduce计算框架和HDFS储存框架,主节点是上面有JobTraker和NameNode,从节点是TaskTracker和DataNode。
通过对比Storm与Hadoop的组件来了解Storm组件的功能,如表2.1。
首先我们通过一个storm和hadoop的对比来了解storm中的基本概念。
表2.1Storm与Hadoop各组件对比
Hadoop
Storm
系统角色
JobTracker
Nimbus
TaskTracker
Supervisor
Child
Worker
应用名称
Job
Topology
组件接口
Mapper/Reducer
Spout/Bolt
2.2Storm组件概念
Storm的组件主要有Nimbus、Supervisor、Worker、Task、Spout、Bolt,各项功能如表2.2所示。
表2.2Storm组件功能
组件名
功能作用
Nimbus
负责集群分发代码,为每个节点指派任务和监控失败任务。
Supervisor
负责接受nimbus分配的任务,启动和停止属于自己管理的worker进程。
Worker
运行具体处理组件逻辑的进程。
Task
worker中每一个spout/bolt的线程称为一个task.在storm0.8之后,task不再与物理线程对应,同一个spout/bolt的task可能会共享一个物理线程,该线程称为executor。
Spout
负责从数据源发送数据到bolt。
Bolt
负责接收并处理Spout或Bolt发送的数据,把数据发送到下一个Bolt。
3、Storm的功能设计
3.1StreamGrouping策略
流分组策略告诉topology如何在两个组件之间发送tuple。
spouts和bolts以很多task的形式在topology里面同步执行。
如果从task的粒度来看一个运行的topology,它应该如图3.1所示。
图3.1数据流的过程
Storm的各种Grouping方式如表3.1所示。
表3.1各类Grouping方式及功能
域分组方式
具体功能
Shufflegrouping
一个源组件,发射tuple到随机选择的bolt并确保每个bolt收到等量元组。
Fieldgrouping
按字段分组,保证相同id值的tuple被发送到相同的task,不同id值的发送到不同的task。
Allgrouping
广播发送,所有bolt的tasks会收到每一个tuple,例如在刷新缓存的时候使用,可以向所有bolt发送一个刷新缓存的信号。
Directgrouping
比较特殊,消息发送者决定消息接收者的哪一个Task处理这个消息。
只要消息流被申明为DirectStreaming就可以使用该方法。
Globalgrouping
所有源实例产生的tuple被分配到一个单独目标实例id值最小的那个task中。
Nonegrouping
一般来说类似shufflegrouping,不同的是storm会把bolt放到他的订阅者同一个线程里面。
3.2保证数据不丢失
在storm里面一个tuple被完全处理的意思是:
这个tuple以及由这个tuple所导致的所有的tuple都被成功处理。
而一个tuple会被认为处理失败了如果这个消息在timeout所指定的时间内没有成功处理。
而这个timetout可以通过Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS来指定。
首先storm通过调用spout的nextTuple方法来获取下一个tuple,Spout通过open方法参数里面提供的SpoutOutputCollector来发射新tuple到它的其中一个输出消息流,发射tuple的时候spout会提供一个message-id,后面我们通过这个message-id来追踪这个tuple。
这个发射的tuple被传送到消息处理者bolt那里,storm会跟踪由此所产生的这棵tuple树。
如果storm检测到一个tuple被完全处理了,那么storm会以最开始的那个message-id作为参数去调用消息源的ack方法;反之storm会调用spout的fail方法。
值得注意的是,storm调用ack或者fail的task始终是产生这个tuple的那个task。
所以如果一个spout被分成很多个task来执行,消息执行的成功失败与否始终会通知最开始发出tuple的那个task。
3.2.1可靠性API
作为storm的使用者,有两件事情要做以更好的利用storm的可靠性特征。
第一,在你生成一个新的tuple的时候要通知storm;第二,完成处理一个tuple之后要通知storm。
这样storm就可以检测整个tuple树有没有完成处理,并且通知源spout处理结果。
storm提供了一些简洁的api来做这些事情。
由一个tuple产生一个新的tuple称为:
anchoring。
你发射一个新tuple的同时也就完成了一次anchoring。
如下代码体现了anchoring功能。
publicvoidexecute(Tupletuple){
Stringsentence=tuple.getString(0);
for(Stringword:
sentence.split("")){
_collector.emit(tuple,newValues(word));
}
_collector.ack(tuple);
}
emit的第一个参数是输入tuple,第二个参数则是输出tuple,这其实就是通过输入tupleanchoring了一个新的输出tuple。
因为这个“单词tuple”被anchoring在“句子tuple”一起,如果其中一个单词处理出错,那么这整个句子会被重新处理。
一个输出tuple可以被anchoring到多个输入tuple。
这种方式在stream合并或者stream聚合的时候很有用。
一个多入口tuple处理失败的话,那么它对应的所有输入tuple都要重新执行。
List
anchors.add(tuple1);
anchors.add(tuple2);
_collector.emit(anchors,newValues(1,2,3));
最后一件要做的事情是在你处理完当个tuple的时候告诉storm,通过OutputCollector类的ack和fail方法来做。
因为每个你处理的tuple,必须被ack或者fail。
因为storm追踪每个tuple要占用内存。
所以如果你不ack/fail每一个tuple,那么最终你会看到OutOfMemory错误。
大多数Bolt遵循这样的规律:
读取一个tuple;发射一些新的tuple;在execute的结束的时候ack这个tuple。
这些Bolt往往是一些过滤器或者简单函数。
Storm为这类规律封装了一个BasicBolt类。
如果用BasicBolt来做,则在execute()方法结束后可以自动ack()。
3.2.2实现高效率可靠性
storm里面有一类特殊的task称为:
acker,他们负责跟踪spout发出的每一个tuple的tuple树。
当acker发现一个tuple树已经处理完成了。
它会发送一个消息给产生这个tuple的那个task。
你可以通Config.TOPOLOGY_ACKERS来设置一个topology里面的acker的数量,默认值是1。
如果你的topology里面的tuple比较多的话,那么把acker的数量设置多一点,效率会高一点。
理解storm的可靠性的最好的方法是来看看tuple和tuple树的生命周期,当一个tuple被创建,不管是spout还是bolt创建的,它会被赋予一个64位的id,而acker就是利用这个id去跟踪所有的tuple的。
每个tuple知道它的祖宗的id(从spout发出来的那个tuple的id),每当你新发射一个tuple,它的祖宗id都会传给这个新的tuple。
所以当一个tuple被ack的时候,它会发一个消息给acker,告诉它这个tuple树发生了怎么样的变化。
具体来说就是:
它告诉acker:
我呢已经完成了,我有这些儿子tuple,你跟踪一下他们吧。
下面这个图3.2演示了C被ack了之后,这个tuple树所发生的变化。
图3.2tupleC被ack()之后的变化
当topology里面有多个acker。
而这又给我们带来一个问题,当一个tuple需要ack的时候,它到底选择哪个acker来发送这个信息呢?
storm使用一致性哈希来把一个spout-tuple-id对应到acker,因为每一个tuple知道它所有的祖宗的tuple-id,所以它自然可以算出要通知哪个acker来ack。
(这里所有的祖宗是指这个tuple所对应的所有的根tuple。
这里注意因为一个tuple可能存在于多个tuple树,所以才有所有一说)。
storm的另一个细节是acker是怎么知道每一个spoutt
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- storm 笔记