Storm——可靠性(ACK原理)

Strom 消息可靠性保障机制和Ack原理 Strom 消息可靠性保障机制和Ack原理Storm提供了消息处理的保障机制,可以保证从Spout发射出的每个tuple都得到完整的处理。当然Storm消息处理保障机制的前提是你使用了这种特性,如果你的业务对偶尔丢失的tuple不敏感,那么也没必要启用这种机制,毕竟有得就会有失。 阅读详情

Storm——可靠性(ACK原理)

转载  2015年10月26日 11:06:39
  • 2754

转自:http://blog.youkuaiyun.com/xeseo/article/details/17754825

对于Storm,它有一个很重要的特性:“Guarantee no data loss” ——可靠性

很显然,要做到这个特性,必须要track每个data的去向和结果。Storm是如何做到的呢——acker机制。

先概括下acker所参与的工作流程:

1. Spout创建一个新的Tuple时,会发一个消息通知acker去跟踪;

2. Bolt在处理Tuple成功或失败后,也会发一个消息通知acker;

3. acker会找到发射该Tuple的Spout,回调其ack或fail方法。


我们说RichBolt和BasicBolt的区别是后者会自动ack。那么是不是我们只要实现了Spout的ack或fail方法就能看到反馈了呢?

试试在RandomSpout中加入如下代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2.     public void ack(Object msgId) {  
  3.         System.err.println("ack " + msgId);  
  4.     }  
  5.   
  6.     @Override  
  7.     public void fail(Object msgId) {  
  8.         System.err.println("fail " + msgId);  
  9.     }  

重新运行ExclaimBasicTopo,看下结果。并没有任何的ack 和 fail 出现?

原因是,Storm要求如果要track一个Tuple,必须要指定其messageId,也就是回调回ack和fail方法的参数。如果我们不指定,Storm是不会去track该tuple的,即不保证消息丢失!

我们改下Spout代码,为每个消息加入一个唯一Id。同时,为了方便看结果,加入更多的打印,并且靠sleep减慢发送速度。(只是为了演示!)

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class RandomSpout extends BaseRichSpout {  
  2.   
  3.     private SpoutOutputCollector collector;  
  4.   
  5.     private Random rand;  
  6.       
  7.     private AtomicInteger counter;  
  8.       
  9.     private static String[] sentences = new String[] {"edi:I'm happy", "marry:I'm angry", "john:I'm sad", "ted:I'm excited", "laden:I'm dangerous"};  
  10.       
  11.     @Override  
  12.     public void open(Map conf, TopologyContext context,  
  13.             SpoutOutputCollector collector) {  
  14.         this.collector = collector;  
  15.         this.rand = new Random();  
  16.         counter = new AtomicInteger();  
  17.     }  
  18.   
  19.     @Override  
  20.     public void nextTuple() {  
  21.         Utils.sleep(5000);  
  22.         String toSay = sentences[rand.nextInt(sentences.length)];  
  23.         int msgId = this.counter.getAndIncrement();  
  24.         toSay = "["+ msgId + "]"+ toSay;  
  25.         PrintHelper.print("Send " + toSay );  
  26.           
  27.         this.collector.emit(new Values(toSay), msgId);  
  28.     }  
  29.   
  30.     @Override  
  31.     public void declareOutputFields(OutputFieldsDeclarer declarer) {  
  32.         declarer.declare(new Fields("sentence"));  
  33.     }  
  34.       
  35.     @Override  
  36.     public void ack(Object msgId) {  
  37.         PrintHelper.print("ack " + msgId);  
  38.     }  
  39.   
  40.     @Override  
  41.     public void fail(Object msgId) {  
  42.         PrintHelper.print("fail " + msgId);  
  43.     }  
  44.   
  45. }  

PrintHelper类:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class PrintHelper {  
  2.   
  3.     private static SimpleDateFormat sf = new SimpleDateFormat("mm:ss:SSS");  
  4.       
  5.     public static void print(String out){  
  6.         System.err.println(sf.format(new Date()) + " [" + Thread.currentThread().getName() + "] " + out);  
  7.     }  
  8.       
  9. }  

同时把PrintBolt里面打印也换成PrintHelper.print打印


