Storm计算模型

来源:互联网 发布:淘宝注册页面表单代码 编辑:程序博客网 时间:2024/05/19 13:58
DAG计算模型,一个阶段接另一个阶段再接另一个阶段,在这个有向无环图里面可以灵活的组合,DAG是由Spout和bolt组合起来的,它们都是节点,是stream数据流,数据流里面的数据单元就是Tuple。

Storm里面关键的组件,有nimbus/supervisor/worker/executor,另外storm还用到了外围的组件zookeeper来存储协调数据。

在Storm中最重要的就是topology,topology就是对于DAG模型的一个实现。

采用DAG的好处,这就是第一,DAG有很多个阶段,可以进行灵活的装配,比如这里的bolt可以在这个应用被用到,也可以在另外的应用里面被用到。另外一个好处就是,它能把数据真正的流起来,还是和hadoop的mapreduce对比,如果跑4个阶段,那就需要4个mapreduce任务,每一个阶段都得等上一个阶段结束,而流式处理4个阶段就可以同时处理。吞吐量的增加。一分钟处理一个,而mapreduce4分钟处理一个。而且整个DAG这个图是在内存里面的一个图,Spout和bolt都是在内存里面进行计算的,不会写入磁盘的,所以是非常高效的在运转。

Tuple
–get[i]
–getString[i]
–getString["name"]
–Tuple的ID对于Storm的可靠性是非常有用的
Stream
–每一个Stream都有一个ID,如果没有指定写ID就用的是默认的流,叫default,每个Spout/Bolt都有一个默认的Stream:default
–一个stream中的Tuple有固定的schema
–每个spout/bolt都有一个默认的stream:default
–spout/bolt可以有多个流

Spout
其实它就是产生Tuple的源头,一般从外部数据源如kafka拉取数据,生成tuple,一般我们使用已有的spout已经足够了,一般你要是想写一个spout,先去看看Storm现在是不是已经有了,拿来用就可以了,像KafkaSpout,DRPCSpout,RedisSpout。
Spout它是产生Tuple的源头,Spout它有核心地方就是有个nextTuple()的函数,每个线程不断调这个回调函数,Spout主动去kafka取数据,然后再用emit方法生成一个Tuple给后面的bolt进行处理,这里用主动这个词是,因为数据不能打给storm,因为storm没有地方去接这个数据,storm是主动拉来数据的系统,数据放在消息队列kafka或者Storm自带的DRPC Server中,都是这个概念。

Storm不用做持久化数据的缓存了,试想一下如果外部的数据是发给storm的话,storm就必须保证数据的可靠性,就必须做一些持久化的操作,因为外部数据发出去之后,可能外部数据认为OK已经发出去了,可能就删掉了。如果是拉数据的话就不需要做这部分工作,这部分工作典型就是消息队列来做。
如果去取数据的时候,我就能决定什么时候去取和什么时候不取,也就是可以做流控,当压力比较大的时候,我就可以不取,当我能够处理的时候,我就再取,这样就可以很好的进行流控,Spout不是可以产生Tuple吗?有个策略就是有个参数可以设置,一个Spout最多有多少Tuple在外面进行处理,如果这个参数设置为80,比如Spout产生有100Tuple,20个已经处理完了,80个正在处理。那么20个已经处理完了,就可以再去取下一个,然后生成一个Tuple,这时如果第21个还没有处理完的话,那我就等着,不再去取数据和发Tuple。

Storm内部会跟踪Tuple的执行来确保可靠性,譬如Tuple在一定时间内,时间是可配置的,完成了bolt1和bolt2两个动作,那么会调用Spout的ACK告诉说执行完毕,否则会调用fail方法表示没在规定时间内完成,最终是否重新发送或丢弃由用户决定,可以选择使得这个机制非常灵活。

真正去处理数据的东西,处理Tuple的核心,做的事情其实很简单,从输入流里面得到tuple,经过转换输出tuple,一般核心业务逻辑就是实现bolt的逻辑,默认是JAVA的实现,当然其他语言也可以。
实现Bolt中最核心的又是实现一个execute回调函数,里面的参数,就是新来的数据Tuple,bolt是数据驱动的,当数据来了就处理。

