欢迎转载,转载请注明出处,徽沪一郎。

本文详细分析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

emitBatch是产生真正需要被处理的tuple的,这些tuple会被各个Operation所在的bolt所接收。它们的调用顺序是

  • TridentBoltExecutor::execute

    •   SubtopologyBolt::execute

      •   InitialReceiver::receive

        •   TridentProcessor::execute

处理结束的判断依据

在TridentSpout中是如何判断所有的tuple都已经被处理的呢。

  1. 在每跳中认为自己处理完毕的时候,它都会告诉下一跳,即下游,我给你发送了多少tuple,如果下游将上游发送过来的确认消息与自身确实已经处理的消息比对一致的话,则认为处理都完成,于是发送ack.
  2. 问题的关键变成每一个bolt是如何判断自己已经处理完毕的呢,请看步骤3
  3. 总有一个bolt是没有上游的,即TridentSpoutExecutor,它只会收到启动指令,但不接收真正的业务数据,于是它会告诉下一跳,我发了多少tuple给你。

STREAM

在MasterBatchCoordinator中定义了三种不同的stream,这三种stream分别是

  1. BATCH_STREAM
  2. COMMIT_STREAM
  3. SUCCESS_STREAM

这些stream分别在什么时候被使用呢,下图给出一个大概的时序

简要说明:

  1. masterbatchcoordinator通过batch_stream发送seeder tuple给tridentspoutcoordinator
  2. tridentspoutcoordinator给tridentspoutexecutor继续传递该指令
  3. TridentSpoutExecutor在收到启动指令后,调用ITridentSpout接口的实现类进行emitBatch
  4. TridentSpoutExecutor在发送完一批batch后,finishBatch被调用,通过emitDirect会给下一跳通过coord_stream发送trackedinfo,即我已经发送了多少消息给你
  5. TridentSpoutExecutor紧接着还会给ack bolt发送ack消息,ack bolt将其传达到MasterBatchCoordinator
  6. MasterBatchCoordinator在收到第一个ack后,将状态置为processed
  7. 当MasterBatchCoordinator再次收到ack后,会将状态转为committing,同时通过commit_stream发送tuple给TridentSpoutExecutor
  8. 收到commit_stream上传来的tuple后,TridentSpoutExecutor会调用ITridentSpout中的emmitter, emmitter::commit()被执行,TridentSpoutExecutor会再次ack收到tuple
  9. MasterBatchCoordinator在收到这个tuple之后,会认为针对某一个seeder tuple的处理已经完全实现,于是通过SUCCESS_STREM告知TridentSpoutCoordinator,所有的活都已经都完成了,收工。
  10. 收到Success_stream上传来的信号后,ITridentSpout中的内嵌子类Emmit和Coordinator中相应的success方法会被调用执行。