看下打印结果:
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 53:33:891 [Thread-26-spout] Send [0]ted:I'm excited  
  2. 53:33:896 [Thread-20-print] Bolt[0] String recieved: [0]ted:I'm excited!  
  3. 53:38:895 [Thread-26-spout] Send [1]edi:I'm happy  
  4. 53:38:895 [Thread-22-print] Bolt[1] String recieved: [1]edi:I'm happy!  
  5. 53:38:895 [Thread-26-spout] ack 0  
  6. 53:43:896 [Thread-26-spout] Send [2]edi:I'm happy  
  7. 53:43:896 [Thread-22-print] Bolt[1] String recieved: [2]edi:I'm happy!  
  8. 53:43:896 [Thread-26-spout] ack 1  
  9. 53:48:896 [Thread-26-spout] Send [3]edi:I'm happy  
  10. 53:48:896 [Thread-26-spout] ack 2  
  11. 53:48:896 [Thread-24-print] Bolt[2] String recieved: [3]edi:I'm happy!  
  12. 53:53:896 [Thread-26-spout] Send [4]ted:I'm excited  
  13. 53:53:896 [Thread-26-spout] ack 3  
  14. 53:53:896 [Thread-20-print] Bolt[0] String recieved: [4]ted:I'm excited!  
  15. 53:58:897 [Thread-26-spout] Send [5]laden:I'm dangerous  
  16. 53:58:897 [Thread-26-spout] ack 4  
  17. 53:58:898 [Thread-24-print] Bolt[2] String recieved: [5]laden:I'm dangerous!  

很明显看到:

a. 并发度为1的Spout确实是一个线程,并发度为3的Bolt确实是三个线程;

b. 消息完全处理完成后,确实回调了ack(Object msgId)方法,而且msgId的值,即为我们emit的msgId;

c. 虽然我们在topology中定义了两个bolt,但实际上ack对于每个tuple只调用了一次;

d. spout发出tuple后,Bolt很快就完成了,但是ack直到5秒后spout醒来才打印。


Tuple树

对于Spout创建的Tuple,在topology定义的流水线中经过Bolt处理时,可能会产生一个或多个新的Tuple。源Tuple+新产生的Tuple构成了一个Tuple树。当整棵树被处理完成,才算一个Tuple被完全处理,其中任何一个节点的Tuple处理失败或超时,则整棵树失败。

超时的值,可以通过定义topology时,conf.setMessageTimeoutSecs方法指定。


Anchor

在我们例子中ExclaimRichBolt用

collector.emit(inputTule, new Values(newTupleValue));

发射一个新的tuple。

第一个参数是传入Bolt的tuple,第二个参数是新产生的tuple的value,这种emit的方式,在Storm中称为: "anchor"。


Tuple的ack

前面我们一直提到acker,看到这里,你应该能猜出acker其实就是Storm里面track一个Tuple保证其一定被处理的功能。acker也是一个component。

我们来看看acker的工作流程:

1. Spout在初始化时会产生一个tasksId;

2. Spout中创建新的Tuple,其id是一个64位的随机数;

3. Spout将新建的Tuple发送出去(给出了messageId来开启Tuple的追踪), 同时会发送一个消息到某个acker,要求acker进行追踪。该消息包含两部分:

  • Spout的taskId:用户acker在整个tuple树被完全处理后找到原始的Spout进行回调ack或fail
  • 一个64位的ack val值: 标志该tuple是否被完全处理。初始值为0。

3. 一个Bolt在处理完Tuple后,如果发射了一个新的anchor tuple,Storm会维护anchor tuple的列表;

4. 该Bolt调用OutputCollector.ack()时,Storm会做如下操作:

  • 将anchor tuple列表中每个已经ack过的和新创建的Tuple的id做异或(XOR)。假定Spout发出的TupleID是tuple-id-0,该Bolt新生成的TupleID为tuple-id-1,那么,tuple-id-0XORtuple-id-0XORtuple-id-1
  • Storm根据该原始TupleID进行一致性hash算法,找到最开始Spout发送的那个acker,然后把上面异或后得出的ack val值发送给acker

5. acker收到新的ack val值后,与保存的原始的Tuple的id进行异或,如果为0,表示该Tuple已被完全处理,则根据其taskId找到原始的Spout,回调其ack()方法。


fail的机制类似,在发现fail后直接回调Spout的fail方法。

Storm就是通过这个acker的机制来保证数据不丢失。


回头再看看上面的打印结果,b、c两条得到很好的解释了。那d是为什么呢?

在最开始时,我曾经提到过,Storm的设计模型中,Spout是源源不断的产生数据的,所以其nextTuple()方法在任何时候不应该被打断。ack,fail 和 nextTuple是在同一个线程中完成的。