当数据来的时候,从Tuple中拿到想要的字段,当然你是可以知道数据是从这个流里来的,还是从另外一个流里来的,当然可以做判断,然后bolt去处理,然后后面再产生新的tuple,讲到这里我们看到storm设计是多么的优雅,写分布式程序就像写单机程序一样简单,主要就是开发bolt,当然这里需要注意的是storm程序中bolt尽量要是独立的,就像UNIX中cat grep wcsort,尽量模块化,bolt就可以后面给其他的topology去使用了。

Grouping

Grouping它是一个路由的策略,这个策略就做一件事,它决定一个Tuple发给下游某个bolt中n个并发中的哪一个Task,告诉topology如何在两个组件之间发送tuple,定义一个topology的其中一步是定义每个bolt接收什么样的流作为输入。stream grouping就是用来定义一个stream应该如果分配数据给bolts上面的多个tasks。


Storm里面有7种类型的stream grouping,也可以通过实现CustomStreamGrouping接口来实现自定义流分组
1. Shuffle Grouping随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同。
2. Fields Grouping按字段分组,比如,按"user-id"这个字段来分组,那么具有同样"user-id"的tuple 会被分到相同的Bolt里的一个task,而不同的"user-id"则可能会被分配到不同的task。
3. All Grouping广播发送,对于每一个tuple,所有的bolts都会收到
4. Global Grouping全局分组,整个stream被分配到storm中的一个bolt的其中一个task。再具体一点就是分配给id值最低的那个task。

5. None Grouping不分组,这个分组的意思是说stream不关心到底怎样分组。目前这种分组和Shuffle grouping是一样的效果,有一点不同的是storm会把使用none grouping的这个bolt放到这个bolt的订阅者同一个线程里面去执行(如果可能的话)。
6. Direct Grouping指向型分组,这是一种比较特别的分组方法,用这种分组意味着消息(tuple)的发送者指定由消息接收者的哪个task处理这个消息。只有被声明为Direct Stream 的消息流可以声明这种分组方法。而且这种消息tuple必须使用emitDirect方法来发射。消息处理者可以通过TopologyContext来获取处理它的消息的task的id (OutputCollector.emit方法也会返回task的id)。
7. Local or shuffle grouping本地或随机分组。如果目标bolt有一个或者多个task与源bolt的task在同一个工作进程中,tuple将会被随机发送给这些同进程中的tasks。否则,和普通的Shuffle Grouping行为一致。


shuffleGrouping,当然最简单就是随机乱发了,当然就是有一个随机发的策略,shuffleGrouping。其实叫randomGrouping更好一点,因为容易和mapreduce里面那个shuffle混起来,因为那个shuffle是默认按hash做分组的。这里的Grouping就有点像mapreduce里面的partition,mapreduce那个是到下游的哪个reduce里面去,storm这个是到下游的哪个bolt里面去。shuffleGrouping随机发,好比这里50条,这里50条,负载均衡的,这样两个都能发挥出作用。
当然某种情况下随机发是不行的,比如说我要按照某一种key,比如我要做wordcount的时候,就必须把同样key单词的发到同一个上面去,否则统计就会不准对吧,那这事就没法干了对吧。fieldsGrouping,按某个字段或某些字段做hash。
•directGrouping,指定taskid,当然这个甚用,有特殊需要才干这个事情,指定的话就很不灵活了。
•allGrouping,上游的数据发给下游呢,就是相当于发给下游的所有,相当于广播。
•customGrouping,自定义,相当于mapreduce那里自己去实现一个partition一样,你只需要相对说0,1,2是哪个,它就会帮你去找到真正集群里面是哪个。


按照word这个field做hash,就会分配到12个并行的task中的某一个task里面去,这样就会保证每一个word都会跑到某一个task里面去,这样的话就保证了count是准确的,这里Fields是可以传多个String,就是根据多个字段做hash的。


当bolt下游没有接bolt的时候,数据就直接扔到了,上面就是wordcount的topology结构,其实是很经典的拓扑结构,这里灰色是后面下游没有bolt接那么为什么还要emit数据?这里就是一个比较好的习惯,这里count bolt可能已经存入数据库了,即使下游没有bolt,也把你的数据emit出去,以后如果要用到这个bolt的时候,譬如后面接一个topN的bolt的话,那个这个上游的emit就有用了,是不是,还是那句话,没有下游,也没有什么损失,有下游,你这个bolt就可以被很好的复用起来了。

原创粉丝点击