一、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如何保证数据的消息不丢失(最简洁)的更多相关文章

  1. Kafka如何保证数据不丢失

    Kafka如何保证数据不丢失 1.生产者数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有0,1,-1. 如果是 ...

  2. [转帖]kafka 如何保证数据不丢失

    kafka 如何保证数据不丢失 https://www.cnblogs.com/MrRightZhao/p/11498952.html   一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数 ...

  3. Spark Streaming和Kafka整合保证数据零丢失

    当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源 ...

  4. kafka 如何保证数据不丢失

    一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失  b ...

  5. kafka如何保证数据可靠性和数据一致性

    数据可靠性 Kafka 作为一个商业级消息中间件,消息可靠性的重要性可想而知.本文从 Producter 往 Broker 发送消息.Topic 分区副本以及 Leader 选举几个角度介绍数据的可靠 ...

  6. 如何保证RabbitMQ的消息不丢失及其背后的原理

    一.消息为什么丢失 RabbitMQ默认情况下的交换机和队列以及消息是非持久化的,也就是说在服务器重启或者宕机恢复后,之前创建的交换机和队列都将不复存在,之前未消费的消息也就消失不见了.原因在于每个队 ...

  7. Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

    1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的 ...

  8. Kafka如何保证消息不丢失不重复

    首先需要思考下边几个问题: 消息丢失是什么造成的,从生产端和消费端两个角度来考虑 消息重复是什么造成的,从生产端和消费端两个角度来考虑 如何保证消息有序 如果保证消息不重不漏,损失的是什么 大概总结下 ...

  9. kafka保证数据不丢失机制

    kafka如何保证数据的不丢失 1.生产者如何保证数据的不丢失:消息的确认机制,使用ack机制我们可以配置我们的消息不丢失机制为-1,保证我们的partition的leader与follower都保存 ...

  10. 大数据平台消息流系统Kafka

    Kafka前世今生 随着大数据时代的到来,数据中蕴含的价值日益得到展现,仿佛一座待人挖掘的金矿,引来无数的掘金者.但随着数据量越来越大,如何实时准确地收集并分析如此大的数据成为摆在所有从业人员面前的难 ...

随机推荐

  1. SpringCore完整学习教程6,入门级别

    本章从第7章开始: 7. Task Execution and Scheduling 在上下文中没有Executor bean的情况下,Spring Boot会自动配置一个ThreadPoolTask ...

  2. 36. 干货系列从零用Rust编写负载均衡及代理,内网穿透中内网代理的实现

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...

  3. 使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理

    在前面随笔<在Winform应用中增加通用的业务编码规则生成>,我介绍了基于Winform和WPF的一个通用的业务编码规则的管理功能,本篇随笔介绍基于后端Web API接口,实现快速的Vu ...

  4. DRF过滤器

    https://www.django-rest-framework.org/api-guide/filtering 一般情况下,我们可以重写DRF视图类的get_queryset()方法来实现查询结果 ...

  5. 【笔记整理】request模块基本使用

    基本使用 发送get请求.获取响应各种请求.响应信息 def fun1(): url = "http://www.baidu.com" resp = requests.get(ur ...

  6. 深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs

    通过这篇文章你可以了解到 Docker 容器的核心实现原理,包括 Namespace.Cgroups.Rootfs 等三个核心功能. 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎 ...

  7. Javascript Ajax总结——跨域资源共享

    XHR对象只能访问与包含它的页面位于同一个中的资源.这种安全策略可以预防某些恶意行为.CORS(Cross-Origin Resource Sharing,跨域资源共享)是W3C的一个工作草案,定义了 ...

  8. 在WInform开发中实现工具栏/菜单的动态呈现

    在Winform系统开发中,为了对系统的工具栏/菜单进行动态的控制,我们对系统的工具栏/菜单进行动态配置,这样可以把系统的功能弹性发挥到极致.通过动态工具栏/菜单的配置方式,我们可以很容易的为系统新增 ...

  9. 基于源码去理解Iterator迭代器的Fail-Fast与Fail-Safe机制

    原创/朱季谦 在Java编程当中,Iterator迭代器是一种用于遍历如List.Set.Map等集合的工具.这类集合部分存在线程安全的问题,例如ArrayList,若在多线程环境下,迭代遍历过程中存 ...

  10. 生产升级JDK 17 必读手册

    原文点这里,查看更多优质文章 DK 17 在 2021 年 9 月 14 号正式发布了!根据发布的规划,这次发布的 JDK 17 是一个长期维护的版本(LTS). Java 17 提供了数千个性能.稳 ...