所以,虽然acker发现一个Tuple已经完全处理完成,但是由于Spout线程在Sleep,无法回调。


在设计中,我们应尽量避免在Spout、Bolt中去Sleep。如果确实需要控制,最好用异步线程来做,例如用异步线程读取数据到队列,再由Spout去取队列中数据。异步线程可以随意控制速度等。


另外,

Storm是否会自动重发失败的Tuple?

这里答案已经很明显了。fail方法如何实现取决于你自己。只有在fail中做了重发机制,才有重发。

注:Trident除外。这是Storm提供的特殊的事务性API,它确实会帮你自动重发的。

Unanchor

如果我们在Bolt中用OutputCollector.emit()发射一个新的Tuple时,并没有指定输入的Tuple(IBasicBolt的实现类用的是BasicOutPutCollector,其emit方法实际上还是调用OutputCollector.emit(),只不过内部会帮你填上输入的Tuple),那么行为称之为“Unanchor”。

是否用Unanchor方式取决于你的实现。


调整可靠性

在某些特定的情况下,你或许想调整Storm的可靠性。例如,你并不关心数据是否丢失,或者你想看看后面是否有某个Bolt拖慢了Spout的速度?
那么,有三种方法可以实现:
1. 在build topology时,设置acker数目为0,即conf.setNumAckers(0);
2. 在Spout中,不指定messageId,使得Storm无法追踪;
3. 在Bolt中,使用Unanchor方式发射新的Tuple。

Storm消息可靠性保证机制ack与fail原理 一.Storm spout的nextTuple以及bolt的execute Storm的API非常丰富,但是记住,本文介绍的ACK机制需要特殊的支持。也就是说,本文所说的ACK的机制只是Storm的一种可选机制,你完全可以无视它去选择一种轻量的无确认的Best effort方式去使用Storm,本文之所以单独介绍ACK机制,是因为其优雅。 在编写spout... 阅读详情

相关推荐

Storm核心原理解析:从入门到精通

随着实时数据处理需求的爆发(如实时推荐、风控、监控),传统批处理框架(Hadoop)无法满足低延迟要求。Storm作为首个开源分布式实时流处理框架(2011年由BackType开发,2014年进入Apache顶级项目),凭借其高吞吐、低延迟、强可靠的特性,成为实时计算领域的经典解决方案。本文将覆盖Storm的架构设计、核心机制(消息可靠性、任务调度、容错)、实战开发及未来趋势,帮助开发者从原理到代码全面掌握。本文采用“原理-模型-实战-趋势”的递进结构:第2章解析核心组件与架构;

AI架构师小马 846

Storm应用系列之——可靠性与acker机制

Storm是如何保证数据的不丢失的?内部原理是什么?什么是acker?

Edison Xu 1万+

远程桌面(RDP)共享USB设备全攻略:不止Hyper-V,你的加密狗和CH340串口也能远程用

本文详细介绍了远程桌面(RDP)共享USB设备的完整解决方案,包括加密狗和CH340串口设备的远程使用技巧。通过RemoteFX USB重定向技术,用户可以在远程会话中无缝使用本地USB设备,提升工作效率。文章涵盖企业级配置、典型设备实战案例及高级故障排除方法,是远程工作者的实用指南。

weixin_42522964的博客 334

storm - 可靠机制

一 可靠性简单介绍                    Storm的可靠性是指Storm会告知用户每个消息单元是否在一个指定的时间(timeout)内被全然处理。全然处理的意思是该MessageId绑定的源Tuple以及由该源Tuple衍生的全部Tuple都经过了Topology中每个应该到达的Bolt的处理。 注: timetout 能够通过Con...

weixin_34192993的博客 169

Android自动化新方案:ESP32-C3蓝牙HID模拟触控与手势操作实战(附源码)

本文详细介绍了使用ESP32-C3通过蓝牙HID协议实现Android设备自动化操作的完整方案。该硬件方案成本低廉且能完美规避系统风控,可模拟鼠标移动、点击及复杂手势操作,延迟低于50毫秒,适用于游戏连招和应用测试等场景。文章包含完整的源码实现和性能优化技巧。

kotlin6android的博客 379

MATLAB安装

