twitter storm源码走读之7 -- trident topology可靠性分析
欢迎转载,转载请注明出处,徽沪一郎。
本文详细分析TridentTopology的可靠性实现, TridentTopology通过transactional spout与transactional state相结合,能够做到tuple“只被处理一次,不多也不少”。也就是做到事务性处理exactly-once,要么成功,要么失败。
而一般的storm topology是无法保证eactly-once的处理的,它们要么是at-least-once(至少被处理一次,有可能被处理多次);要么是at-most-once(最多被处理一次,这样就存在遗漏的可能).
TridentTopology在设计中借鉴和保留了目前已经过期的transactional topology的设计思想。
Storm Topology的ack机制

在进行TridentTopology的可靠性分析之前,我们先回顾一下在storm topology中的ack机制。ack bolt是在提交到storm cluster中,由系统自动产生的,一般来说一个topology只有一个ack bolt(当然可以通过配置参数指定多个)。
当bolt处理并下发完tuple给下一跳的bolt时,会发送一个ack给ack bolt。ack bolt通过简单的异或原理(即同一个数与自己异或结果为零)来判定从spout发出的某一个bolt是否已经被完全处理完毕。如果结果为真,ack bolt发送消息给spout,spout中的ack函数被调用并执行。如果超时,则发送fail消息给spout,spout中的fail函数被调用并执行,spout中的ack和fail的处理逻辑由用户自行填写。
如在github上的kerstel spout就能做到只有当某一个tuple被成功处理之后,它才会从缓存中移除,否则继续放入到处理队列再次进行处理。
TridentTopology的可靠性机制

在“走读之6”一文中分析了一个tridenttopology是如何转换成storm topology的,我想用上面这幅图再次阐述一下转变后的结果。
- 一个tridenttopoloy会至少引入一个MasterBatchCoordinator,这个MBC就类似于storm topology中的spout
- newStream时使用的入参spout会裂变成两个bolt,一是TridentSpoutCoordinator,另一个是TridentSpoutExecutor
- 针对stream的各种操作则被分散到各个Bolt中,它们的执行上下文是TridentBoltExecutor
可以看出使用TridentTopology Api进行操作时,所有的东西其实都运行在bolt context中,而真正的spout是在调用TridentTopologyBuilder.buildTopology()的时候被添加的。
- MasterBatchCoordinator使用batch_stream发送一个类似于seeder tuple的东西给tridentspoutcoordinator,tridentspoutcoordinator将该信号继续下发给TridentSpoutExecutor, TridentSpout是如何一步步被调用到的呢。
- TridentBoltExecutor::execute
- TridentSpoutExecutor::execute
- BatchSpoutExecutor::execute
- ITridentSpout::emitBatch
- BatchSpoutExecutor::execute
- TridentSpoutExecutor::execute
- TridentBoltExecutor::execute
emitBatch是产生真正需要被处理的tuple的,这些tuple会被各个Operation所在的bolt所接收。它们的调用顺序是
- TridentBoltExecutor::execute
- SubtopologyBolt::execute
- InitialReceiver::receive
- TridentProcessor::execute
- InitialReceiver::receive
- SubtopologyBolt::execute
处理结束的判断依据
在TridentSpout中是如何判断所有的tuple都已经被处理的呢。
- 在每跳中认为自己处理完毕的时候,它都会告诉下一跳,即下游,我给你发送了多少tuple,如果下游将上游发送过来的确认消息与自身确实已经处理的消息比对一致的话,则认为处理都完成,于是发送ack.
- 问题的关键变成每一个bolt是如何判断自己已经处理完毕的呢,请看步骤3
- 总有一个bolt是没有上游的,即TridentSpoutExecutor,它只会收到启动指令,但不接收真正的业务数据,于是它会告诉下一跳,我发了多少tuple给你。
STREAM
在MasterBatchCoordinator中定义了三种不同的stream,这三种stream分别是
- BATCH_STREAM
- COMMIT_STREAM
- SUCCESS_STREAM
这些stream分别在什么时候被使用呢,下图给出一个大概的时序

简要说明:
- masterbatchcoordinator通过batch_stream发送seeder tuple给tridentspoutcoordinator
- tridentspoutcoordinator给tridentspoutexecutor继续传递该指令
- TridentSpoutExecutor在收到启动指令后,调用ITridentSpout接口的实现类进行emitBatch
- TridentSpoutExecutor在发送完一批batch后,finishBatch被调用,通过emitDirect会给下一跳通过coord_stream发送trackedinfo,即我已经发送了多少消息给你
- TridentSpoutExecutor紧接着还会给ack bolt发送ack消息,ack bolt将其传达到MasterBatchCoordinator
- MasterBatchCoordinator在收到第一个ack后,将状态置为processed
- 当MasterBatchCoordinator再次收到ack后,会将状态转为committing,同时通过commit_stream发送tuple给TridentSpoutExecutor
- 收到commit_stream上传来的tuple后,TridentSpoutExecutor会调用ITridentSpout中的emmitter, emmitter::commit()被执行,TridentSpoutExecutor会再次ack收到tuple
- MasterBatchCoordinator在收到这个tuple之后,会认为针对某一个seeder tuple的处理已经完全实现,于是通过SUCCESS_STREM告知TridentSpoutCoordinator,所有的活都已经都完成了,收工。
- 收到Success_stream上传来的信号后,ITridentSpout中的内嵌子类Emmit和Coordinator中相应的success方法会被调用执行。
注意:
- 为了描述方便,将TridentTopology进行了简化,认为其在转换成真正的storm topology时,只有一个TridentProcessor所在的bolt。真实的情况可能比这复杂,但消息的传递路径还是差不多的。
- 注意在TridentTopology中ack会被多次反复调用,这不同于普通的storm topology
状态机
在MasterBatchCoordinator中,针对每一个seeder tuple,其状态机如下图所示。注意这些状态是会被保存到zookeeper server中的,使用的api定义在TransactionalState中。

