在很多应用场景中,分布式系统的可靠性保障尤其重要。比如电商平台中,客户的购买请求需要可靠处理,不能因为节点故障等原因丢失请求;比如告警系统中,产生的核心告警必须及时完整的知会监控人员,不能因为网络故障而丢失数据。

Storm消息可靠性保障是Storm核心特性之一,其中消息树的跟踪管理机制是Storm核心算法之一,本文将详细介绍Storm消息可靠处理机制。我们从Storm初探中的例子入手。

一、消息处理流程

1、 Spout节点

(1) Spout接收到一个文本消息;

msg1

刘备 关羽 张飞

曹操 郭嘉 荀彧

(2) Spout把文本消息拆分为2个行字符串消息,并把2个消息发送给NamesSplit Bolt节点。

2、 NamesSplit Bolt节点

(1) NamesSplit Bolt接收到两个行字符串消息;

msg2 刘备 关羽 张飞

msg3 曹操 郭嘉 荀彧

(2) NamesSplit Bolt把2个行字符串消息拆分为6个名字消息,发送给HelloWorld Bolt节点;

(3) NamesSplit Bolt确认,msg2、msg3处理完成。

3、 HelloWorld Bolt节点

(1) HelloWorld Bolt接收到6个名字消息;

msg4 刘备

msg5 关羽

msg6 张飞

msg7 曹操

msg8 郭嘉

msg9 荀彧

(2) HelloWorld Bolt SayHello;

(3) HelloWorld Bolt确认,msg4、msg5、msg6、msg7、msg8、msg9处理完成。

 二、关键代码

 1、 Spout

下面代码表示Spout节点发送消息,消息绑定到messageId上,这里的messageId可以看做上述例子中的msg1,tuple可以看做上述例子中的msg2或msg3。

  1. public void nextTuple()
  2. {
  3. this.collector.emit(List<Object> tuple, Object messageId);
  4. }

下面代码会在消息处理成功或失败后调用。

  1. public void ack(Object msgId)
  2. {
  3. }
  4.  
  5. public void fail(Object msgId)
  6. {
  7. }

2、 Bolt

这段代码是Bolt消息处理发送代码,我们详细看一下标红代码。

  1. public void execute(Tuple input)
  2. {
  3. String[] nameArray = names.split(" ");
  4. for(String name : nameArray)
  5. {
  6. List<Object> splitList = new ArrayList<Object>();
  7. splitList.add(name);
  8. collector.emit(inputList, splitList);
  9. }
  10. collector.ack(input);
  11. }
  1. OutputCollector.emit(Collection<Tuple> anchors, List<Object> tuple) tuple表示发送的子消息,anchors表示子消息的父节点。
    这段代码既发送了子消息,又把子消息锚定到了消息树上。上述例子中,相当于把消息msg4 刘备,msg5关羽,msg6张飞锚定到消息msg2 刘备 关羽 张飞上。
    OutputCollector.ack(Tuple input)表示回答消息处理完成。上述例子中,相当于确认msg2 刘备 关羽 张飞处理完成。
  1. 下面代码会在消息处理成功或失败后调用。
  1. public void ack(Object msgId)
  2. {
  3. }
  4.  
  5. public void fail(Object msgId)
  6. {
  7. }
  1.  

三、消息重发机制

可以看到,一条消息从Spout发送后,会产生一棵消息树,只有当消息树中的所有消息都被确认后(ack),Storm才认为消息处理完成。

代码上可以轻易看出,我们只需要指定根节点消息ID(即Spout接收到的消息ID),其他消息ID系统会自动生成。同时,我们只需要确认非根节点消息处理完成。

实际上,Spout或者Bolt每发送一条消息,消息便会存储到kestrel队列中,Bolt每接收到一条消息,kestrel便会标记这条消息在处理中(pengding),直到该条消息被确认处理完成,kestrel才把它移除出队列。

Bolt消息处理过程中,发生异常或者超时,kestrel会把该条消息从处理中状态重新置为待处理状态,等待Storm下一次调度处理。

四、消息树管理算法

可以看到,Spout每处理一个消息,就会生成一棵消息树,如果Storm存储每棵消息树每个节点的状态,内存很快便会耗尽,显然是不可取的。

实际上,Storm仅仅采用20字节管理一棵消息树,数据结构如下:

treeId|{64bit}

treeId用于区分不同的消息树(和代码中指定的根节点ID一一对应),{64bit}则用于消息树节非根点异或计算。

每生成一个64位msgid,则与{64bit}异或计算一次,直到该消息确认处理完成后,再与{64bit}异或计算一次。(异或计算结果为新的{64bit}值)

{64bit}==0时,表示消息处理完毕。(一目了然,在此不再证明)