Matlab 2016a 安装包及破解教程百度云分享链接: 链接:https://pan.baidu.com/s/1i6BgD8p       密码:17gg   Matlab安装教程: 1、下载文件,得到R2016a_win64.part1.rar、R2016a_win64.part2.rar两部分安装文件和Matlab 2016a Win64 Crack破解文件。 2、解压安装文件(解...

qq_36734094的博客 17万+

Storm UI

storm集群搭建好以后,我们通过Storm UI来查看集群的运行情况:关于如何查看可以看我的另一篇博客:http://www.fengxiaochuan.com/?p=4 Storm UI

枫丶小丶川 1832

Bob-Smith电路在千兆以太网(1000BASE-T)中的优化设计与性能分析

本文深入探讨了Bob-Smith电路在千兆以太网(1000BASE-T)中的关键作用与优化设计。分析表明,相较于单纯追求75欧姆电阻的精确匹配,优化重点应转向PCB布局对称性、高频元件选型及共模路径完整性,以有效抑制共模噪声、提升信号完整性,并确保系统通过EMC测试。

weixin_29281941的博客 281

Storm容错机制Acker

目录(1)基于tuple树的Acker详解(2)如何开启或者关闭Acker(1)如何开启Acker(2)如何关闭Acker(3)Acker机制的编程模型(4)Storm可靠性实现的设计思想(1)需要实现可靠性的场景(2)可靠性设计 — Acker失败重发编码实现思路(5)Storm可靠性及Acker失败重发编码实现 (1)基于tuple树的Acker详解 Storm中有个特殊的Executor叫acker,他们负责跟踪spout发出的每一个Tuple的Tuple树。当acker发现一个Tuple树 已经处理

蔡政洁的博客 807

WIFI 相关的频偏调试以及天线调试记录

