我们在学习ack机制的时候,我们知道Storm的Bolt有BaseBasicBolt和BaseRichBolt。
在BaseBasicBolt中,BasicOutputCollector在emit数据的时候,会自动和输入的tuple相关联,而在execute方法结束的时候那个输入tuple会被自动ack。
在使用BaseRichBolt需要在emit数据的时候,显示指定该数据的源tuple要加上第二个参数anchor tuple,以保持tracker链路,即collector.emit(oldTuple, newTuple);并且需要在execute执行成功后调用OutputCollector.ack(tuple), 当失败处理时,执行OutputCollector.fail(tuple);

那么我们来看看BasicBolt的源码是不是这样的,不能因为看到别人的帖子说是这样的,我们就这样任务,以讹传讹,我们要To see is to believe。

为了方便看源代码,我先上我们的继承类:

public class SplitSentenceBolt extends BaseBasicBolt {  public void prepare(Map stormConf, TopologyContext context) {
super.prepare(stormConf, context);
}

  //5:执行我们自己的逻辑处理方法,接收传入的参数。
  public void execute(Tuple input, BasicOutputCollector collector) {
String sentence = (String)input.getValueByField("sentence");
String[] words = sentence.split(" ");
for (String word : words) {
word = word.trim();
word = word.toLowerCase();
collector.emit(new Values(word,1));//这个地方就是调用OutputCollector的包装类,来发消息
}
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word","num"));
}
}

通过打断点,我们发现,bolt的task会创建这个类下面会标准执行顺序

public class BasicBoltExecutor implements IRichBolt {
public static Logger LOG = LoggerFactory.getLogger(BasicBoltExecutor.class); private IBasicBolt _bolt;
private transient BasicOutputCollector _collector;
//1:创建该对象,然后把我们写的SplitSentenceBolt对象赋给父类IBasicBolt。
public BasicBoltExecutor(IBasicBolt bolt) {
_bolt = bolt;
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
_bolt.declareOutputFields(declarer);//这里就是调用SplitSentenceBolt对象的方法了。
}
 //2:给BasicOutputCollector _collector字段赋值,BasicOutputCollector就是对OutputCollector类的包装。
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
_bolt.prepare(stormConf, context);
_collector = new BasicOutputCollector(collector);
}
  //3:然后程序执行该方法,input的值source: spout1:4, stream: default, id: {}, [+ - * % /]
public void execute(Tuple input) {
_collector.setContext(input);//把接收到的tuple值设置给BasicOutputCollector中inputTuple字段。
try {
_bolt.execute(input, _collector);//这个地方是调用我们实现类SplitSentenceBolt的ececute方法。
_collector.getOutputter().ack(input);//这个地方就是响应
} catch(FailedException e) {
if(e instanceof ReportedFailedException) {
_collector.reportError(e);
}
_collector.getOutputter().fail(input);//这个地方就是响应
}
}
public void cleanup() {
_bolt.cleanup();
}
public Map<String, Object> getComponentConfiguration() {
return _bolt.getComponentConfiguration();
}
}
public class BasicOutputCollector implements IBasicOutputCollector {
private OutputCollector out;
private Tuple inputTuple;
public BasicOutputCollector(OutputCollector out) {
this.out = out;
}
//4:把收到的tuple数据赋值给inputTuple,这个时候BasicOutputCollector对象的字段都具有值了。
   public void setContext(Tuple inputTuple) {
this.inputTuple = inputTuple;
}
   //6:这里我们发送新的(转换后的)tuple数据,看他内部的调用,其实他也会发送一个anchor tuple来保持tracker链路,
而这个anchor tuple就是bolt接收到转换前的源tuple数据。
  public List<Integer> emit(List<Object> tuple) {
     return emit(Utils.DEFAULT_STREAM_ID, tuple);
   }
public List<Integer> emit(String streamId, List<Object> tuple) {
return out.emit(streamId, inputTuple, tuple);
}
public void emitDirect(int taskId, String streamId, List<Object> tuple) {
out.emitDirect(taskId, streamId, inputTuple, tuple);
}
public void emitDirect(int taskId, List<Object> tuple) {
emitDirect(taskId, Utils.DEFAULT_STREAM_ID, tuple);
}
protected IOutputCollector getOutputter() {
return out;
}
public void reportError(Throwable t) {
out.reportError(t);
}
}

这里大家不要纠结bolt的启动时从哪里开始的,我后面会讲的,这里我们关注的是,BasicBoltExecutor对象创建后的执行过程,以这我们来看执行的过程。在BasicBoltExecutor的execute方法中,我们看到了ack和fail方法会被自动调用的,当我们的程序抛出异常则会执行fail方法的。

这个

