Storm容错机制(一):ACK机制

前言

好久没有写文章了,然后一连就写了三篇,
前两篇文章
Storm入门(一):编程模型
Storm入门(二):架构模型和集群部署
都是一些比较简单的入门教程,这一篇我们来聊一聊稍微高级点的话题,
关于 Storm 的 ACK 机制。

不过话又说回来,其实大数据领域,该机制还是显得比较鸡肋的!!!

ACK机制有什么用?

我们知道 Storm 是一个常驻服务,消息源源不断的来,他源源不断的处理,那肯定在有些情况下会导致消息的不正确处理,比如worker进程挂掉了,那么正在被处理的消息很可能就会丢失掉,那么该如何解决这个问题呢?这时候我们就可以引入 ACK 机制了,当消息没有被正确处理时,可以通过 ACK机制 重新发送该消息进行处理。

当然,大多数时候,一条两条数据的异常,并不在我们的考虑范围内,所以并不是所有任务都要引入 ACK 机制

开启 ACK 机制

  • 首先我们来看看如何开启 ACK 机制:
  1. spout 发送 tuple 的时候需要指定该消息的 messageId
    SpoutOutputCollector.emit(List<Object> tuple, Object messageId)
  2. spout要重写BaseRichSpout的fail和ack方法
 static class MySpout extends BaseRichSpout {
        @Override
        public void fail(Object msgId) {
          //消息失败的时候回回调到这个方法
        }

        @Override
        public void ack(Object msgId) {
          //消息成功执行的时候回回调到这个方法
        }
    }

你可能已经发现这两个回调的参数是 msgId,而不是你发送的 message,所以这个时候需要我们自己在发送数据的时候维护一个缓存,在 ack 回调里面移除, 在 fail 里面重发。

  1. Bolt 发送消息的时候需要将原消息当做 anchor 发送
    OutputCollector.emit(Tuple anchor, List<Object> tuple)
  2. 设置acker数至少大于0:
    Config.setNumAckers(1);
  • 通过上面三步我们就可以开启 ACK机制了,不过这里需要注意的是:
    如果启用 ACK机制,我们可以采用 IBasicBolt 接口下的 BaseBasicBolt 而不是 IRichBolt接口下的BaseRichBolt
    该 Bolt 会自动进行 ACK 的发送 和 anchor的关联,这样就省得我们忘记添加ACK,使得ACK无法正确运行

上面介绍了如何开启一个 ACK,实际上我们也看到了,ACK机制的控制是精确到了 message 的,比如我们Spout 发送这个 message 的时候不指定其 messageId,那么这个message 的数据流就不会被 ACK,

ACK 原理

  • 知道如何使用ACK了,那么我们现在一起来看下 ACK的是怎么实现的吧!!!

    1. 首先我们在开启ACK机制的时候设置了 Config.setNumAckers(1),其实就是开启了一个 ACKER 的task,
      ACKER 会负责跟踪 spout 发出的每一个数据流
    2. 我们在 Bolt 中的每次 ack()调用就是向 ACKER 汇报本次执行任务结果,ACKER 接受到数据之后会判断该任务是否执行完毕
    3. 如果执行完毕,ACKER 会向Spout 汇报说该消息执行完毕,这个时候 Spout就会通过我们重写的 ack 方法让我们处理成功的逻辑
    4. 如果执行失败,或者很长一段时间 (Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS可以设置这个时间还) 没有收到 ACKER 的汇报,那么Spout就认为该任务失败了,会通过fail方法告诉我们处理失败的逻辑

    看完这个原理,我想你大概也知道了这个 ACK机制 其实并无法保证数据有且只有一次被消费,他只能保证你的数据至少被消费一次,很可能会重复消费。

  • 这里还有一个问题就是 ACKER 是如何判断 一个消息被处理完成的呢?这里 Storm 使用了一个比较巧妙的方法,下面我们就来说一下这个 判断的机制

    1. 首先我们需要知道一点:任意值 异或 同一个值两次,还是其本身,比如 10^3^3 还是 10
    2. ACKER 实际上会为每个 message 生成一个ack-val,初始值为 0。(注意这个message,这也是个坑,一个消息进来后,可能产生多个数据流,当某个数据流失败后,却要重试整个message所有的流),每执行一个 task,即spout或者 bolt 每次执行完毕,会向 ACKER 汇报其 输入Tuple生成Tuple,ACKER会将其本身的ack-val 异或 输入Tuple的id 再异或 生成Tuple的id 生成一个新的 ack-val
    3. 下面为了方便理解,我们举个小例子如下图:


      image.png
    • 假设我们现在有一个message 发送过来了,通过 Spout 生成A1 和 A2 两个touple 分别发送给 BoltA1,BoltB1.最后BoltA1 和 BoltB1将数据汇聚到 bolt。
      那么这个 ACKER 的判断过程大概就是这样:

      1. spout 发送 到 A1 和 B1 的时候:ack_val =0^A1^B1
      2. A1 通过 boltA1 生成 A2,ack_val = ack_val ^(A1^A2)
      3. B1 通过 boltB1 生成 B2,ack_val = ack_val ^(B1^B2)
      4. 最后 B2 和 A2 汇聚到 bolt 的时候, ack_val = ack_val ^(B2^A2)

      最后我们把ack_val值的变化都写在一个公式,大概就是:0^A1^B1^(A1^A2)^(B1^B2)^(B2^A2),因为异或的性质,不难得出 最后的结果为 0 , 而当ack_val 重新变为0,ACKER就认为你这个数据已经处理完成了

      • 你可能需要注意的问题:
        1. 关于重试机制的控制,当一个消息处理失败,你可以重发它,它失败十次, 你还可以重发,但是百次千次呢?所以每个消息最好设置下最大重发次数。哈~~这个要你自己实现哈....Storm 没有提供相关的配置

        2. 消息重复问题,比如一个message有产生了两个数据流,其中一个成功,另外一个失败,当消息重发的时候,成功的那个数据可能就被计算了两次,所以对于结果数据如果有必要,需要进行相关的去重逻辑。至于这个去重,可以好好利用下 messageId。

        3. 如果你有补充,欢迎指教

好吧,ACK的讲解就到这里了,不知道有没有讲清楚,不过实际运用中并没有太大的用处,也可能只是我目前用的不多,基于对一门技术的热情,还是稍稍深入研究了一下,如有不对,欢迎指错

你的点赞是对作者最大的支持

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容