Storm的重要概念
Storm中一些重要的概念:
Spout(消息源)
Bolt(消息处理者)
Stream grouping(数据的分发方式)
Topology(拓扑)
Worker(工作进程)
Task(执行具体逻辑的任务)
Executor(执行Task的线程)
Configuration(配置)
Storm的重要概念
物理模型:
Storm的重要概念
worker进程:
Storm的重要概念
一,计算拓扑:Topology
一个实时计算应用程序的逻辑在storm里面被封装到Topology对象里面,我们把它叫做计算拓补。Storm里面的Topology相当于Hadoop里面的MapReduce Job,
它们的关键区别是:一个MapReduce Job最终总是会结束的,而一个Storm的Topoloy会一直运行,除非你显式的杀死它。
一个Topology是Spouts和Bolts组成的图状结构,而连接Spouts和Bolts的则是Stream groupings。
二,消息源: Spout
消息源Spouts是Storm里面一个topology里面的消息生产者。一般来说消息源会从一个外部源读取数据并且向topology里面发出消息: tuple。
消息源Spouts可以是可靠的也可以是不可靠的。一个可靠的消息源可以重新发射一个tuple当这个tuple没有被storm成功的处理,
但是一个不可靠的消息源Spouts一旦发出一个tuple就把它彻底忘了,也就不可能再发了。
消息源Spouts可以发射多条消息流stream。要达到这样的效果,使用OutFieldsDeclarer.declareStream来定义多个stream, 然后使用SpoutOutputCollector来发射指定的sream。
三,消息处理者: Bolt
所有的消息处理逻辑被封装在bolts里面。 Bolts可以做很多事情:过滤, 聚合, 查询数据库等等。
Bolts的主要方法是execute, 它以一个tuple作为输入,Bolts使用OutputCollector来发射tuple, Bolts必须要为它处理的每一个tuple调用OutputCollector的ack方法,以通知storm这个tuple被处理完成了。从而我们通知这个tuple的发射者Spouts。 一般的流程是: Bolts处理一个输入tuple, 发射0个或者多个tuple, 然后调用ack通知storm自己已经处理过这个tuple了。storm提供了一个IBasicBolt会自动调用ack。
四,Worker
Supervisor会监听分配给它那台机器的工作,根据需要启动/关闭工作进程,这个工作进程就是worker
每一个worker都会占用工作节点的一个端口,这个端口可以在storm.yarm中配置。
一个topology可能会在一个或者多个工作进程里面执行,每个工作进程执行整个topology的一部分,所以一个运行的topology由运行在很多机器上的很多工作进程组成。
五,Task:任务
每一个Spout和Bolt会被当作很多task在整个集群里面执行。默认情况下每一个task对应到一个线程(Executor),这个线程用来执行这个task,而stream grouping则是定义怎么从一堆task发射tuple到另外一堆task。
六,配置Configuration
storm里面有一堆参数可以配置来调整nimbus, supervisor以及正在运行的topology的行为, 一些配置是系统级别的, 一些配置是topology级别的。所有有默认值的配置的默认配置是配置在default.xml里面的。你可以通过定义个storm.xml在你的classpath厘米来覆盖这些默认配置。并且你也可以在代码里面设置一些topology相关的配置信息 – 使用StormSubmitter。当然,这些配置的优先级是: default.xml < storm.xml < TOPOLOGY-SPECIFIC配置。
七,消息流:Stream
消息流是storm里面的最关键的抽象。一个消息流是一个没有边界的tuple序列, 而这些tuples会被以一种分布式的方式并行地创建和处理。 对消息流的定义主要是对消息流里面的tuple的定义, 我们会给tuple里的每个字段一个名字。 并且不同tuple的对应字段的类型必须一样。 也就是说: 两个tuple的第一个字段的类型必须一样, 第二个字段的类型必须一样, 但是第一个字段和第二个字段可以有不同的类型。 在默认的情况下, tuple的字段类型可以是: integer, long, short, byte, string, double, float, boolean和byte array。 你还可以自定义类型 — 只要你实现对应的序列化器。
八,消息分发策略:Stream groupings
Shuffle Grouping:随机分组,随机派发stream里面的tuple,保证每个bolt接收到的tuple数目相同。
Fields Grouping:按字段分组,比如按userid来分组,具有同样userid的tuple会被分到相同的Bolts,而不同的userid则会被分配到不同的Bolts。做wordcount场景的时候就必须使用这种分组策略。
All Grouping:广播发送,对于每一个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来获取处理它的消息的taskid (OutputCollector.emit方法也会返回taskid)
Local or shuffle grouping:如果目标bolt有一个或者多个task在同一个工作进程中,tuple将会被随机发生给这些tasks。否则,和普通的Shuffle Grouping行为一致。