首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【34期】如何保证消息不被重复消费?

【34期】如何保证消息不被重复消费?

作者头像
架构狂人
发布于 2023-09-21 12:37:55
发布于 2023-09-21 12:37:55
2280
举报
文章被收录于专栏:架构狂人架构狂人

面试官心理分析

其实这是很常见的一个问题,这俩问题基本可以连起来问。既然是消费消息,那肯定要考虑会不会重复消费?能不能避免重复消费?或者重复消费了也别造成系统异常可以吗?这个是 MQ 领域的基本问题,其实本质上还是问你使用消息队列如何保证幂等性,这个是你架构里要考虑的一个问题。

面试题剖析

回答这个问题,首先你别听到重复消息这个事儿,就一无所知吧,你先大概说一说可能会有哪些重复消费的问题。

首先,比如 RabbitMQ、RocketMQ、Kafka,都有可能会出现消息重复消费的问题,正常。因为这问题通常不是 MQ 自己保证的,是由我们开发来保证的。挑一个 Kafka 来举个例子,说说怎么重复消费吧。

Kafka 实际上有个 offset 的概念,就是每个消息写进去,都有一个 offset,代表消息的序号,然后 consumer 消费了数据之后,每隔一段时间(定时定期),会把自己消费过的消息的 offset 提交一下,表示“我已经消费过了,下次我要是重启啥的,你就让我继续从上次消费到的 offset 来继续消费吧”。

但是凡事总有意外,比如我们之前生产经常遇到的,就是你有时候重启系统,看你怎么重启了,如果碰到点着急的,直接 kill 进程了,再重启。这会导致 consumer 有些消息处理了,但是没来得及提交 offset,尴尬了。重启之后,少数消息会再次消费一次。

举个栗子。

有这么个场景。数据 1/2/3 依次进入 Kafka,Kafka 会给这三条数据每条分配一个 offset,代表这条数据的序号,我们就假设分配的 offset 依次是 152/153/154。消费者从 Kafka 去消费的时候,也是按照这个顺序去消费。假如当消费者消费了 offset=153 的这条数据,刚准备去提交 offset 到 Zookeeper,此时消费者进程被重启了。那么此时消费过的数据 1/2 的 offset 并没有提交,Kafka 也就不知道你已经消费了 offset=153 这条数据。那么重启之后,消费者会找 Kafka 说,嘿,哥儿们,你给我接着把上次我消费到的那个地方后面的数据继续给我传递过来。由于之前的 offset 没有提交成功,那么数据 1/2 会再次传过来,如果此时消费者没有去重的话,那么就会导致重复消费。

注意:新版的 Kafka 已经将 offset 的存储从 Zookeeper 转移至 Kafka brokers,并使用内部位移主题 __consumer_offsets 进行存储。

如果消费者干的事儿是拿一条数据就往数据库里写一条,会导致说,你可能就把数据 1/2 在数据库里插入了 2 次,那么数据就错啦。

其实重复消费不可怕,可怕的是你没考虑到重复消费之后,怎么保证幂等性。

举个例子吧。假设你有个系统,消费一条消息就往数据库里插入一条数据,要是你一个消息重复两次,你不就插入了两条,这数据不就错了?但是你要是消费到第二次的时候,自己判断一下是否已经消费过了,若是就直接扔了,这样不就保留了一条数据,从而保证了数据的正确性。

一条数据重复出现两次,数据库里就只有一条数据,这就保证了系统的幂等性。

幂等性,通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。

所以第二个问题来了,怎么保证消息队列消费的幂等性?

其实还是得结合业务来思考,我这里给几个思路:

  • 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
  • 比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
  • 比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
  • 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

