RocketMQ学习笔记(14)----RocketMQ的去重策略
1. Exactly Only Once
(1). 发送消息阶段,不允许发送重复的消息
(2). 消费消息阶段,不允许消费重复的消息。
只有以上两个条件都满足情况下,才能认为消息是“Exactly Only Once”,而要实现以上两点,在分布式系统环
境下,不可避免要产生巨大的开销。所以RocketMQ 为了追求高性能,并不保证此特性,要求在业务上进行去重,也就是说消费消息要做到幂等性。RocketMQ 虽然不能严格保证不重复,但是正常情况下很少会出现重复发送、消
费情况,只有网络异常,Consumer 启停等异常情况下会出现消息重复。
此问题的本质原因是网络调用存在不确定性,即既不成功也不失败的第三种状态,所以才产生了消息重复性问
题。
2. 重复消费的原因
在于回馈机制。正常情况下,消费者在消费消息时候,消费完毕后,会发送一个ACK确认信息给消息队列(broker),消息队列(broker)就知道该消息被消费了,就会将该消息从消息队列中删除。
不同的消息队列发送的确认信息形式不同,例如RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offset的概念。
造成重复消费的原因?,就是因为网络原因闪断,ACK返回失败等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者。(因为消息重试等机制的原因,如果一个consumer断了,rocketmq有consumer集群,会将该消息重新发给其他consumer)
3. 去重策略
去重原则:1.幂等性 2.业务去重
幂等性:(处理必须唯一) 无论这个业务请求被(consumer)执行多少次,我们的数据库的结果都是唯一的,不可变的。
去重策略:去重表机制,业务拼接去重策略(比如唯一流水号)
1.建立一个消息表,拿到这个消息做数据库的insert操作。给这个消息做一个唯一主键(primary key)或者唯一约束,那么就算出现重复消费的情况,就会导致主键冲突。
高并发下去重:采用Redis去重(key天然支持原子性并要求不可重复),但是由于不在一个事务,要求有适当的补偿策略,但是对于很重要的业务,不应该支持补偿
2.利用redis事务,主键(我们必须把全量的操作数据都存放在redis里,然后定时去和数据库做数据同步)—-即消费处理后,该处理本来应该保存在数据库的,先保存在redis,再通过一定业务方式从redis中取数据进行db持久化
3.利用redis和关系型数据库一起做去重机制
4.拿到这个消息做redis的set的操作.redis就是天然幂等性
5.准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将 < id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。
原文 RocketMQ学习笔记(14)----RocketMQ的去重策略
RocketMQ学习笔记(14)----RocketMQ的去重策略的更多相关文章
- 【rocketmq学习笔记】rocketmq入门学习
基本介绍 rocketmq是阿里巴巴团队使用java语言开发的一款基于发布订阅模型的分布式消息队列中间件,是一款低延迟,高可用,拥有海量消息堆积能力和灵活拓展性的消息队列. 特点 可以实现集群无单点故 ...
- RocketMQ学习笔记(15)----RocketMQ的消息模式
在前面学习ActiveMQ时,看到ActiveMQ可以是队列消息模式,也可以是订阅发布模式. 同样,在RocketMQ中,也存在两种消息模式,即是集群消费模式和广播消费模式. 1. 集群消费模式 跟A ...
- RocketMQ学习笔记(13)----RocketMQ的Consumer消息重试
1. 概念 Producer端重试: 生产者端的消息失败,也就是Producer往MQ上发消息没有发送成功,比如网络抖动导致生产者发送消息到MQ失败. 这种消息失败重试我们可以手动设置发送失败重试的次 ...
- RocketMQ学习笔记(16)----RocketMQ搭建双主双从(异步复制)集群
1. 修改RocketMQ默认启动端口 由于只有两台机器,部署双主双从需要四个节点,所以只能修改rocketmq的默认启动端口,从官网下载rocketmq的source文件,解压后使用idea打开,全 ...
- RocketMQ学习笔记(4)----RocketMQ搭建双Master集群
前面已经学习了RockeMQ的四种集群方式,接下来就来搭建一个双Master(2m)的集群环境. 1. 双Master服务器环境 序号 ip 用户名 密码 角色 模式 (1) 47.105.145.1 ...
- 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理
1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...
- Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法
Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...
- SQL反模式学习笔记14 关于Null值的使用
目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...
- golang学习笔记14 golang substring 截取字符串
golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...
随机推荐
- EXISTS 执行顺序 CLR-2-2-引用类型和值类型
EXISTS 执行顺序 select * from a where a.s_status=1 and exists (select orderid from b on a.orderid=b.or ...
- HDU5806 NanoApe Loves Sequence Ⅱ
NanoApe Loves Sequence Ⅱ Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Ja ...
- searchView 颜色 icon 设置
public void initSearchViewActions() { searchView.setMaxWidth(Integer.MAX_VALUE); searchView.onAction ...
- luogu 3388 【模板】割点(割顶)
点双. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> ...
- 【BJOI 2018】 求和
[题目链接] 点击打开链接 [算法] 预处理i^k的前缀和,对于每次询问,树上倍增即可 时间复杂度 : O(nk + mlog(n)) [代码] #include<bits/stdc++.h&g ...
- jsp中一行多条数据情况
1.实现效果:点击新增会在之前文本框后一直新增文本框并且保留新增的图片 效果图: 2.jsp代码: <table class="Business_Table"> < ...
- [入门帮助] Kafka入门经典教程
问题导读 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有 ...
- request.getRemoteAddr()和request.getRemoteHost()
转自:https://www.cnblogs.com/aizj/p/7593209.html request.getRemoteAddr()是获得客户端的ip地址.request.getRemoteH ...
- JEECG框架使用Tomcat启动报ClassNotFound
JEECG框架缺少一个类,名为AnnotationProcessor,包名为:org.apache package org.apache; import java.lang.reflect.Invoc ...
- recast 生成navmesh主要流程
参考: critterai http://www.critterai.org recast & Detour https://github.com/recastnavig ...