注意:

  1. 为了描述方便,将TridentTopology进行了简化,认为其在转换成真正的storm topology时,只有一个TridentProcessor所在的bolt。真实的情况可能比这复杂,但消息的传递路径还是差不多的。
  2. 注意在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可靠性分析的更多相关文章

  1. twitter storm源码走读之6 -- Trident Topology执行过程分析

    欢迎转载,转载请注明出处,徽沪一郎. TridentTopology是storm提供的高层使用接口,常见的一些SQL中的操作在tridenttopology提供的api中都有类似的影射.关于Tride ...

  2. twitter storm源码走读之1 -- nimbus启动场景分析

    欢迎转载,转载时请注明作者徽沪一郎及出处,谢谢. 本文详细介绍了twitter storm中的nimbus节点的启动场景,分析nimbus是如何一步步实现定义于storm.thrift中的servic ...

  3. twitter storm 源码走读之5 -- worker进程内部消息传递处理和数据结构分析

    欢迎转载,转载请注明出处,徽沪一郎. 本文从外部消息在worker进程内部的转化,传递及处理过程入手,一步步分析在worker-data中的数据项存在的原因和意义.试图从代码实现的角度来回答,如果是从 ...

  4. twitter storm源码走读之2 -- tuple消息发送场景分析

    欢迎转载,转载请注明出处源自徽沪一郎.本文尝试分析tuple发送时的具体细节,本博的另一篇文章<bolt消息传递路径之源码解读>主要从消息接收方面来阐述问题,两篇文章互为补充. worke ...

  5. twitter storm源码走读之3--topology提交过程分析

    概要 storm cluster可以想像成为一个工厂,nimbus主要负责从外部接收订单和任务分配.除了从外部接单,nimbus还要将这些外部订单转换成为内部工作分配,这个时候nimbus充当了调度室 ...

  6. twitter storm源码走读之8 -- TridentTopology创建过程详解

    欢迎转载,转载请注明出处,徽沪一郎. 从用户层面来看TridentTopology,有两个重要的概念一是Stream,另一个是作用于Stream上的各种Operation.在实现层面来看,无论是str ...

  7. twitter storm源码走读之4 -- worker进程中线程的分类及用途

    欢迎转载,转载请注明出版,徽沪一郎. 本文重点分析storm的worker进程在正常启动之后有哪些类型的线程,针对每种类型的线程,剖析其用途及消息的接收与发送流程. 概述 worker进程启动过程中最 ...

  8. 【原】storm源码之mac os x编译twitter storm源码

    twitter storm是由backtype公司创始人nathanmarz一手研发和开源的流计算(实时计算)框架,堪称实时计算领域的hadoop.nathanmarz也是在mac os x环境下开发 ...

  9. Apache Spark源码走读之7 -- Standalone部署方式分析

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 在Spark源码走读系列之2中曾经提到Spark能以Standalone的方式来运行cluster,但没有对Application的提交与具体运行流程做详细 ...

随机推荐

  1. Linux网络编程入门 (转载)

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  2. Android中获取蓝牙log

    1.蓝牙的snoop log存放位置 /etc/bluetooth/bt_stack.conf   2.修改方法 #关闭蓝牙 修改bt_stack.conf文件中打印log的等级 adb root a ...

  3. [译] Web API 之 简介

    事实上,MVC 框架本身已经提供了构建REST风格服务的基础,而Web API 只是让你可以更加容易和快捷的构建REST服务. 特性 基于约定的 CRUD Actions: 自动按照HTTP的acto ...

  4. php 解决和避免form表单重复提交的方法

    在提交表单的时候,可能遇到网速等导致页面突然加载变慢,用户重复地点击提交按钮,将在数据库产生多条数据,导致不可控情况. 比如下面的情况就会导致表单重复提交: 点击提交按钮两次. 点击刷新按钮. 使用浏 ...

  5. MATLAB学习笔记(十一)——MATLAB图形用户界面设计

    (一)菜单设计 一.建立用户菜单 1.概况: 用户菜单一般含有一级菜单和二级菜单,乃至多级菜单.每一级菜单又包含多个菜单项.建立菜单可以使用uimenu函数. 2.uimenu函数调用: %建立一级菜 ...

  6. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(四)码农网

    17. 安装 Webmin Webmin 是基于 Web 的 Linux 配置工具.它像一个中央系统,用于配置各种系统设置,比如用户.磁盘分配.服务以及 HTTP 服务器.Apache.MySQL 等 ...

  7. SharedPreferences存储

    *通过getSharedPreferences()方法获得SharedPreferences对象 SharedPreferences pref = getShaedPreferences(“key”, ...

  8. android自定义弹出框样式实现

    前言: 做项目时,感觉Android自带的弹出框样式比较丑,很多应用都是自己做的弹出框,这里也试着自己做了一个. 废话不说先上图片: 实现机制 1.先自定义一个弹出框的样式 2.自己实现CustomD ...

  9. Hark的数据结构与算法练习之煎饼排序

    算法说明 假设煎锅里边有N个煎饼摞在了一起,它们大小不一并且顺序不一致,我们需要通过拿铲子将它们不停的翻个,进行排序,最终得到一个底下是大的煎饼,上边是小的煎饼的序列.这个排序的过程就是煎饼排序. 这 ...

  10. Bitnami Redmine安装和插件配置

    公司要进行敏捷开发管理,最后选择Redmine作为管理工具. 而Redmine本身的安装非常麻烦,要安装mysql,ruby,redmine,apach. 显然这不是一个偷懒的人应该做的,最后找到Bi ...