storm批处理事物原理

对于容错机制,storm通过一个系统级别的组件acker,结合xor校验机制判断一个tuple是否发送成功,进而spout可以重发该tuple,保证一个tuple在出错的情况下至少被重发一次。

但是在需要精确统计tuple的数量如销售额场景时,希望每个tuple被且仅被处理一次,storm 0.7.0引入了transactional topology,它保证每个tuple被且仅被处理一次,这样我们就可以实现一种非常准确,且高度容错方式来实现计数类应用。

逐个处理单个tuple,增加很多开销,如写库,输出结果频率过高

事物处理单个tuple效率比较低,因此storm中引入了batch处理。

事物可确保该批次要么全部处理成功,如果有处理失败的则全部不计,storm会对失败的批次重新发送,且确保每个batch有且仅被处理一次。


事物机制原理:

对于只处理一次的需要,从原理上来讲,需要在发送tuple的时候带上事物id:txid,在需要事物处理的时候,根据该txid是否以前已经处理成功来决定是否进行处理,当然需要把txid和处理结果一起做保存。并且需要保障顺序性,在当前请求txid提交之前,所有比自己低txid请求都已经提交。

在事物batch处理中,一批tuple赋予一个txid,为了提高batch之间处理的并行度,storm采用pipeline(管道)处理模型,这样多个事物可以并行执行,但是commit的是按严格顺序的。


storm事物处理中,把一个batch的计算分成两个阶段processing和commit阶段:

processing阶段:多个batch可以并行计算;

commiting阶段:batch之间强制按照顺序进行提交。


事物topo:

processing阶段:多个batch可以并行计算,比如说bolt2是普通的batchbolt(实现了IBatchBolt),那么多个batch在bolt2的task之间可以并行执行。

commiting阶段:batch之间强制按照顺序进行提交,比如bolt3实现IBatchBolt并且标记需要事物处理(实现了ICommitter接口,或者通过TransactionalTopologyBuilder的setCommitterBolt方法把BatchBolt添加到topology里面),那么storm认为可以提交batch的时候调用finishbatch,在finishBatch做txid的比较以及状态保存工作。


使用transactional topologles的时候,storm会为你做下面的事情:

管理状态:storm把所有实现transactional topologies所必须的状态保存在zookeeper里面,包括当前transaction id以及每个batch的一些元数据;

协调事务:storm帮你管理所有事情,如帮你决定在任何一个时间点是该processing还是该committing。

错误检测:storm利用acking框架来高效地检测什么时候一个batch被成功处理了,被成功提交了,或者失败了。Storm然后会相应地replay对应的batch。你不需要自己手动做任何acking或者anchoring(emit的时候发生的动作)。

内置的批处理api:storm在普通bolt之上包装了一层API来提供对tuple的批处理支持。storm管理所有的协调工作,包括决定什么时候一个bolt接收到一个特定transaction的所有tuple,storm同时也会自动清理每个transaction所产生的中间数据。


事物性的spout需要实现ITransactionalSpout,这个接口包含两个内部类接口类Coordinator和Emmiter。在topology运行的时候,事务性的spout内部包含一个子topology。

这里面有两种类型的tuple,一种是事务性的tuple,一种是batch中的tuple;

coordinator开启一个事务准备发射一个batch时候,进入一个事务的processing阶段,会发射一个事务性tuple(transactionAttempt & metadata)到“batch emit”流

emitter以all grouping(广播)的方式订阅coordinator的“batch emit”流,负责为每个batch实际发射tuple,发送的tuple都必须以transactionAttempt作为第一个field,storm根据这个field来判断tuple属于哪一个batch。

coordinator只有一个,emmitter根据并行度可以有多个实例


transactionAttempt包含两个值:一个transaction id,一个attempt id。

transaction id的作用就是我们上面说的对每个batch中的tuple是唯一的,而不管这个batch replay多少次都是一样的。

attemp id是对于每个batch唯一的一个id,但对于同一个batch,它replay之后的attempt id和replay之前的就不一样了。

我们可以把attempt id理解成replay-times,storm利用这个id来区别一个batch发送的tuple的不同版本。


metadata(元数据)中包含当前事务可以从哪个point进行重放数据,存放到zookeeper中的,spout可以通过Kryo从zookeeper中序列化和反序列化该元数据


事务bolt:

BaseTransactionalBolt

处理batch在一起的tuples,对于每一个tuple调用execute方法,而整个batch处理(processing)完成的时候调用finishBatch方法。如果BatchBolt被标记成committer,则只能在commit阶段调用finishBatch方法。一个batch的commit阶段由storm保证只在前一个batch成功提交之后才会执行。并且它会重试直到topology里面的所有bolt在commit完成提交。那么如何直到batch的processing完成了,也就是bolt是否接受处理了batch里面所有的tuple:在bolt内部,有一个CoordinatedBolt的模型。


CoordinateBolt:

每个CoordinateBolt记录两个值:有哪些task给我发送了tuple(根据topology的grouping信息);我给哪些task发送信息(同样根据grouping信息)。

等所有的tuple都发送完成之后,coordinatorBolt通过另外一个特殊的stream以emitDirect的方式告诉所有它发送过tuple的task,它发送了多少tuple给这个task。下游task会将这个数字和自己已经接收到的tuple数量做对比,如果相等,则说明处理完了所有的tuple。

下游CoordinateBolt会重复上面的步骤,通知其下游。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值