Storm消息可靠处理机制的更多相关文章

  1. Storm-6 Storm的并行度、Grouping策略以及消息可靠处理机制简介

    概念: 配置并行度 动态的改变并行度 流分组策略----Stream Grouping 消息的可靠处理机制 概念: Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程.一 ...

  2. Storm的并行度、Grouping策略以及消息可靠处理机制简介

    转自:https://my.oschina.net/zc741520/blog/409949 概念: Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程.一个Topolo ...

  3. Storm消息可靠机制

    一:介绍 1.介绍 默认情况是,Spout每获取一条数据,封装后发送给后面的组件,不再管后面是否处理完成或成功接收,不再考虑. 这种的情况是不用太精确,没有启用可靠性消息机制. 2.方面的体现 spo ...

  4. Storm消息容错机制(ack-fail机制)

    storm消息容错机制(ack-fail) 1.介绍 在storm中,可靠的信息处理机制是从spout开始的. 一个提供了可靠的处理机制的spout需要记录他发射出去的tuple,当下游bolt处理t ...

  5. IM消息送达保证机制实现(二):保证离线消息的可靠投递

    1.前言 本文的上篇<IM消息送达保证机制实现(一):保证在线实时消息的可靠投递>中,我们讨论了在线实时消息的投递可以通过应用层的确认.发送方的超时重传.接收方的去重等手段来保证业务层面消 ...

  6. ActiveMQ的JMS消息可靠机制

    JMS消息可靠机制 ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成 ...

  7. Storm系列三: Storm消息可靠性保障

    Storm系列三: Storm消息可靠性保障 在上一篇 Storm系列二: Storm拓扑设计 中我们已经设计了一个稍微复杂一点的拓扑. 而本篇就是在上一篇的基础上再做出一定的调整. 在这里先大概提一 ...

  8. Storm内部的消息传递机制

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 一个Storm拓扑,就是一个复杂的多阶段的流式计算.Storm中的组件 ...

  9. 【RabbitMQ】如何进行消息可靠投递【上篇】

    说明 前几天,突然发生线上报警,钉钉连发了好几条消息,一看是RabbitMQ相关的消息,心头一紧,难道翻车了? [橙色报警] 应用[xxx]在[08-15 16:36:04]发生[错误日志异常],al ...

随机推荐

  1. windows_xp下卸载office2003报无法打开此修补程序包错误

    今天在给公司一同事装完xp系统后.准备卸载预安装的Microsoft office2003,然后安装Microsoft office2007.结果在卸载office2003时报如下错误. 经过上网查询 ...

  2. Shell while

    while commanddo ...done c=0while [ $c -lt 5 ]do c='expr $c+1' echo $cdone

  3. Laravel 查询包括软删除的记录

    查询结果包括已被软删除的记录: Model::withTrashed()->get(); 只查询软删除记录: Model::onlyTrashed()->get(); PS:个人博客-La ...

  4. T49

    明天参加媳妇朋友的婚礼.今天晚上的火车,下班后匆忙的打了个的,正好到的哥交接班的时间拦了几辆车都不拉火车站!无奈-五分钟后打上车接上媳妇去火车站!正值五中学生放假路上各种堵!安阳这四线城市什么时候变的 ...

  5. 基础知识系列☞C#中→委托

    有些.NET中的高级特性,比如:委托! 有一种怎么也搞不懂的赶脚... 博客读了好几篇,代码也动手写了,书中的一些介绍也看了, 各种搜索关于委托的,至今还处于"会用"的阶段. 该怎 ...

  6. ZH奶酪:JavaScript调用AngularJS的函数/$scope/变量

    使用背景: 需要在其他JavaScript文件中调用AngularJS内部方法或改变$scope变量,同时还要保持双向数据绑定: 首先获取AngularJS application: 方法一:通过co ...

  7. linux下pip安装pygame

    在学习python的过程中要用到pygame,在安装过程中遇到一些问题,经百度解决.因为使用的版本为python3,故以下教程针对python3版本.安装教程如下: 一.首先你要确保你已经安装了pip ...

  8. Spring 对JDBC操作的支持

    1.Spring 对JDBC操作的支持 Spring对jdbc技术提供了很好的支持,体现在: 1.Spring对c3p0连接池的支持很完善 2.Spring对jdbc提供了jdbcTemplate,来 ...

  9. Oracle性能优化之普通用户使用dbms_xplan包需要有的权限

    普通用户使用dbms_xplan包查看执行计划需要对v$sql.v$sql_plan.v$session及v$sql_plan_statistics_all这四个视图同时具有select权限. 如果普 ...

  10. python数据结构之动态数组

    数组列表:动态数组(Array List) 简介: 最基础简单的数据结构.最大的优点就是支持随机访问(O(1)),但是增加和删除操作效率就低一些(平均时间复杂度O(n)) 动态数组也称数组列表,在py ...