总结
通过上面的分析可以看出,TridentTopology实现了一个比较好的框架,但真正要做到exactly-once的处理,还需要用户自己去实现ITridentSpout中的两个重要内嵌类,Emmitter和Coordinator。
具体如何实现该接口,可以查看storm-core/src/jvm/storm/trident/testing目录下的FixedBatchSpout.java和FeederCommitterBatchSpout.java
twitter storm源码走读之7 -- trident topology可靠性分析的更多相关文章
- twitter storm源码走读之6 -- Trident Topology执行过程分析
欢迎转载,转载请注明出处,徽沪一郎. TridentTopology是storm提供的高层使用接口,常见的一些SQL中的操作在tridenttopology提供的api中都有类似的影射.关于Tride ...
- twitter storm源码走读之1 -- nimbus启动场景分析
欢迎转载,转载时请注明作者徽沪一郎及出处,谢谢. 本文详细介绍了twitter storm中的nimbus节点的启动场景,分析nimbus是如何一步步实现定义于storm.thrift中的servic ...
- twitter storm 源码走读之5 -- worker进程内部消息传递处理和数据结构分析
欢迎转载,转载请注明出处,徽沪一郎. 本文从外部消息在worker进程内部的转化,传递及处理过程入手,一步步分析在worker-data中的数据项存在的原因和意义.试图从代码实现的角度来回答,如果是从 ...
- twitter storm源码走读之2 -- tuple消息发送场景分析
欢迎转载,转载请注明出处源自徽沪一郎.本文尝试分析tuple发送时的具体细节,本博的另一篇文章<bolt消息传递路径之源码解读>主要从消息接收方面来阐述问题,两篇文章互为补充. worke ...
- twitter storm源码走读之3--topology提交过程分析
概要 storm cluster可以想像成为一个工厂,nimbus主要负责从外部接收订单和任务分配.除了从外部接单,nimbus还要将这些外部订单转换成为内部工作分配,这个时候nimbus充当了调度室 ...
- twitter storm源码走读之8 -- TridentTopology创建过程详解
欢迎转载,转载请注明出处,徽沪一郎. 从用户层面来看TridentTopology,有两个重要的概念一是Stream,另一个是作用于Stream上的各种Operation.在实现层面来看,无论是str ...
- twitter storm源码走读之4 -- worker进程中线程的分类及用途
欢迎转载,转载请注明出版,徽沪一郎. 本文重点分析storm的worker进程在正常启动之后有哪些类型的线程,针对每种类型的线程,剖析其用途及消息的接收与发送流程. 概述 worker进程启动过程中最 ...
- 【原】storm源码之mac os x编译twitter storm源码
twitter storm是由backtype公司创始人nathanmarz一手研发和开源的流计算(实时计算)框架,堪称实时计算领域的hadoop.nathanmarz也是在mac os x环境下开发 ...
- Apache Spark源码走读之7 -- Standalone部署方式分析
欢迎转载,转载请注明出处,徽沪一郎. 楔子 在Spark源码走读系列之2中曾经提到Spark能以Standalone的方式来运行cluster,但没有对Application的提交与具体运行流程做详细 ...
随机推荐
- Android实现边缘凹凸的View
转载 最近做项目的时候遇到一个卡劵的效果,由于自己觉得用图片来做的话可以会出现适配效果不好,再加上自己自定义view方面的知识比较薄弱,所以想试试用自定义View来实现.但是由于自己知识点薄弱,一开始 ...
- 创建型模式之Singleton模式
单例模式大概是最直观的一种设计模式了,尽管直观却不简单. 数学与逻辑学中,singleton定义为“有且仅有一个元素的集合”, 单例模式可以如下定义:“一个类有且仅有一个实例,并且自行实例化向整个系统 ...
- 解决Windows和Ubuntu时间不一致的问题
问题原因是使用的时间不一致导致的.win10直接从bios读出来的时间认为就是实际时间,ubuntu认为加上8个小时 后的才是.win10用的rtc ,ubuntu用的utc 在ubuntu16.04 ...
- uva 11380(最大流+拆点)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36707 思路:根据题意拆点建图即可. #include<io ...
- OD使用心得
查看堆栈 从返回前面的竖线 到 竖线结束 也就是到 (从返回 msconfig.0065a318) 全看.这样不会丢失些东西 或者 看堆栈 直接将堆栈框拉大 避免有些东西没有看到
- 如何写出安全的API接口
通过园友们的讨论,以及我自己查了些资料,然后对接口安全做一个相对完善的总结,承诺给大家写个demo,今天一并放出. 对于安全也是相对的,下面我来根据安全级别分析 1.完全开放的接口 有没有这样的接口, ...
- web_save_timestamp_param获取时间戳函数介绍
函数说明: web_save_timestamp_param("tStamp", LAST); lr_output_message("%s",lr_eval_s ...
- html 音频视频
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- hdu 1269 迷宫城堡 强连通分量
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 关于遍历javascript 中的json串浏览器输出的结果不统一的情况
我们在做项目的时候经常会用到javascript的json. 首先说一下javascript的json串是什么,json串属于javascript的一个对象,有键和值对应的对象. 一般的格式是: a ...