最近碰到一个storm的坑, 两个bolt都需要从kafkaSpout中获取数据进行各自的业务处理, bolt1的处理是幂等的, bolt2的处理是非幂等的, 上线后发现非幂等的bolt处理总是会处理两次, 代码如下:

//创建拓扑作业
TopologyBuilder builder = new TopologyBuilder(); //1. 创建Spout,负责时间调度
builder.setSpout("timeSpout", new TimeScheduleSpout(60 * 60), 1); //2. 创建Spout,从Kafka中读取信息,流ID:RcKafkaSpout builder.setSpout("RcKafkaSpout", new KafkaSpout(spoutConfig), RiskControllConfig.getInt(StormConfig.STORM_SPOUT_PARALLELISM_HINT, 1)); //3. 创建Bolt,处理Kafka中读取的信息, redis计数,流ID:RcAnalyzeBolt builder.setBolt("RcAnalyzeBolt", new RcAnalyzeBolt(), RiskControllConfig.getInt(StormConfig.STORM_BOLT1_PARALLELISM_HINT, 1)).allGrouping("RcKafkaSpout").allGrouping("timeSpout");//非幂等的叠加操作 //4. 创建Bolt,将处理的结果存储至Redis builder.setBolt("RcAggregateBolt", new RcAggregateBolt(), RiskControllConfig.getInt(StormConfig.STORM_BOLT2_PARALLELISM_HINT, 1)).shuffleGrouping("RcAnalyzeBolt"); //5. 更新用户已完成订单金额的bolt
builder.setBolt("LastOrderBolt", new LastOrderBolt(), RiskControllConfig.getInt(StormConfig.STORM_BOLT1_PARALLELISM_HINT, 1)).allGrouping("RcKafkaSpout");//幂等的hbase put操作

红色位置即为bug, 错误原因是对 storm 消息分发策略的理解有问题

徐明明的博客在这一点上讲的有点误导: http://xumingming.sinaapp.com/117/twitter-storm%E7%9A%84%E4%B8%80%E4%BA%9B%E5%85%B3%E9%94%AE%E6%A6%82%E5%BF%B5/

All Grouping: 广播发送, 对于每一个tuple, 所有的Bolts都会收到。

实际上, 官网的解释如下:

http://storm.apache.org/documentation/Concepts.html

All grouping: The stream is replicated across all the bolt's tasks. Use this grouping with care

应该是对于每个tuple, 所有Bolt的所有task(也就是线程)都会收到, 也就意味着, 如果你的并行度设置>1, 则每个tuple会被bolt处理N次

allgrouping, 一般用于全局的数据同步和共享才需要, 比如全局的配置更新等, 比如上面的用于定时更新缓存数据的timeSpout, 我们就使用的是allgrouping方式

Storm bolt重复消费问题解决的更多相关文章

  1. KafkaSpout 重复消费问题解决

    使用https://github.com/nathanmarz/storm-contrib来对接Kafka0.7.2时, 发现kafkaSpout总会进行数据重读, 配置都无问题, 也没报错 进行de ...

  2. Kafka消息保证不丢失和重复消费问题

    使用同步模式的时候,有3种状态保证消息被安全生产,在配置为1(只保证写入leader成功)的话,如果刚好leader partition挂了,数据就会丢失.还有一种情况可能会丢失消息,就是使用异步模式 ...

  3. Kafka重复消费和丢失数据研究

    Kafka重复消费原因 底层根本原因:已经消费了数据,但是offset没提交. 原因1:强行kill线程,导致消费后的数据,offset没有提交. 原因2:设置offset为自动提交,关闭kafka时 ...

  4. Spring Cloud Stream如何处理消息重复消费?

    最近收到好几个类似的问题:使用Spring Cloud Stream操作RabbitMQ或Kafka的时候,出现消息重复消费的问题.通过沟通与排查下来主要还是用户对消费组的认识不够.其实,在之前的博文 ...

  5. kafka consumer重复消费问题

    在做分布式编译的时候,每一个worker都有一个consumer,适用的kafka+zookeep的配置都是默认的配置,在消息比较少的情况下,每一个consumer都能均匀得到互不相同的消息,但是当消 ...

  6. kafka丢失和重复消费数据

    Kafka作为当下流行的高并发消息中间件,大量用于数据采集,实时处理等场景,我们在享受他的高并发,高可靠时,还是不得不面对可能存在的问题,最常见的就是丢包,重发问题. 1.丢包问题:消息推送服务,每天 ...

  7. 程序重启RocketMQ消息重复消费

    最近在调试RocketMQ消息发送与消费的Demo时,发现一个问题:只要重启程序,RocketMQ消息就会重复消费. 那么这是什么原因导致的,又该如何解决呢? 经过一番排查,发现程序使用的Rocket ...

  8. 【消息队列】kafka是如何保证消息不被重复消费的

    一.kafka自带的消费机制 kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offs ...

  9. r-mq实现顺序消费,不重复消费

    根据订单号,同一订单号的消息,会被发送到同一个topic下的同一个queue,发送端的有序,会导致topic中消息的有序,而consumer和queue是一对多?的关系.可以保证topic中的有顺序的 ...

随机推荐

  1. Python内置函数之sorted()

    sorted(iterable,*,key=None,reverse=False) 对可迭代对象进行排序,默认ASCII进行排序. 例子: sorted(iterable,*,key=None,rev ...

  2. CSRF--花式绕过Referer技巧

    CSRF遇到Referer绕过的情况,有条件限制,不一定所有的Refere验证就可以绕过 1.Refere为空条件下 解决方案: 利用ftp://,http://,https://,file://,j ...

  3. 初始化map和list的两种写法

    第一种方法(常用方法): //初始化List List list = new ArrayList(); list.add("string1"); list.add("st ...

  4. centos 7 安装 mail

    yum install -y sendmail 将下面内容粘贴到/etc/mail.rc中 set ssl-verify=ignore set nss-config-dir=/root/.certs ...

  5. 【Selenium + Python】自动化测试之发送邮件正文以及附件同时发送

    废话不多说,直接上代码: import unittest import time import os import smtplib from HTMLTestRunner import HTMLTes ...

  6. 探究 Redis 4 的 stream 类型

    redis 2 10 月初,Redis 搞了个大新闻.别紧张,是个好消息:Redis 引入了名为 stream 的新数据类型和对应的命令,大概会在年底正式发布到 4.x 版本中.像引入新数据类型这样的 ...

  7. java学习日历输出(一)

    import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.GregorianCalendar; i ...

  8. 杭电OJ(HDU)-ACMSteps-Chapter Three-《FatMouse' Trade》《今年暑假不AC》《排名》《开门人和关门人》

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Fpc2luaV92Yw==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  9. JS 创建对象(常见的几种方法)

    贴个代码先: function O(user,pwd){ //use constructor this.user=user; this.pwd=pwd; this.get=get; return th ...

  10. mac查看网页时翻页

    1 fn + 上下  翻页 2 command + 上下  一下子到文档头和文档尾部