Storm的ACK机制与编码实例

2024-04-26 02:18
文章标签 实例 编码 机制 ack storm

本文主要是介绍Storm的ACK机制与编码实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Storm为了保证每条数据成功被处理,实现至少一次语义,通过Storm的ACK机制可以对spout产生的每一个tuple进行跟踪;

tuple处理成功是指这个Tuple以及这个Tuple产生的所有子Tuple都被成功处理, 由每一个处理bolt通过OutputCollector的方法ack(tuple)来告知storm当前bolt处理成功,最终调用spout的ack方法;

处理失败是指这个Tuple或这个Tuple产生的所有Tuple中的任意一个tuple处理失败或者超时(超时时间由Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS指定), 处理失败bolt调用OutputCollector的方法fail(tuple),来告知storm当前bolt处理失败,最终调用spout的fail方法重新发送失败的tuple,失败时storm不会自动重发失败的tuple,需要我们在spout中重新获取发送失败数据,手动重新发送一次。

Ack原理

Storm中有个特殊的task名叫acker,他们负责跟踪spout发出的每一个Tuple的Tuple树(因为一个tuple通过spout发出了,经过每一个bolt处理后,会生成一个新的tuple发送出去)。当acker(框架自启动的task)发现一个Tuple树已经处理完成了,它会发送一个消息给产生这个Tuple的那个task。对任意大的一个Tuple树,storm只需要恒定的20字节就可以进行跟踪。acker对于每个spout-tuple保存一个ack-val的校验值,它的初始值是0,然后每发射一个Tuple或Ack一个Tuple时,这个Tuple的id就要跟这个校验值异或一下,
并且把得到的值更新为ack-val的新值。那么假设每个发射出去的Tuple都被ack了,那么最后ack-val的值就一定是0。Acker就根据ack-val是否为0来判断是否完全处理,如果为0则认为已完全处理。

例如下图是一个简单的Topology:



开启Act机制

1.spout发射tuple的时候指定messageId
2.spout对发射的tuple进行缓存,否则spout无法获取发送失败的数据进行重发,
(这里到底系统里有没有缓存没有成功处理的tuple,比如接口conf.setMaxSpoutPending()是否只缓存了条数还是原始数据还要去查证一下)
3.spout要重写BaseRichSpout的fail和ack方法,spout根据messageId对于成功处理的tuple从缓存队列中删除,对于失败的tuple选择重发或做其它处理;
4.如果使用BasicBolt,BasicOutputCollector在emit新的tuple时自动与源tuple锚定,execute方法结束时源tuple会被自动ack或fail;
使用RichBolt在emit数据的时需显示指定该数据的源tuple,以保持tracker链路,即collector.emit(oldTuple, newTuple);
并且需要在execute执行成功后调用OutputCollector.ack(tuple), 当失败处理时,执行OutputCollector.fail(tuple);
5.设置acker数大于0,conf.setNumAckers(>0);

关闭Ack机制

1.在Tuple层面去掉可靠性。在发射Tuple的时候不指定MessageID来达到不不跟踪这个Tuple的目的
2.如果对于一个Tuple树里面的某一部分到底成不成功不是很关心,那么可以在Bolt发射这些Tuple的时候不锚定它们。
这样这些Tuple就不在Tuple树里面,也就不会被跟踪了。
3.把Config.TOPOLOGY_ACKERS设置成0。在这种情况下,Storm会在Spout发射一个Tuple之后马上调用Spout的ack方法,
也就是说这个Tuple树不会被跟踪。

例子程序:

  1. public class RandomSentenceSpout extends BaseRichSpout {
  2. private SpoutOutputCollector _collector;
  3. private Random _rand;
  4. private ConcurrentHashMap<UUID, Values> _pending;
  5. public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
  6. _collector = spoutOutputCollector;
  7. _rand = new Random();
  8. _pending = new ConcurrentHashMap<UUID, Values>();
  9. }
  10. public void nextTuple() {
  11. Utils.sleep(1000);
  12. String[] sentences = new String[] {
  13. "I write php",
  14. "I learning java",
  15. "I want to learn swool and tfs"
  16. };
  17. String sentence = sentences[_rand.nextInt(sentences.length)];
  18. Values v = new Values(sentence);
  19. UUID msgId = UUID.randomUUID();
  20. this._pending.put(msgId, v);//spout对发射的tuple进行缓存
  21. _collector.emit(v, msgId);//发射tuple时,添加msgId
  22. }
  23. public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
  24. outputFieldsDeclarer.declare(new Fields("world"));
  25. }
  26. public void ack(Object msgId) {
  27. this._pending.remove(msgId);//对于成功处理的tuple从缓存队列中删除
  28. }
  29. public void fail(Object msgId) {
  30. this._collector.emit(this._pending.get(msgId), msgId);//当消息处理失败了,重新发射,当然也可以做其他的逻辑处理
  31. }
  32. }
  33. public class SplitSentence extends BaseRichBolt {
  34. OutputCollector _collector;
  35. public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
  36. _collector = outputCollector;
  37. }
  38. public void execute(Tuple tuple) {
  39. String sentence = tuple.getString(0);
  40. for (String word : sentence.split(" "))
  41. _collector.emit(tuple, new Values(word));//发射tuple时进行锚定
  42. _collector.ack(tuple);//对处理完的tuple进行确认
  43. }
  44. public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
  45. outputFieldsDeclarer.declare(new Fields("word"));
  46. }
  47. }

