kafka如何保证数据的消息不丢失(最简洁)
一、kafka 本身配置层面
1.1、replication.factor 默认值1
创建kafka的topic时候,每个分区设置的副本数, 根据broker数量酌情设置, 建议业界通常做法设置为3
1.2、min.insync.replicas 默认值1
消息至少要被写入到min.insync.replicas这么多副本才算成功时候,通常使用小于replication.factor,当request.required.acks = all时生效
二、kafka的生产者层面
2.1、设置副本确认
request.required.acks 有3个取值,分别是0,1,all
0:表示无需等待broker确认就认为写入成功,风险大,一般不使用
1:表示当leader确认写入成功就认为成功了,有数据丢失风险,不建议使用
all:leader和follower都确认写入成功,才能认为是写入成功了,推荐使用(-1在新版本已弃用)
2.2、设置重试次数
retries 默认值0,不重试。kafka返回写入消息失败,生产者进行重新发送,直到成功, 根据业务合理设置重试次数
2.3、消息补偿机制
虽设置了重试次数,但不可能一直重试,如重试3次后仍然失败,这时候可把失败消息放入本地消息表,用定时任务轮询消息表, 重新生产推送到kafka
三、kafka的消费者层面
3.1 关闭自动 offset
设置 enable.auto.commit = false , 默认值true,自动提交
3.2 手动提交offset
使用kafka的Consumer的类,用方法consumer.commitSync()提交
或者使用spring-kafka的 Acknowledgment类,用方法ack.acknowledge()提交(推荐使用
第二:如何确保消息成功地发送至 MQ?
1. 实现:提交事务。 channel.txSelect:用于将当前的信道设置成事务模式、channel.txCommit:用于提交事务、channel.txRollback:用于回滚事务
2. 实现: 发送方确认模式(publisher confirm)。(即信道设置成confirm模式): channel.confirmSelect();将信道设置成confirm模式。
一旦信道进入confirm模式,所有在该信道上面发布的消息都会被指派一个唯一的ID(从1开始),
一旦消息被投递到RabbitMQ服务器之后,RabbitMQ就会发送一个确认(Basic.Ack)给生产者(包含消息的唯一ID),
这就使得生产者知晓消息已经正确到达了目的地了。如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。
性能比较:
可以看出,事务机制最慢,使用事务机制会“吸干”RabbitMQ的性能。 普通confirm机制虽有提升但是不多,
批量confirm和异步confirm性能最好,大家可以根据自己喜好自行选择使用哪种机制,个人建议使用异步confirm机制。
第三:如何确保消息接收方消费了消息MQ?
消息确认模式有:
AcknowledgeMode.NONE:自动确认
AcknowledgeMode.AUTO:根据情况确认
AcknowledgeMode.MANUAL:手动确认
1.消息通过 ACK 确认是否被正确接收,每个 Message 都要被确认(acknowledged),可以手动去 ACK 或自动 ACK
2.自动确认会在消息发送给消费者后立即确认,但存在丢失消息的可能,如果消费端消费逻辑抛出异常,也就是消费端没有处理成功这条消息,那么就相当于丢失了消息。
3.如果消息已经被处理,但后续代码抛出异常,使用 Spring 进行管理的话消费端业务逻辑会进行回滚,这也同样造成了实际意义的消息丢失
4.如果手动确认则当消费者调用 ack、nack、reject 几种方法进行确认,手动确认可以在业务失败后进行一些操作,如果消息未被 ACK 则会发送到下一个消费者。
5.如果某个服务忘记 ACK 了,则 RabbitMQ 不会再发送数据给它,因为 RabbitMQ 认为该服务的处理能力有限。
第四:如何保证MQ消息的可靠传输?
以我们常用的RabbitMQ为例,
丢失又分为:生产者丢失消息、消息队列丢失消息、消费者丢失消息;
1. 生产者丢失消息:从生产者弄丢数据这个角度来看,RabbitMQ提供confirm模式来确保生产者不丢消息;
2. 消息队列RabbitMQ丢数据:消息持久化。就是消息写入之后会持久化到磁盘。
持久化可以跟生产者那边的 confirm 机制配合起来,只有消息被持久化到磁盘之后,
才会通知生产者 ack 了,所以哪怕是在持久化到磁盘之前,RabbitMQ 挂了,数据丢了,
生产者收不到 ack,你也是可以自己重发的。
3. 消费端弄丢了数据:关闭 RabbitMQ 的自动ack可以通过一个api来调用就行,每次代码里确保处理完的时候,再在程序里ack一把。
第五:如何避免消费者手动ack失败,导致该消息会阻塞在队列中,后续的消息也会被阻塞住导致消息无法消费?
针对:rabbitMQ
rabbitMQ提供配置参数来开启消费者重试机制,也能配置配置最大重试次数和重试间隔时间,
rabbitMQ对于消息消费失败达到一定次数后,就会放弃该消息,
我们可以手动实现,如果消费失败达到最大重试次数后,将数据转发到死信队列上,
由死信队列的消费者来实现消息的持久化到数据库或者日志文件中,一般重试次数我们设置为3此,间隔时间为5s。
第六:Kafka中如何实现死信队列&重试队列?
死信队列: 当一条消息初次消费失败,消息队列 MQ 会自动进行消息重试;达到最大重试次数后,若消费依然失败,
则表明消费者在正常情况下无法正确地消费该消息,此时,消息队列 MQ 不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中,
这种正常情况下无法被消费的消息称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue)。
回退队列: 与此对应的还有一个“回退队列”的概念,试想如果消费者在消费时发生了异常,那么就不会对这一次消费进行确认(Ack),
进而发生回滚消息的操作之后消息始终会放在队列的顶部,然后不断被处理和回滚,导致队列陷入死循环。为了解决这个问题,
可以为每个队列设置一个回退队列,它和死信队列都是为异常的处理提供的一种机制保障。实际情况下,回退队列的角色可以由死信队列和重试队列来扮演。
重试队列: 其实可以看成是一种回退队列,具体指消费端消费消息失败时,为防止消息无故丢失而重新将消息回滚到Broker中。
与回退队列不同的是重试队列一般分成多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大。
Kafka不支持重试机制也就不支持消息重试,也不支持死信队列,
因此使用kafka做消息队列时,如果遇到了消息在业务处理时出现异常的场景时,需要额外实现消息重试的功能。
demo举例: https://artisan.blog.csdn.net/article/details/113846000
如果不想自己实现消息重试机制,建议使用RocketMQ作为消息队列,RocketMQ的消息重试机制相当完善,
详见: https://help.aliyun.com/document_detail/43490.html
第七:如何避免MQ消息重复投递或重复消费?
关键在于消息处理逻辑的幂等性,也就是说同一条消息无论被消费多少次,产生的结果和消息被消费一次是一样的.
(1)比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update一下好吧,(或者inSertIgnore有就更新,没有就插入)
(2)比如你是写redis,那没问题了,反正每次都是set,天然幂等性
(3)业务发送方带入唯一UUID,订单id做,消费方用唯一标示去查询,status作为标示是否处理过。
第八:如何保证消息的顺序性?
一个消费者对应一个队列,并且确保需要保证顺序的消息路由在同一个队列中。
kafka如何保证数据的消息不丢失(最简洁)的更多相关文章
- Kafka如何保证数据不丢失
Kafka如何保证数据不丢失 1.生产者数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有0,1,-1. 如果是 ...
- [转帖]kafka 如何保证数据不丢失
kafka 如何保证数据不丢失 https://www.cnblogs.com/MrRightZhao/p/11498952.html 一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数 ...
- Spark Streaming和Kafka整合保证数据零丢失
当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源 ...
- kafka 如何保证数据不丢失
一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失 b ...
- kafka如何保证数据可靠性和数据一致性
数据可靠性 Kafka 作为一个商业级消息中间件,消息可靠性的重要性可想而知.本文从 Producter 往 Broker 发送消息.Topic 分区副本以及 Leader 选举几个角度介绍数据的可靠 ...
- 如何保证RabbitMQ的消息不丢失及其背后的原理
一.消息为什么丢失 RabbitMQ默认情况下的交换机和队列以及消息是非持久化的,也就是说在服务器重启或者宕机恢复后,之前创建的交换机和队列都将不复存在,之前未消费的消息也就消失不见了.原因在于每个队 ...
- Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?
1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的 ...
- Kafka如何保证消息不丢失不重复
首先需要思考下边几个问题: 消息丢失是什么造成的,从生产端和消费端两个角度来考虑 消息重复是什么造成的,从生产端和消费端两个角度来考虑 如何保证消息有序 如果保证消息不重不漏,损失的是什么 大概总结下 ...
- kafka保证数据不丢失机制
kafka如何保证数据的不丢失 1.生产者如何保证数据的不丢失:消息的确认机制,使用ack机制我们可以配置我们的消息不丢失机制为-1,保证我们的partition的leader与follower都保存 ...
- 大数据平台消息流系统Kafka
Kafka前世今生 随着大数据时代的到来,数据中蕴含的价值日益得到展现,仿佛一座待人挖掘的金矿,引来无数的掘金者.但随着数据量越来越大,如何实时准确地收集并分析如此大的数据成为摆在所有从业人员面前的难 ...
随机推荐
- Android学习day01【搭建Android Studio】
是Google开发的操作系统 Android开发是移动应用开发的表现形式之一 还有很多的开发形式,就不一一列举了 完整项目精简的开发流程 开发工具 Android studio(强烈建议) Andro ...
- 七天.NET 8操作SQLite入门到实战 - 第四天EasySQLite前后端项目框架搭建
前言 今天的主要任务是快速下载并安装.NET 8 SDK,搭建EasySQLite的前后端框架. .NET 8 介绍 .NET 8 是 .NET 7 的后继版本. 它将作为长期支持 (LTS) 版本得 ...
- C++ 共享内存ShellCode跨进程传输
在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码.为了增加攻击的难度,研究人员经常探索新的传递ShellCode的方式.本文介绍了一种使用共享内存的方法,通过该方法,两 ...
- antd Pro组件ProFormList实现自定义action
antd Pro组件ProFormList实现自定义action ProFormList是ant design pro的结构化数据组件,通常用来实现动态表单. 现在有个需求,除了组件自带的删除和复制, ...
- SpringBoot设置日志级别
输出到控制台 logging: # 日志记录到文件中 file: # 指定文件名 name: server.log logback: rollingpolicy: # 指定文件大小 max-file- ...
- 如何使用sharding-sphere完成读写分离和分库分表?
一.sharding-sphere配置读写分离 1.先搭建好一个MySQL的主从集群,可以参考[MySQL主从集群搭建] 2.在项目中导入相关依赖(记得刷新Maven) <!--读写分离--&g ...
- 【.NET】控制台应用程序的各种交互玩法
老周是一个不喜欢做界面的码农,所以很多时候能用控制台交互就用控制台交互,既方便又占资源少.有大伙伴可能会说,控制台全靠打字,不好交互.那不一定的,像一些选项类的交互,可以用键盘按键(如方向键),可比用 ...
- 关于Secure Hash Algorithm加密算法
一.概述 SHA(Secure Hash Algorithm)加密算法是一种广泛应用的密码散列函数,由美国国家安全局(NSA)设计,用于保障数据的安全性和完整性.SHA算法经历了多个版本的更新,目前主 ...
- 深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs
通过这篇文章你可以了解到 Docker 容器的核心实现原理,包括 Namespace.Cgroups.Rootfs 等三个核心功能. 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎 ...
- SpringBoot 接口:响应时间优化9个技巧!
今天聊聊 SpringBoot接口:响应时间优化的9个技巧.在实际开发中,提升接口响应速度是一件挺重要的事,特别是在面临大量用户请求的时候.好了,咱们直接切入正题. 本文,已收录于,我的技术网站 dd ...