[Kafka 常见面试题]如何保证消息的不重复不丢失

简介: [Kafka 常见面试题]如何保证消息的不重复不丢失


Kafka

1. Kafka如何保证不丢失消息?

生产者数据的不丢失

  • 如果是同步模式:

ack机制能够保证数据的不丢失,如果ack设置为0,风险很大,一般不建议设置为0。即使设置为1,也会随着leader宕机丢失数据。

producer.type=sync 
request.required.acks=1
  • 如果是异步模式:

也会考虑ack的状态,除此之外,异步模式下的有个buffer,通过buffer来进行控制数据的发送,有两个值来进行控制,时间阈值与消息的数量阈值,如果buffer满了数据还没有发送出去,有个选项是配置是否立即清空buffer。可以设置为-1,永久阻塞,也就数据不再生产。异步模式下,即使设置为-1。也可能因为程序员的不科学操作,操作数据丢失,比如kill -9,但这是特别的例外情况。

producer.type=async
request.required.acks=1
queue.buffering.max.ms=5000
queue.buffering.max.messages=10000 
queue.enqueue.timeout.ms = -1 
batch.num.messages=200

结论:producer有丢数据的可能,但是可以通过配置保证消息的不丢失。

消费者数据的不丢失

通过 offset commit 来保证数据的不丢失,Kafka自己记录了每次消费的offset数值,下次继续消费的时候,会接着上次的offset进行消费。

而offset的信息在Kafka0.8版本之前保存在Zookeeper中,在0.8版本之后保存到topic中,即使消费者在运行过程中挂掉了,再次启动的时候会找到offset的值,找到之前消费消息的位置,接着消费,由于 offset的信息写入的时候并不是每条消息消费完成后都写入的,所以这种情况有可能会造成重复消费,但是不会丢失消息。

唯一例外的情况是,我们在程序中给原本做不同功能的两个consumer组设置

Kafka SpoutConfig.bulider.setGroupid的时候设置成了一样的 groupid,这种情况会导致这两个组共享同一份数据,就会产生组A消费 partition1,partition2 中的消息,组B消费 partition3 的消息,这样每个组消费的消息都会丢失,都是不完整的。 为了保证每个组都独享一份消息数据,groupid一定不要重复才行。

Kafka集群中的broker的数据不丢失

每个broker中的partition我们一般都会设置有replication(副本)的个数,生产者写入的时候首先根据分发策略(有partition按partition,有key按key,都没有轮询)写入到leader中,follower(副本)再跟leader同步数据,这样有了备份,也可以保证消息数据的不丢失。

2. Kafka中的消息是否会丢失和重复消费?

要确定Kafka的消息是否丢失或重复,从两个方面分析入手:消息发送和消息消费。

1. 消息发送

Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过 producer.type属性进行配置。

Kafka通过配置 request.required.acks属性来确认消息的生产:

0---表示不进行消息接收是否成功的确认;
1---表示当Leader接收成功时确认;
-1---表示Leader和Follower都接收成功时确认;

综上所述,有6种消息生产的情况,下面分情况来分析消息丢失的场景:

(1) acks=0,不和 Kafka 集群进行消息接收确认,则当网络异常、缓冲区满了等情况时,消息可能丢失;

(2) acks=1、同步模式下,只有Leader确认接收成功后但挂掉了,副本没有同步,数据可能丢失;

2. 消息消费

Kafka 消息消费有两个 consumer 接口,Low-level API 和 High-level API:

Low-level API:消费者自己维护 offset 等值,可以实现对 Kafka 的完全控制;

High-level API:封装了对 parition 和 offset 的管理,使用简单;

如果使用高级接口High-level API,可能存在一个问题就是当消息消费者从集群中把消息取出来、并提交了新的消息offset值后,还没来得及消费就挂掉了,那么下次再消费时之前没消费成功的消息就“ 诡异”的消失了;

解决办法:

针对消息丢失:

同步模式下,确认机制设置为-1,即让消息写入Leader和Follower之后再确认消息发送成功;

异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态;

针对消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。

消息重复消费及解决参考: 如何保证消息不被重复消费?(如何保证消息消费时的幂等性)-Java知音

消息的重复消费问题,需要考虑幂等性,如果消费类型天生幂等,那么就没有必要去考虑重复消费的问题。

但是一般上 MQ 的任务都是一些比较耗时的任务,比如说调用第三方服务,此时可以采用第三方记录(redis),保存消息的唯一 id,定义消息的唯一id 以及时间戳的消费类型(待处理,过程中,失败/完成),如果是消费过程丢失,会导致消息长时间处于待处理的状态,我们可以另起一个定时任务,轮询一定时间间隔的任务,将它生产到兜底服务,由兜底服务去判断是否需要再次消费(比如说,一个 sms 服务,可以去查询当前消息 id 的短信是否已经成功发出,如果成功发出,则标记当前任务成功消费。)

3. Kafka 的设计是什么样的呢?

Kafka 将消息以主题为单位进行归纳。

  • 将向 Kafka 主题发布消息的程序称为生产者。
  • 将预订主题并消费消息的程序成为消费者。
  • Kafka 以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个 broker(中间人)。
  • 生产者通过网络将消息发送到 Kafka 集群,集群向消费者提供消息

4. 数据传输的事务定义有哪三种

  • 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输;
  • 最少一次: 消息不会被漏发送,最少被传输一次,但也有可能被重复传输;
  • 精确的一次(Exactly once): 不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的。

5. Kafka 怎么判断一个节点存活