当然,如何保证 MQ 的消费是幂等性的,在实际应用中需要结合具体的业务来看。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-19 07:30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 顶尖架构师栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
【最佳实践】巡检项:云数据库(Redis)跨可用区部署
相比于单可用区集群来说,腾讯云支持的多可用区集群提供更高的容灾能力,可有效的抵御可用区中断或者机房级别的故障。针对存量实例巡检发现的单可用区Redis集群,推荐升级至多可用区集群部署。
邵聪 SHAO CONG
2022/04/13
1.3K0
腾讯云数据库(Redis)监控最佳指南
简介 云数据库 Redis(TencentDB for Redis)是由腾讯云提供的兼容 Redis 协议的缓存数据库,具备高可用、高可靠、高弹性等特征。云数据库 Redis 服务兼容 Redis 2.8、Redis 4.0、Redis 5.0 版本协议,提供标准和集群两大架构版本。最大支持 4TB 的存储容量,千万级的并发请求,可满足业务在缓存、存储、计算等不同场景中的需求。 云数据库 Redis 的优势: 主从热备:提供主从热备,宕机自动监测,自动容灾。 数据备份:标准和集群架构数据持久化存储,可提供
腾讯云可观测平台
2021/01/08
5.2K0
【最佳实践】巡检项:云数据库(Redis)副本数达到上限 5 个
针对读多写少的业务场景,为解决热点数据的集中读需求,腾讯云Redis支持读写分离功能,最大1主5从模式,即最大5倍的读能力扩展。当集群中的副本数量已经达到5个上限时,不能再通过简单增加副本的方式来扩展读能力,因此建议通过分片数量扩展的方式来提升集群总体的读写能力,应对可能发生的业务请求增加。
邵聪 SHAO CONG
2022/04/18
1.1K0
【最佳实践】巡检项:云数据库(MongoDB)CPU 使用率
检查腾讯云数据库 MySQL 实例的 CPU 使用率情况,如果MongoDB实例的CPU使⽤率过⾼,会导致MonogoDB响应缓慢,甚⾄业务不可⽤。
ivesjiang@DBA
2022/04/07
1K0
【最佳实践】巡检项:云数据库(Redis)利用率不足
检查到云数据库Redis的资源利用率较低,如果业务生命周期已经稳定,并且没有增长的计划,可以适当调整实例的规格配置,降低成本。
邵聪 SHAO CONG
2022/04/21
1.7K1
Redis案例:热key导致实例CPU 100%
在Redis世界里,热key指的是那些在一段时间内访问频率特别高的键值,具体到业务场景,包括热点新闻、热门直播、秒杀活动等等。
brightdeng@DBA
2020/08/27
2.4K1
Redis案例:热key导致实例CPU 100%
史上最全腾讯云数据库(MongoDB)监控最佳实践
文章旨在通过对 MongoDB 监控指标的梳理和架构的分解,帮助广大的腾讯云 MongoDB 用户更好的通过监控告警及时发现业务异常,实时监控数据趋势。内容将会包括三个部分:
腾讯云可观测平台
2020/11/12
3.1K0
邹鹏:Redis数据库云端最佳技术实践
这次过来主要是和大家分享一下,腾讯云上个月正式上线的Redis4.0集群版的相关内容,跟大家分享我们在做集群版的时候有哪些思考,我们怎么去设计整个系统架构,最终我们做了哪些东西。大概会有三个点,第一个点是说Redis的使命,我们看Redis是什么产品,为什么这么火,第二块就是腾讯云Redis4.0集群设计经历了哪些思考,最终做成什么样子,最后是2018年年初,登录到腾讯云的自研兼容Redis协议的CKV引擎,他是怎么样的一个架构设计。
腾讯云开发者社区技术沙龙
2018/11/05
1.5K0
【最佳实践】巡检项:云数据库(MySQL)CPU 使用率
检查腾讯云数据库 MySQL 实例的 CPU 使用率情况,若使用率过高,可能会出现业务请求延迟增加,甚至无响应等风险。
王文安@DBA
2022/04/06
1K0
【最佳实践】巡检项:云数据库(MySQL)CPU 使用率
Redis最佳实践:7个维度+43条使用规范,带你彻底玩转Redis | 附实践清单
你的项目或许已经使用 Redis 很长时间了,但在使用过程中,你可能还会或多或少地遇到以下问题:
CSDN技术头条
2021/03/22
6.5K0
Redis最佳实践:7个维度+43条使用规范,带你彻底玩转Redis | 附实践清单
打开思路,数据库的全场景高可用性架构长什么样?
数据库是企业核心业务运行的重要组成部分,数据是企业的生命线,如果数据库出现宕机、数据丢失或不可用等问题,将会对企业的生产、营销和决策产生难以预估的影响,因此,一套高可用的数据库架构对于企业来说至关重要,可以最大化保证业务稳定性和数据可靠性。腾讯云MySQL推出全场景高可用性架构(All-Scenario High Availability Architecture,AS-HAA),用户可根据实际业务需求、业务类型自行配置。
腾讯云数据库 TencentDB
2023/07/25
4710
打开思路,数据库的全场景高可用性架构长什么样?
Redis数据库云端最佳技术实践
邹鹏,腾讯高级工程师,腾讯云数据库Redis负责人,多年数据库、网络安全研发经验。在网络、计算、存储、安全等领域有深入的研究和丰富的产品化经验。 在Redis、MySQL等数据库的高可用、高可靠和中间件方面有丰富的实践经验。
腾讯云数据库 TencentDB
2018/11/06
1.5K0
Redis数据库云端最佳技术实践
Redis - 高并发场景下的Redis最佳实践_翻过6座大山
在高并发系统中,Redis缓存通常被视为数据在存入数据库之前的重要中间层,其设计专注于缓存功能,性能往往比传统数据库高出一个数量级以上。以Redis单实例而言,其读取并发能力可达到10万QPS(官方理论值)。
小小工匠
2024/05/26
1.5K0
Redis - 高并发场景下的Redis最佳实践_翻过6座大山
Redis 生产架构选型解决方案
采用主从(master-replica)模式搭建。主节点提供日常服务访问,备节点提供HA高可用,当主节点发生故障,系统会自动在30秒内切换至备节点,保证业务平稳运行。
玄姐谈AGI
2021/07/29
3720
用Redis构建缓存集群的最佳实践有哪些?
Redis 从 3.0 版本开始,提供了官方的集群支持,也就是 Redis Cluser。Redis Cluster 相比于单个节点的 Redis,能保存更多的数据,支持更多的并发,并且可以做到高可用,在单个节点故障的情况下,继续提供服务。
码农架构
2020/10/26
1.2K0
用Redis构建缓存集群的最佳实践有哪些?
相比原生,腾讯云数据库MySQL 8.0带来了哪些新的极致体验?
官方MySQL 8.0 是非常大的版本,以前的版本号是 5.6、5.7,现在一下飞跃到 8.0,对于 Oracle MySQL官方来说也是非常大的版本,有很多的更新。
腾讯云开发者
2020/08/20
5.6K2
得物 Redis 设计与实践
自建 Redis 系统是得物 DBA 团队自研高性能分布式 KV 缓存系统,目前管理的 ECS 内存总容量超过数十TB,数百多个 Redis 缓存集群实例,数万多个 Redis 数据节点,其中内存规格超过 1T 的大容量集群多个。
得物技术
2023/10/27
8K2
得物 Redis 设计与实践
Redis认知-分布式系统中的单主怎么组建一个集群来抗高并发
1、Redis-Server:Redis服务端,用于存储用户数据的,此处就一个master节点【IP: 100.100.100.1:6379】
Janesong
2024/07/07
2140
Redis进阶学习10---redis最佳实践
当key可以转换为数字时,即key由数字组成,底层会编码为int,如果key长度小于44字节,采用embstr编码类型,否则采用非连续空间存储,为raw编码类型
大忽悠爱学习
2022/05/14
5840
Redis进阶学习10---redis最佳实践
Redis集群方案对比:Codis、Twemproxy、Redis Cluster
数据持久化本质上是为了做数据备份,有了数据持久化,当Redis宕机时,我们可以把数据从磁盘上恢复回来,但在数据恢复之前,服务是不可用的,而且数据恢复的时间取决于实例的大小,数据量越大,恢复起来越慢。Redis的持久化过程可以参考《Redis持久化是如何做的?》。
Java技术栈
2020/09/22
5.4K1
Redis集群方案对比:Codis、Twemproxy、Redis Cluster
推荐阅读
相关推荐
【最佳实践】巡检项:云数据库(Redis)跨可用区部署
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档