场景分析

1. Bolt挂掉了,一个tuple没有被ack,storm的超时机制在超时之后会把这个tuple标记为失败,从而可以重新处理。
2. Acker挂掉了: 这种情况下由这个acker所跟踪的所有spout tuple都会超时,也就会被重新处理。
3. Spout挂掉了: 在这种情况下给spout发送消息的消息源负责重新发送这些消息。
以上机制保证storm的高度容错性

另外Ack机制还常用于限流作用: 为了避免spout发送数据太快,而bolt处理太慢,常常设置pending数,当spout有等于或超过pending数的tuple没有收到ack或fail响应时,跳过执行nextTuple, 从而限制spout发送数据。
通过conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, pending);设置spout pend数。

本文参考:
http://www.cnblogs.com/intsmaze/p/5918087.html
http://itindex.net/detail/55385-storm-trident-%E5%AD%A6%E4%B9%A0
http://www.tuicool.com/articles/vErmIb


这篇关于Storm的ACK机制与编码实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936443

相关文章

Nginx服务器部署详细代码实例

《Nginx服务器部署详细代码实例》Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,:本文主要介绍Nginx服务器部署的相关资料,文中通过代码... 目录Nginx 服务器SSL/TLS 配置动态脚本反向代理总结Nginx 服务器Nginx是一个‌高性

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

Java中自旋锁与CAS机制的深层关系与区别

《Java中自旋锁与CAS机制的深层关系与区别》CAS算法即比较并替换,是一种实现并发编程时常用到的算法,Java并发包中的很多类都使用了CAS算法,:本文主要介绍Java中自旋锁与CAS机制深层... 目录1. 引言2. 比较并交换 (Compare-and-Swap, CAS) 核心原理2.1 CAS

Spring Boot 集成 mybatis核心机制

《SpringBoot集成mybatis核心机制》这篇文章给大家介绍SpringBoot集成mybatis核心机制,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值... 目录Spring Boot浅析1.依赖管理(Starter POMs)2.自动配置(AutoConfigu

springboot+mybatis一对多查询+懒加载实例

《springboot+mybatis一对多查询+懒加载实例》文章介绍了如何在SpringBoot和MyBatis中实现一对多查询的懒加载,通过配置MyBatis的`fetchType`属性,可以全局... 目录springboot+myBATis一对多查询+懒加载parent相关代码child 相关代码懒

C++中的解释器模式实例详解

《C++中的解释器模式实例详解》这篇文章总结了C++标准库中的算法分类,还介绍了sort和stable_sort的区别,以及remove和erase的结合使用,结合实例代码给大家介绍的非常详细,感兴趣... 目录1、非修改序列算法1.1 find 和 find_if1.2 count 和 count_if1

MySQL中如何求平均值常见实例(AVG函数详解)

《MySQL中如何求平均值常见实例(AVG函数详解)》MySQLavg()是一个聚合函数,用于返回各种记录中表达式的平均值,:本文主要介绍MySQL中用AVG函数如何求平均值的相关资料,文中通过代... 目录前言一、基本语法二、示例讲解1. 计算全表平均分2. 计算某门课程的平均分(例如:Math)三、结合

Redis的安全机制详细介绍及配置方法

《Redis的安全机制详细介绍及配置方法》本文介绍Redis安全机制的配置方法,包括绑定IP地址、设置密码、保护模式、禁用危险命令、防火墙限制、TLS加密、客户端连接限制、最大内存使用和日志审计等,通... 目录1. 绑定 IP 地址2. 设置密码3. 保护模式4. 禁用危险命令5. 通过防火墙限制访问6.

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS