面试必备-kafka如何保证消息不丢失

501 阅读7分钟

Kafka 如何保证消息不丢失?——从生产者、Broker、消费者全方位揭秘

引言

大家好,今天我们来聊聊 Kafka 如何保证消息不丢失。这个话题看似简单,但实际上涉及到了 Kafka 的方方面面。你可能会想:“消息不丢失?这不是 Kafka 的基本功能吗?” 没错,Kafka 确实很强大,但如果你不了解它的内部机制,消息丢失的坑可是无处不在的!今天,我们就从生产者、Broker、消费者三个角度,循序渐进地揭开 Kafka 保证消息不丢失的神秘面纱。准备好了吗?让我们一起踏上这段充满幽默与知识的旅程吧!


消息的生命周期

image.png

一、生产者:别让你的消息“半路失踪”

1.1 生产者的“心路历程”

想象一下,你是一个 Kafka 生产者,你的任务是把消息送到 Kafka Broker。你可能会想:“这不就是发个消息吗?有什么难的?” 但别急,事情可没这么简单。消息在发送的过程中可能会遇到各种“意外”,比如网络抖动Broker 宕机等。那么,Kafka 生产者是如何保证消息不丢失的呢?

1.2 关键机制:ACK 机制

Kafka 生产者有一个非常重要的配置参数:acks。这个参数决定了生产者发送消息后,需要等待多少个副本确认收到消息,才认为消息发送成功。它有以下几个选项:

  • acks=0:生产者发送消息后,根本不等待任何确认。这种模式下,消息可能会丢失,但发送速度最快。 没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据
  • acks=1:生产者等待 Leader 副本确认收到消息。这种模式下,如果 Leader 副本崩溃,消息可能会丢失。 follower同步成功之前 leader 故障,那么将会丢失数据 image.png
  • acks=all:生产者等待所有 ISR(In-Sync Replicas)副本确认收到消息。这种模式下,消息最安全,但发送速度最慢。 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复

image.png

思考题:如果你是一个电商平台的开发者,你会选择哪种 acks 配置?为什么?

1.3 重试机制:不怕失败,只怕放弃

除了 acks 配置,Kafka 生产者还提供了重试机制。如果消息发送失败,生产者会自动重试。你可以通过 retries 参数设置重试次数,通过 retry.backoff.ms 参数设置重试间隔。

幽默时刻:想象一下,Kafka 生产者就像一个坚持不懈的推销员,即使被拒绝多次,依然不放弃,直到把消息成功“推销”出去!

1.4 总结:生产者的“防丢秘籍”

  • 使用 acks=all 确保消息被多个副本确认。
  • 启用重试机制,避免因网络抖动导致的发送失败。
  • 合理配置 retries 和 retry.backoff.ms,避免过度重试。

二、Broker:消息的“守护者”

2.1 Broker 的“职责”

Broker 是 Kafka 集群的核心组件,负责存储和管理消息。它的任务不仅仅是接收消息,还要确保消息在集群中的多个副本之间同步。那么,Broker 是如何保证消息不丢失的呢?

2.2 关键机制:副本同步

Kafka 通过副本机制来保证消息的高可用性。每个分区(Partition)都有多个副本,其中一个副本是 Leader,其他副本是 Follower。Leader 负责处理读写请求,Follower 负责从 Leader 同步数据。

思考题:如果 Leader 副本崩溃,Kafka 如何选举新的 Leader?这个过程会导致消息丢失吗?

2.3 ISR 机制:同步副本的“小圈子”

Kafka 引入了一个叫做 ISR(In-Sync Replicas)的概念。ISR 是一个与 Leader 保持同步的副本集合。只有 ISR 中的副本才有资格被选举为新的 Leader。如果某个 Follower 副本落后太多,它会被踢出 ISR,直到它追上 Leader 的进度。

幽默时刻:ISR 就像是一个精英俱乐部,只有最优秀的副本才能加入。如果你的副本不够“优秀”,那就只能在外面等着了!

2.4 总结:Broker 的“防丢秘籍”

  • 使用副本机制确保消息的高可用性。
  • 通过 ISR 机制保证副本之间的同步。
  • 定期检查副本的健康状态,及时剔除落后的副本。

image.png

LEO:指的是每个副本最大的 offset;

HW:指的是消费者能见到的最大的 offset,ISR 队列中最小的 LEO。

(1)follower 故障

follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后,follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。

(2)leader 故障

leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。

注意:这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复


三、消费者:别让消息“溜走”

3.1 消费者的“任务”

消费者是 Kafka 消息的最终接收者。它的任务是从 Broker 拉取消息并进行处理。但是,如果消费者处理不当,消息也可能会丢失。那么,消费者是如何保证消息不丢失的呢?

3.2 关键机制:偏移量提交

Kafka 消费者通过偏移量(Offset)来记录消息的消费进度。消费者在处理完消息后,需要提交偏移量,以告知 Broker 这条消息已经被成功消费。如果消费者在处理消息时崩溃,偏移量没有提交,那么下次启动时,消费者会从上次提交的偏移量处重新消费,导致消息重复。

思考题:如果消费者在处理消息时崩溃,如何避免消息重复消费?

3.3 手动提交 vs 自动提交

Kafka 消费者支持自动提交和手动提交偏移量。自动提交虽然方便,但可能会导致消息丢失或重复。手动提交可以更精确地控制偏移量的提交时机,但需要开发者自己处理提交逻辑。

幽默时刻:自动提交就像是一个“懒人模式”,虽然省事,但可能会让你错过一些重要的消息。手动提交则像是一个“强迫症模式”,虽然麻烦,但能确保万无一失!

3.4 总结:消费者的“防丢秘籍”

  • 使用手动提交偏移量,确保消息处理完成后再提交。
  • 处理消息时做好幂等性设计,避免重复消费。
  • 监控消费者的消费进度,及时发现和处理异常。

四、总结:Kafka 消息不丢失的“终极秘籍”

通过以上分析,我们可以看到,Kafka 保证消息不丢失需要从生产者、Broker、消费者三个角度共同努力:

  1. 生产者:使用 acks=all 和重试机制,确保消息成功发送。
  2. Broker:通过副本和 ISR 机制,确保消息在集群中的高可用性。
  3. 消费者:使用手动提交偏移量,确保消息被成功处理。

终极思考题:如果你是一个 Kafka 系统的架构师,你会如何设计一个既能保证消息不丢失,又能兼顾性能的系统?


结语

Kafka 的消息不丢失机制看似复杂,但只要我们理解了它的核心原理,就能轻松应对各种挑战。希望今天的文章不仅能让你学到知识,还能让你在轻松愉快的氛围中感受到技术的魅力。如果你觉得这篇文章对你有帮助,别忘了点赞、分享哦!我们下次再见!