如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?


》幂等性,通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。
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 会再次传过来,如果此时消费者没有去重的话,那么就会导致重复消费。



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

Kafka 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?的更多相关文章

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

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

  2. Kafka如何保证百万级写入速度以及保证不丢失不重复消费

    一.如何保证百万级写入速度: 目录 1.页缓存技术 + 磁盘顺序写 2.零拷贝技术 3.最后的总结 “这篇文章来聊一下Kafka的一些架构设计原理,这也是互联网公司面试时非常高频的技术考点. Kafk ...

  3. 实际业务处理 Kafka 消息丢失、重复消费和顺序消费的问题

    关于 Kafka 消息丢失.重复消费和顺序消费的问题 消息丢失,消息重复消费,消息顺序消费等问题是我们使用 MQ 时不得不考虑的一个问题,下面我结合实际的业务来和你分享一下解决方案. 消息丢失问题 比 ...

  4. 《RabbitMQ》如何保证消息不被重复消费

    一 重复消息 为什么会出现消息重复?消息重复的原因有两个:1.生产时消息重复,2.消费时消息重复. 1.1 生产时消息重复 由于生产者发送消息给MQ,在MQ确认的时候出现了网络波动,生产者没有收到确认 ...

  5. RocketMQ 如何保证消息不丢失,重复消费

    RocketMQ 如何保证消息不丢失 Producer 提供SYNC的发送消息方式,等待broker处理结果. 发送消息如果失败或者超时,则重新发送. // 同步发送消息,如果5秒内没有发送成功,则重 ...

  6. RocketMQ(消息重发、重复消费、事务、消息模式)

    分布式开放消息系统(RocketMQ)的原理与实践 RocketMQ基础:https://github.com/apache/rocketmq/tree/rocketmq-all-4.5.1/docs ...

  7. 利用Kafka的Assign模式实现超大群组(10万+)消息推送

    引言 IM即时通信场景下,最重要的一个能力就是推送:在线的直接通过长连接网关服务转发,离线的通过APNS或者极光等系统进行推送.   本文主要是针对在线用户推送场景来进行总结和探讨:如何利用Kafka ...

  8. Disruptor多个消费者不重复处理生产者发送过来的消息

    1.定义事件事件(Event)就是通过 Disruptor 进行交换的数据类型. package com.ljq.disruptor; import java.io.Serializable; /** ...

  9. 初试kafka消息队列中间件二(采用java代码收发消息)

    初试kafka消息队列中间件二(采用java代码收发消息) 上一篇 初试kafka消息队列中间件一 今天的案例主要是将采用命令行收发信息改成使用java代码实现,根据上一篇的接着写: 先启动Zooke ...

  10. 消息队列(七)--- RocketMQ延时发送和消息重试(半原创)

    本文图片和部分总结来自于参考资料,半原创,侵删 问题 Rocketmq 重试是否有超时问题,假如超时了如何解决,是重新发送消息呢?还是一直等待 假如某个 msg 进入了重试队列(%RETRY_XXX% ...

随机推荐

  1. [GIT] 如何处理GIT分支合并(GIT MERGE)

    1 概述 2 分支合并 如果你有两个分支main和dev,main存放稳定版本,dev是开发版本,一个阶段后,你需要把dev代码更新到main分支中. dev --(merge update cont ...

  2. [Linux]常用命令之【systemctl/service/chkconfig/pstree】

    1 systemctl 1-0 systemctl 基本使用 systemctl start/stop/restart/status sshd systemctl enable/disable ssh ...

  3. 升级:Logical Upgrade升级MySQL5.6.26

    升级需谨慎,事前先备份 MySQL升级的实质是对数据字典的升级,数据字典有:sys.mysql.information_schema.performance_schema . MySQL升级的两种方式 ...

  4. Java学习笔记09

    1. 多态 1.1 多态 ​ 多态是指同一种行为具有多种不同的表现形式. 前提 有继承或者实现关系 有方法重写(没有重写多态就没有意义) 父类引用指向子类对象 格式 父类类型 变量名 = new 子类 ...

  5. c语言趣味编程(3)打鱼还是筛网

    一.问题描述 中国有句俗语叫"三天打鱼两天晒网".某人从1990年1月1日起开始"三天打鱼两天晒网",问这个人在以后的以后的某一天中是打鱼还是晒网. 二.设计思 ...

  6. 操作系统实验 & bochs 环境配置

    wsl2 - Ubuntu 22.04 + VSCode + bochs + xfce4 + VcXsrv 笔者环境 wsl2 - Ubuntu 22.04 0. 安装WSL2 & VSCod ...

  7. CF1808E Minibuses on Venus 智商毁灭记

    都要考省选了大脑还在这里下线 场上看到这道题很快推出了 \(k\) 为奇数的搞法,发现可以直接做到 \(O(k\log n)\),一阵狂喜然后肝起了 E3,结果 E1 都没过. 事实上这道题可以直接做 ...

  8. 微服务 - Nginx网关 · 进程机制 · 限流熔断 · 性能优化 · 动态负载 · 高可用

    系列目录: 微服务 - 概念 · 应用 · 通讯 · 授权 · 跨域 · 限流 微服务 - 集群化 · 服务注册 · 健康检测 · 服务发现 · 负载均衡 微服务 - Redis缓存 · 数据结构 · ...

  9. Node.js躬行记(28)——Cypress自动化测试实践

    最近在研究如何提升项目质量,提炼了许多个用于自测的测试用例,但是每次修改后,都手工测试,成本太高,于是就想到了自动化测试. 在一年前已将 Cypress 集成到管理后台的项目中,不过没有投入到实践中. ...

  10. MySQL 中读写分离数据延迟

    MySQL 中读写分离可能遇到的问题 前言 读写分离的架构 基于客户端实现读写分离 基于中间代理实现读写分离 MySQL 中如何保证主从数据一致 循环复制问题 主从同步延迟 主从同步延迟的原因 主从延 ...