banq
2013-08-29 08:44

在一个流系统中,事件流通过串联的处理器,直至最终结果产生,每个输入事件产生一系列图谱式派生的子事件,为了确保可靠性,有必要在失败时确保整个图谱中事件全部被成功处理,然后才能重新启动处理。

下面是Twitter的 Storm如何跟踪事件的过程处理:

1.所有从源点,也就是处理图中第一个数据节点出发的事件,都有一个随机ID,对于每个源点,框架将维护一对数据[event ID -> signature], 对于每个初始事件,signature签名是由event ID初始的.

2.下游节点基于接受到的初始事件可能产生更多事件,每个事件都带有初始事件的那个随机 ID

3. 如果事件被下一个节点成功接受和处理,这个节点将更新相应初始事件的签名,通过异或操作,将输入事件的ID和所有基于该输入事件产生的所有事件的ID进行异或操作,如下图,事件 01111 产生子事件 01100, 10010, 和 00010, 这样事件 01111的签名是11100 (= 01111 (initial value) xor 01111 xor 01100 xor 10010 xor 00010).

4.一个事件可能基于一个或多个输入事件产生的,因此它带有几个初始化事件信息,带有多个初始化事件的ID.

5.只要签名将变成0,事件成功被处理,当图谱中最后一个节点事件被成功处理,也就是再也没有事件发往下游, 框架自己将发出一个commit信息到源点。图中三部分

6.框架将定期遍历初始事件的表,寻找旧的未被commit的事件(也就是签名不为0的事件),这些事件被认为是失败的,框架请求源点再重新播放处理它们。

7.注意的是签名的更新顺序并不是很重要,因为XOR异或操作本身的可替代性。....

8. 上面的算法并不是严格的可靠,当签名可能因为不幸的ID结合突然变为0,64位的ID足够降低这种错误的发生...

待续..


banq
2013-08-30 07:48
前面使用事件签名的方式是简单的,因为它是去除中心化,节点独立地发出确认信息,没有中央节点跟踪所有的来龙去脉,但是对于sliding windows滑动窗或其他类型的缓存,这种方式很难管理事务处理,每一个滑动窗片刻就有成百上千个事件,这是很难于管理是否完成确认的,因为很多事件可能还处于未确认状态,或者在持久保存中间状态,量太大了。

替代方案是 Apache Spark. 它认为最后的状态作为一个输入数据的函数,为了简化来路跟踪, 该框架以批次处理事件,这样结果就是批次的顺序,结果批次能被并行计算,如果计算失败,框架也只是简单返回它。


框架将两个流合并到一个滑动窗,结果经过更多处理阶段,框架认为输入流不是一个流,而是一系列批次,每个批次有一个ID,框架能够根据ID任何时刻获得它,这样流处理被一串串事务替代,每个事务都带有一组输入批次,用处理函数改变他们,然后持久一个结果。图中这样一个事务是用红色表达,如果事务失败,框架只是简单返回,关键是事务能够并行被执行。

这种简单而强大范式激活了中央式事务管理机制,提供一次消息处理的语义,既可以用于批处理也可适合流处理,因为它将数据看成一系列批次,而不考虑他们自然静态的流特性。

banq
2013-08-30 11:39
之前使用事件的签名来实现来路跟踪,以此确保分布式系统的可靠性,但是有两个问题:

1.在大多数场合,一次处理语义(exactly-once processing semantics)是必须的,比如如果一些消息传送两次导致对事件计数的管道线产生不正确结果。

2.在管道线中的节点在消息被处理以后,其计算状态必须被更新,如果节点出错,这个状态就丢失,有必要持久化它或复制它。

Twitter的 Storm框架使用如下协议纠正这些问题:

1.事件被分组进入一个个批次,每个批次有一个事务ID.这个ID是线性呈数字增长(e.g. the first batch has ID 1, the second ID 2, and so on). 如果管道线处理一个批失败,这个批将用同样事务ID再次发送一次。

2.首先,框架向管道线中节点告示,一个新的事务将开始,然后,框架发出一个批通过管道线,最后,如果所有节点都确认它们的状态更新,框架就宣布这个事务完成了。

3.框架确保 commit phases跨事务是全局有序的。事务2 永远不会在事务1之前被确认提交committed 这种确保机制是按如下状态更新逻辑实现的:

最后一个事务 ID 将和状态一起持久化,如果框架用持久化到数据库的ID请求确认提交当前事务,状态才能被修改,数据库中的一个计数器将被增加,假设事务有一个很强的次序,那么更新将一批接着一批地更新。

如果当前事务ID等同于持久化到数据库的ID值,节点将忽视确认提交,因为该批在重放。节点之前肯定已经处理过该批,已经更新过状态,但是事务也许因为管道线什么地方错误而出错。

强提交确认的次序对于完成一次处理语义exactly-once processing semantics是重要的,严格的处理顺序并不可行,因为管道线中经常发生空闲等待下游处理完成,这种情况可以通过并行处理然后序列化提交确认的方式得到缓解,如下图:


bingyang
2013-08-30 13:37
好文,Storm 搭建起来比较麻烦,Bang 老师多传播下Storm相关的东西。呵呵

banq
2013-11-02 11:27
了解了这些实时流处理模式,再看看Storm内部原理就非常简单了:

Storm介绍

猜你喜欢