WIFI RF 相关的频偏调试以及天线调试 1,频率误差(Frequency Error) 频率误差(Frequency Error):表征射频信号偏离该信号所处信道中心频率的大小,单位PPM。频偏误差要求范围如下表。 频偏越小越好。PPM的计算公式如下: 问题: 我们ESP8089认证测试的时候频偏测试超了。需要修改哪些呢。 测试频率点在2.411865385GHz 宣称点:2.412GHz 频率偏移计算:{(2.412GHz-2.411865385GHz)÷2...

armkits的博客 1万+

AFSim2.9.0学习笔记 —— 2、AFSim的Wizard软件概述(ArkSIM集成开发环境 (IDE))

AFSim2.9.0学习笔记 —— 2、AFSim的Wizard软件详述(ArkSIM集成开发环境 (IDE))

923

storm的ack原理

Storm的ack机制 Ack机制基本知识 (1)为了保证消息处理过程中的可靠性,storm使用了ack机制。storm会专门启动若干acker线程,来追踪tuple的处理过程。acker线程数量可以设置。 (2)每一个Tuple在Spout中生成的时候,都会分配一个64位的messageId。通过对messageId进行哈希我们可以知道要对哪个ack...

麋鹿麋鹿迷了路 346

通过轻量级图像增强Transformer (IAT) 提升YOLOv8在低光环境下的检测性能

随着深度学习和计算机视觉的快速发展,目标检测模型在各个领域中的应用不断扩展,特别是在低照度环境下的视觉任务。YOLOv8作为当前最先进的目标检测模型之一,在高亮度和良好照明条件下表现出色,但在低照度环境下的性能存在一定的不足。为了解决这一问题,我们提出了一种轻量级的低照度图像增强网络(IAT)来改进YOLOv8的暗光检测能力。本篇文章将深入探讨这一创新改进,并附带代码实现,帮助大家更好地理解这一技术的应用和效果。

博客 1215

storm的ack机制以及原理

Storm的ack机制 Ack机制基本知识 (1)为了保证消息处理过程中的可靠性,storm使用了ack机制。storm会专门启动若干acker线程,来追踪tuple的处理过程。acker线程数量可以设置。 (2)每一个Tuple在Spout中生成的时候,都会分配一个64位的messageId。通过对messageId进行哈希我们可以知道要对哪个ack...

麋鹿麋鹿迷了路 578

12、探索新型高能量密度材料:FOX-7的化学进展

本文全面探讨了新型高能量密度材料FOX-7的化学进展,包括其独特的分子结构、优异的热稳定性、光谱性质以及爆炸性能。对比传统高爆炸药RDX,FOX-7展现出更低的敏感性和更高的安全性。文章还介绍了FOX-7的合成方法、异构体研究、与其结构相关的化合物以及富氮高能材料的最新发展。通过实验和计算方法,研究人员不断优化这类材料的性能,以满足军事和工业领域的高要求。

sea99的博客 353

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Storm的消息确认ack机制原理详解

参考博客:https://www.cnblogs.com/Transkai/p/10909117.html加上个人理解 消息不丢失机制ack ack是什么 ack 机制是storm整个技术体系中非常闪亮的一个创新点。 通过Ack机制,spout发送出去的每一条消息,都可以确定是被成功处理或失败处理, 从而可以让开发者采取动作。 比如在Meta中,成功被处理,即可更新偏移量,当失败时,重复发送数据。 因此,通过Ack机制,很容易做到保证所有数据均被处理,一条都不漏。 另外需要注意的...

zytmaster的博客 661

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Storm的可靠性与ack机制

无论是实时处理还是离线处理,都会遇到一个不可避免的问题是,失败任务如何重做?Storm提供了一个ack机制。首先来看一下ISpout接口的方法。 1 Spout的可靠性 ISpout.java部分源码: public interface ISpout extends Serializable { /** * Called when a task for this comp...

orisonchan的博客 490

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

xor(异或)解决Storm的Tuple确认问题

Storm spout的nextTuple以及bolt的execute Storm的API非常丰富,但是记住,本文介绍的ACK机制需要特殊的支持。也就是说,本文所说的ACK的机制只是Storm的一种可选机制,你完全可以无视它去选择一种轻量的无确认的Best effort方式去使用Storm,本文之所以单独介绍ACK机制,是因为其优雅。   在编写spout的nextTuple时,最终你必须要em...

qq_36864672的博客 520

ack是什么,如何使用Ack机制,如何关闭Ack机制,基本实现,STORM的消息容错机制,Ack机制

ack是什么,如何使用Ack机制,如何关闭Ack机制,基本实现,STORM的消息容错机制,Ack机制

qq_44884269的博客 2028

Storm的ACK机制与编码实例

Storm的ACK机制与编码实例 2016年10月25日 17:46:10 阅读数:5124 Storm为了保证每条数据成功被处理,实现至少一次语义,通过Storm的ACK机制可以对spout产生的每一个tuple进行跟踪; tuple处理成功是指这个Tuple以及这个Tuple产生的所有子Tuple都被成功处理, 由每一个处理bolt通过OutputCollector的方法ack(tup...

jason_xiaojie_liu的博客 227

Storm的ack机制在项目应用中的坑

正在学习storm的大兄弟们,我又来传道授业解惑了,是不是觉得自己会用ack了。好吧,那就让我开始啪啪打你们脸吧。 先说一下ACK机制:   为了保证数据能正确的被处理, 对于spout产生的每一个tuple, storm都会进行跟踪。   这里面涉及到ack/fail的处理,如果一个tuple处理成功是指这个Tuple以及这个Tuple产生的所有Tup...

weixin_33831196的博客 229

Storm的Act机制

ack是什么 ack 机制是storm整个技术体系中非常闪亮的一个创新点。 通过Ack机制,spout发送出去的每一条消息,都可以确定是被成功处理或失败处理, 从而可以让开发者采取动作。比如在Meta中,成功被处理,即可更新偏移量,当失败时,重复发送数据。 因此,通过Ack机制,很容易做到保证所有数据均被处理,一条都不漏。 另外需要注意的,当spout触发fail动作时,不会自动重发失败的...

春水初生,春林初盛,春风十里,不如随笔 458

五、Storm分组策略与可靠性

一、分组策略: 1、Stream Grouping概述: A stream grouping defines how that stream should be partitioned among the bolt's tasks http://storm.apache.org/releases/1.1.2/Concepts.html 8种分组策略; ①Shuffle grouping:...

qq_1306238492的博客 210

Apache Storm 实时流处理系统ACK机制以及源码分析

1.ACK机制简介        Storm的可靠性是指Storm会告知用户每一个消息单元是否在一个指定的时间(timeout)内被完全处理。完全处理的意思是该MessageId绑定的源Tuple以及由该源Tuple衍生的所有Tuple都经过了Topology中每一个应该到达的Bolt的处理。注: timetout 可以通过Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS ...

Master-TJ的个人博客 1965
上一篇: storm中declareOutputFields方法的使用规则及与fieldsGrouping方法的联系
下一篇: Cloudera简介和安装部署概述
王树民
博客等级 码龄10年 912粉丝 560原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值