Transaction Topology

Storm transaction topology 

Storm 可以­­­保 证Tuple至少被处理一次,最常见的关于的Storm的问题是: 既然失败的Tuple可以被Replay, 那么它如何处理像计数统计这样的问题呢? 这样不会重复计数吗?在Storm0.7版本中提供的transaction Topology机制可以保证每个Tuple 精确的被处理一次。

本文主要阐述

  1. transaction Topology基本概念和原理
  2. 使用transaction Topology API
  3. Transaction Topology的实现

 transaction Topology基本概念和原理

下面我们一步一步介绍Transaction Topology怎么实现, 先从最简单的实现模型开始

Design 1

Transaction Topology 最核心的理念是:对处理的数据提供一个 Strong Ordering. 最基本的实现是一次只处理一个Tuple,直到目前处理的Tuple被Topology处理完毕才开始下一个.每个Tuple和一个Transaction Id 关联, 如果这个Tuple处理失败, 我们需要用同样的Transaction Id 去 Replay Tuple. 

下面看一个例子。

假设你想要对Steam里面的Tuples做全局计数。我们不仅仅需要在数据库中存储目前的计数值, 还需要记录最新的Transaction Id。 当你需要更新数据库中的计数值时,你首先要判断数据库中Transaction Id 和目前正在处理的Tuple的Transaction Id 是否一样, 如果一样说明这个Tuple已经在数据库中被统计过,不需要进行加1跳过这次更新。我们可是推断Tuple在成功更新数据库后返回成功消息给Storm的时候出错了。如果不一样,我们就可以安全的更新数据库的存储值了。

这样的设计我们可以保证全局统计的结果是准确的, 能保证exactly-once的语义,但是这种方法存在一个问题,由于每次只能处理一个Tuple,并且只有这一个Tuple处理成功之后才可以开始下一个导致数据处理的效率不高,从而不能充分利用Storm的高并发能力。

 Design 2

除了一次处理一个Tuple,一个更好的方法是每个Transaction 一次处理一批Tuple。在全局计数的例子中,我们可以用整个Batch 中Tuple的个数更新计数值。 如果批处理失败,我们应该relay整批Tuple。我们给每批Tuple分配一个 Transaction Id,这种批处理也是strong ordering的。



如果我们每批处理1000个tuple, 那么和每次只处理一个tuple相比,我们的应用将要减少1000X的数据库操作。另外,由于批量计算可以并行化,我们可以充分利用Strom的高并发特性。虽然这种方法效率比每次只处理一个Tuple的效率高,但是它也没用尽可能充分的使用资源。整个Topology的worker大部分处于等待其他部分完成的闲置状态。例如,在一个这样的Topology中, 在bolt1 完成他的处理任务后 一直处于闲置状态直到bolt2,bolt3, bolt4完成并且Spout排出下批tuples。

 

 





Design 3

我们知道不是批量处理任务的所有工作都需要Strong Ordering ,比如当我们的全局计数的例子中,可以拆分为两部分的计算工作,一是计算批量Tuple的计数, 二是更新数据库的全局计数。第二部分工作在批量Tuple之间是需要StrongOrdering的,但是第一部分工作在批量tuple之间是可以并行计算的,因此在批量1进行更新数据库的同时,批量2至批量10可以进行第一部分工作,最大限度地利用空闲的资源。

Storm就是按照这个方法把一个批量的计算分为2个阶段

第一个阶段是processing处理阶段: 这个阶段允许多个批量任务可以同时并行计算。

第二个阶段是commit提交阶段:这个阶段是对多个批量处理任务是StrongOrdering的。直到批量任务1的Commit提交阶段成功处理完毕,批量处理任务2的提交阶段才开始执行

这两个阶段合在一起成为“事务”。很多批量任务能并行处理在第一处理阶段,但是只有一个批量任务执行在第二个提交阶段。如果一个批量任务在处理阶段或者提交阶段发生了错误,整个事务过程需要Replay(两个阶段都需要Replay)。

使用transaction Topology API

详细设计

当使用Transaction Topology 的时候, Storm为我们提供了以下:

1 状态管理: Storm把所有TransactionTopology的状态信息存储在Zookeeper中,包括目前的transactionId, 每个Batch定义的参数的Metadata信息。

2 协调多个Transaction: Storm 管理了所有决定哪些Transactions应该被处理 和 什么时候提交的必要的信息

3 错误发现: Storm 借助 Acking框架高效的判断什么时候Batch被成功的处理,什么时候成功的被提交和失败。Storm会适当的自动的Replay失败的Transaction,我们不必自己Ack,Storm帮我们管理这些。

4 一流Batch处理API:在常规的Bolts的基础上抽象出一个API来支持批量的Tuple处理, Storm管理了所有的状态来判断哪个Transcation已经收到所有Batch中的Tuple。Storm也负责清理每个Transaction累积的状态信息。

最后需要说明的是Transaction Topology需要一个数据源队列来支持,以便能够Replay一个确切的Batch。Kestrel不支持这样,但是ApacheKafka完美的适合这类Spout,Storm-Kafka包含了一个KafkaTransaction Spout 的实现

实例解析
以下是一个用Transaction Topology 进行全局计数的Topology的定义:
    MemoryTransactionalSpout spout = new MemoryTransactionalSpout(DATA, new Fields("word"), PARTITION_TAKE_PER_BATCH);
    TransactionalTopologyBuilder builder = new TransactionalTopologyBuilder("global-count", "spout", spout, 3);
    builder.setBolt("partial-count", new BatchCount(), 5).noneGrouping("spout");
    builder.setBolt("sum", new UpdateGlobalCount()).globalGrouping("partial-count");


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值