Storm学习----ACK机制

Storm通过ACK机制确保无数据丢失,跟踪每个数据的处理情况。Acker任务跟踪Spout发出的每个tuple及其子tuple,成功处理后发送ACK,超时则调用fail。在实现上,Storm为消息分配随机ID,Spout和Bolt处理后通知Acker,Acker通过异或检查消息是否完成处理。当组件挂掉时,Storm有超时重试机制保证容错性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于Storm,有一个相对比较重要的概念就是 "Guarantee no data loss" -- 可靠性

很明显,要做到这个特性,必须要tracker 每一个data的去向和结果,Storm是如何做到的?

那就是我们接下来要说的 Acker 机制,先概括下Acker所参与的工作流程

1 Spout 创建一个新的Tuple时候,会发射一个消息通知acker去跟踪;

2 Bolt 在处理Tuple成功或者失败的时候,也会发送一个消息通知Acker

3 Acker会回调发射该Tuple的Spout其Ack ,fail方法

一个tuple被完全处理的意思是:

这个tuple以及由这个tuple后续所导致的所有tuple 都被成功的处理, 而一个tuple会被认为处理失败了,如果这个消息在timeout所指定的时间内没有成功处理。

也就是说对于任何一个Spout-tuple以及它的子孙,到底处理成功失败与否,我们都会得到通知。

由一个tuple产生一个新的tuple称为:anchoring,你发射一个tuple的同时也就完成了一次anchoring。

Storm 里面有一类特殊的task称为:acker,请注意,Acker也是属于一种task,如果您对Task还不够熟悉,请参考另外的一篇文档:有关Storm-executor-task的关系,acker负责跟踪spout发出的每一个tuple的tuple树,当Acker发现一个tuple树已经处理完成了,它就会发送一个消息给产生这个tuple的task。

Acker task 组件来设置一个topology里面的acker的数量,默认值是一,如果你的topoogy里面的tuple比较多的话,那么请把acker的数量设置多一点,效率会更高一点。

理解Storm的可靠性的办法是看看 tuple,tuple树的生命周期,当一个tuple被创建,不管是Spout 和bolt 创建的,他被赋予一个位的ID,而acker就是利用这个ID 去跟踪所有的tuple的。每一个tuple知他祖宗的iD,吐过Stomr检测到一个tuple被完全处理了,那么Storm会以最开始的那个message-id 作为参数去调用消息源头的ACK方法,反之Storm会调用Spout的fail方法。

值得注意的一点是Storm调用Ack或者fail的task始终是产生这个tuple的那个task,所以如果一个Spout,被分为很多个task来执行,消息执行的成功失败与否始终会通知最开始发出tuple的那个task。

作为Storm的使用者,有两件事情要做以更好的利用Storm的可靠性特征,首先你在生成一个tuple的时候要通知Storm,其次,完全处理一个tuple之后要通知Storm,这样Storm就可以检测到整个tuple树有没有完成处理,并且通知源Spout处理结果。

1 由于对应的task挂掉了,一个tuple没有被Ack:

Storm的超时机制在超时之后会把这个tuple标记为失败,从而可以重新处理。

2 Acker挂掉了: 在这种情况下,由这个Acker所跟踪的所有spout tuple都会出现超时,也会被重新的处理。

3 Spout 挂掉了:在这种情况下给Spout发送消息的消息源负责重新发送这些消息。

三个基本的机制,保证了Storm的完全分布式,可伸缩的并且高度容错的。

============================

对于Storm的Ack机制 在源码实现上进行一些补充。

1: 在Ack框架的设计之中,Storm发射出去的消息都会对应于一个随机的消息ID号。

2 : Spout发射消息之后。将像Acker Bolt发射一个消息,这个消息的内容为 《RootID,消息ID》 Acker Bolt将会为该消息创建一条跟踪项。

3: Bolt产生要发射的消息的过程之中,也会将该消息ID发射到Acker Bolt,AckerBolt 对消息ID进行异或以后进行存储。

4:Acker Bolt 在更新某一个消息的跟踪值时,若发现他的值变为0,那么就会像Spout节点发射消息,表明Spout发射的这条消息已经被成功的处理 。

5:所有消息的消息ID 都将更新到Spout发射出去的根消息上,Bolt新产生的消息并不会被单独跟踪。

6:如果你在发射的过程之中,没有指定用于消息跟踪的ID,那么系统就不对消息进行跟踪,若系统中不含有Ack bolt,消息也不会被跟踪。

7: Spout的每条消息以及该消息所演化出来的消息的跟踪 容量负载为:16个字节:8个字节的根消息ID,以及8个字节的消息跟踪值AckValue。 事实上,由于Storm中采用的是HashMap对其进行的跟踪,在32位的JVM之中,每条消息至少需要20个字节的额外负载,故有一条消息的跟踪需要 40个左右的负载。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值