主要有两个条件

  1. 必须可以维护和 ZooKeeper 的连接,ZooKeeper 通过心跳机制检查每个节点的连接;
  2. 如果节点是个 follower,他必须能及时的同步 leader 的写操作,延时不能太久。

6. 生产者是否直接将数据发送到 broker 的 leader (主节点)

生产者直接将数据发送到 broker 的 leader(主节点),不需要在多个节点进行分发,为了 帮助 producer 做到这点,所有的 Kafka 节点都可以及时的告知,哪些节点是活动的,目标 topic 目标分区的 leader 在哪。这样 producer 就可以直接将消息发送到目的地了。

7. Kafka 消费者是否可以消费指定分区消息?

Kafka 消费消息时,向 broker 发出 “fetch” 请求去消费特定分区的消息,同时,consumer 还指定消息在日志中的偏移量(offset),这样就可以消费从这个位置开始的消息。

消费者拥有 了 offset 的控制权,可以向后回滚去重新消费之前的消息,这是很有意义的。

8. Kafka 消息是采用 Pull 模式,还是 Push 模式?

Kafka 遵循了一种大部分消息系统共同的传统 的设计:producer 将消息推送到 broker,consumer 从 broker 拉取消息 。

9. Kafka 存储在硬盘上的消息格式是什么? (存疑)

消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和 CRC32 校验码。

  • 版本号: 1 byte
  • CRC 校验码: 4 bytes
  • 具体的消息: n bytes

10. 介绍一下kafka 的 ack 机制

在Kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常被收到。

可以通过设置request.required.acks 决定 ack 策略。

  • 0: 生产者不会等待 broker 的 ack,这个延迟最低但是存储的保证最弱。当 server 挂掉的时候就会丢数据;
  • 1:服务端会等待 ack 值。leader 副本确认接收到消息后发送 ack 。如果 leader 挂掉后,不确保是否复制完成,也就是说新 leader 可能会丢失数据;
  • -1:同样在 1 的基础上,服务端会等所有的 follower 的副本收到数据后, leader 才会发出 的 ack,这样数据就不会丢失。

11. Kafka 的消费者如何消费数据

消费者每次消费数据的时候,都会记录消费的物理偏移量(offset), 等到下次消费时,他会接着上次位置继续消费 。

相关文章
|
3天前
|
消息中间件 存储 监控
Kafka 面试题及答案整理,最新面试题
Kafka 面试题及答案整理,最新面试题
156 3
|
3天前
|
消息中间件 分布式计算 监控
Python面试:消息队列(RabbitMQ、Kafka)基础知识与应用
【4月更文挑战第18天】本文探讨了Python面试中RabbitMQ与Kafka的常见问题和易错点,包括两者的基础概念、特性对比、Python客户端使用、消息队列应用场景及消息可靠性保证。重点讲解了消息丢失与重复的避免策略,并提供了实战代码示例,帮助读者提升在分布式系统中使用消息队列的能力。
42 2
|
3天前
|
消息中间件 监控 大数据
Kafka消息队列架构与应用场景探讨:面试经验与必备知识点解析
【4月更文挑战第9天】本文详尽探讨了Kafka的消息队列架构,包括Broker、Producer、Consumer、Topic和Partition等核心概念,以及消息生产和消费流程。此外,还介绍了Kafka在微服务、实时数据处理、数据管道和数据仓库等场景的应用。针对面试,文章解析了Kafka与传统消息队列的区别、实际项目挑战及解决方案,并展望了Kafka的未来发展趋势。附带Java Producer和Consumer的代码示例,帮助读者巩固技术理解,为面试做好准备。
29 0
|
21小时前
|
消息中间件 关系型数据库 MySQL
MySQL 到 Kafka 实时数据同步实操分享(1),字节面试官职级
MySQL 到 Kafka 实时数据同步实操分享(1),字节面试官职级
|
1天前
|
消息中间件 Java Kafka
Java大文件排序(有手就能学会),kafka面试题2024
Java大文件排序(有手就能学会),kafka面试题2024
|
1天前
|
消息中间件 前端开发 Java
java面试刷题软件kafka和mq的区别面试
java面试刷题软件kafka和mq的区别面试
|
3天前
|
消息中间件 Kafka API
这些年背过的面试题——Kafka篇
本文是技术人面试系列Kafka篇,面试中关于Kafka都需要了解哪些基础?一文带你详细了解,欢迎收藏!
|
3天前
|
消息中间件 网络协议 Dubbo
Kafka常见面试题
Kafka常见面试题
32 2
|
3天前
|
消息中间件 存储 监控
深入剖析:Kafka流数据处理引擎的核心面试问题解析75问(5.7万字参考答案)
Kafka 是一款开源的分布式流处理平台,被广泛应用于构建实时数据管道、日志聚合、事件驱动的架构等场景。本文将深入探究 Kafka 的基本原理、特点以及其在实际应用中的价值和作用。 Kafka 的基本原理是建立在发布-订阅模式之上的。生产者将消息发布到主题(Topic)中,而消费者则可以订阅这些主题并处理其中的消息。Kafka包括多个关键组件,如生产者、消费者、主题分区、ZooKeeper 等,Kafka 实现了高性能的消息传递和存储。特点:高吞吐量、可持久化存储、水平扩展、容错性和实时性等。
115 0
|
1天前
|
安全 Java 数据库
Spring boot 入门教程-Oauth2,java面试基础题核心
Spring boot 入门教程-Oauth2,java面试基础题核心

热门文章

最新文章