Storm的BaseBasicBolt源码解析ack机制的更多相关文章

  1. Netty源码解析 -- ChannelPipeline机制与读写过程

    本文继续阅读Netty源码,解析ChannelPipeline事件传播原理,以及Netty读写过程. 源码分析基于Netty 4.1 ChannelPipeline Netty中的ChannelPip ...

  2. Storm可靠性实例解析——ack机制

    对于Storm,它有一个很重要的特性:“Guarantee no data loss” ——可靠性 很显然,要做到这个特性,必须要track每个data的去向和结果.Storm是如何做到的呢——ack ...

  3. Flink 源码解析 —— 深度解析 Flink 序列化机制

    Flink 序列化机制 https://t.zsxq.com/JaQfeMf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭 ...

  4. [源码解析] 并行分布式框架 Celery 之 容错机制

    [源码解析] 并行分布式框架 Celery 之 容错机制 目录 [源码解析] 并行分布式框架 Celery 之 容错机制 0x00 摘要 0x01 概述 1.1 错误种类 1.2 失败维度 1.3 应 ...

  5. Android -- 从源码解析Handle+Looper+MessageQueue机制

    1,今天和大家一起从底层看看Handle的工作机制是什么样的,那么在引入之前我们先来了解Handle是用来干什么的 handler通俗一点讲就是用来在各个线程之间发送数据的处理对象.在任何线程中,只要 ...

  6. [Spark內核] 第42课:Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践

    本课主题 Broadcast 运行原理图 Broadcast 源码解析 Broadcast 运行原理图 Broadcast 就是将数据从一个节点发送到其他的节点上; 例如 Driver 上有一张表,而 ...

  7. jquery源码解析:jQuery数据缓存机制详解2

    上一课主要讲了jQuery中的缓存机制Data构造方法的源码解析,这一课主要讲jQuery是如何利用Data对象实现有关缓存机制的静态方法和实例方法的.我们接下来,来看这几个静态方法和实例方法的源码解 ...

  8. jquery源码解析:jQuery数据缓存机制详解1

    jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...

  9. 【Java实战】源码解析Java SPI(Service Provider Interface )机制原理

    一.背景知识 在阅读开源框架源码时,发现许多框架都支持SPI(Service Provider Interface ),前面有篇文章JDBC对Driver的加载时应用了SPI,参考[Hibernate ...

随机推荐

  1. atitit.闭包的概念与理解attilax总结v2 qb18.doc

    atitit.闭包的概念与理解attilax总结v2 qb18.doc 1.1. 闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.1 2. #---- ...

  2. LINQ系列:Linq to Object转换操作符

    转换是指将输入对象的类型转变为序列的动作. 1. AsEnumerable AsEnumerable操作符将查询的输入以IEnumberable(T)类型返回. 2. Cast Cast操作符将IEn ...

  3. ExtJs4之Grid详细

    ExtJs博客前奏 由于这段时间事情比较杂乱,博客就主要以项目中例子来说明编写. ExtJs4中的Grid非常强大,有展示,选中,搜索,排序,编辑,拖拽等基本功能,这篇博客我就这几个功能做写累述. 1 ...

  4. 前端MVVM框架avalon揭秘 - HTML编译器

    MVVM试图更加清晰的讲用户界面(UI)开发从应用程序的业务逻辑与行为中心分离,因为,很多这样的模式的实现都需要利用声明式数据绑定来实现讲View(视图)工作从其他层分离 所以出现了一大堆自定义的声明 ...

  5. jQuery-easyui实现关闭全部tabs

    有时候当我们打开很多tabs选项卡时,要关闭它只能一个一个的进行关闭,显然太麻烦,这时可以在选项卡的最右边添加一个按钮 实现关闭全部. function openTab(text, url, icon ...

  6. 通过3个Hello World应用来了解ASP.NET 5应用是如何运行的(3)

    设置自定义的入口程序体现应用本身与应用托管之间的分离,它使我们可以创建独立于托管环境的应用,并根据需要寄宿于任何一个我们希望的宿主程序下,对于Web应用来说这一点尤为重要.对于之前的Web应用来说,I ...

  7. flat network 原理与配置 - 每天5分钟玩转 OpenStack(86)

    flat network 是不带 tag 的网络,要求宿主机的物理网卡直接与 linux bridge 连接,这意味着: 每个 flat network 都会独占一个物理网卡. 上图中 eth1 桥接 ...

  8. 关于SubSonic3.0插件使用SubSonic.Query.Select查询时,字段类型为tinyint时列丢失问题的Bug修复

    下午在写代码时,突然发现一个列名为Enable的字段怎么也查询不出来,开始以为可能这个名称是关键字,所以给过滤掉了,所以就将名称修改为IsEnable,问题还是一样......将名称又改为IsEnab ...

  9. scikit-learn 朴素贝叶斯类库使用小结

    之前在朴素贝叶斯算法原理小结这篇文章中,对朴素贝叶斯分类算法的原理做了一个总结.这里我们就从实战的角度来看朴素贝叶斯类库.重点讲述scikit-learn 朴素贝叶斯类库的使用要点和参数选择. 1. ...

  10. 关于在Linux64位下安装xampp

    网上关于这个主题的内容比较少,所以就写一下按装后的心得.之前一直在windows下用xampp,想在Linux下也体验一把,可是自己的Linux装的是64位的在XAMPP的官网上http://www. ...