找回密码
 立即注册
查看: 466|回复: 0

[后端] Kafka 消息传递魔法揭秘:至少消费一次的实现原理!

[复制链接]

279

主题

0

回帖

964

积分

超级版主

积分
964
发表于 2024-6-1 13:45:58 | 显示全部楼层 |阅读模式
本帖最后由 Shaw0xyz 于 2024-6-9 13:51 编辑

1. 简介

Kafka 是一种高吞吐量、分布式消息队列系统,广泛应用于实时数据处理和日志采集等场景。在使用 Kafka 进行消息传递时,至少消费一次(at-least-once)是一个重要的保证。本文将详细解析 Kafka 至少消费一次的实现原理,帮助读者理解其工作机制和实现细节。

1.1 Kafka 消息传递模式

Kafka 支持三种消息传递模式:至多消费一次(at-most-once)、至少消费一次(at-least-once)和精确消费一次(exactly-once)。本文重点讨论至少消费一次模式。

1.1.1 至少消费一次模式

在至少消费一次模式下,Kafka 保证消息至少被消费一次。这意味着每条消息可能会被消费多次,但不会丢失消息。实现这一模式的关键在于消息的可靠存储和消费者的处理机制。

2. Kafka 至少消费一次的实现原理

2.1 生产者发送消息

Kafka 生产者在发送消息时,会将消息写入到指定主题的分区中。为了确保消息可靠传输,Kafka 提供了多种确认机制(acks),包括:
(1) acks=0:生产者发送消息后不等待确认,性能最高,但可靠性最低。
(2) acks=1:生产者在消息被写入到主分区副本后收到确认,可靠性较高。
(3) acks=all:生产者在消息被写入到所有同步副本后收到确认,可靠性最高。

推荐使用 acks=all 配置,以确保消息可靠写入。

2.2 消息存储与日志

Kafka 将消息存储在主题的分区中,每个分区对应一个日志文件。消息一旦写入日志文件,将被持久化存储,以防止数据丢失。为了提高存储性能和可靠性,Kafka 支持多副本机制,每个分区可以有多个副本,分布在不同的节点上。

2.3 消费者拉取消息

Kafka 消费者通过拉取(pull)模式从分区中读取消息。为了保证至少消费一次,消费者需要定期提交偏移量(offset),表示已经处理到哪一条消息。Kafka 提供了两种提交偏移量的方式:
(1) 自动提交:消费者定期自动提交当前处理的偏移量。
(2) 手动提交:消费者在处理完消息后,显式提交偏移量。

推荐使用手动提交,以确保消息处理的准确性和可靠性。

2.4 消费者提交偏移量

手动提交偏移量的流程如下:
(1) 消费者从分区中拉取消息。
(2) 处理消息。
(3) 在处理完消息后,提交当前偏移量。

例如,使用 Kafka 的 java 客户端代码进行手动提交:

  1. Properties props = new Properties();
  2. props.put("bootstrap.servers", "localhost:9092");
  3. props.put("group.id", "test");
  4. props.put("enable.auto.commit", "false");
  5. props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
  6. props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

  7. KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
  8. consumer.subscribe(Arrays.asList("topic"));

  9. try {
  10.     while (true) {
  11.         ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
  12.         for (ConsumerRecord<String, String> record : records) {
  13.             System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
  14.         }
  15.         consumer.commitSync();
  16.     }
  17. } finally {
  18.     consumer.close();
  19. }
复制代码


在上述代码中,消费者拉取消息并处理后,通过 commitSync() 方法手动提交偏移量。这种方式确保在消息处理完成后才提交偏移量,避免消息丢失。

2.5 处理失败与重试机制

在实际应用中,消息处理过程中可能会出现异常情况。为了实现至少消费一次,消费者需要实现处理失败与重试机制:
(1) 捕获异常:在消息处理过程中捕获所有可能的异常。
(2) 重试处理:对于处理失败的消息,重新尝试处理,直到成功为止。
(3) 死信队列:对于多次重试仍然失败的消息,发送到死信队列(Dead Letter Queue),进行人工干预或后续处理。

3. 总结

Kafka 至少消费一次的实现依赖于可靠的消息存储、消费者的手动提交偏移量以及处理失败的重试机制。通过合理配置生产者、消费者以及日志存储,Kafka 能够确保消息至少被消费一次,满足高可靠性的数据传输需求。在实际应用中,结合业务需求,灵活调整消费模式和处理策略,可以有效提高系统的可靠性和稳定性。



/ 荔枝学姐de课后专栏 /

Hi!这里是荔枝学姐~

欢迎来到我的课后专栏

自然语言学渣 NLP摆烂姐

热衷于技术写作 IT边角料

AIGC & Coding & linux ...

~互撩~ TG: @Shaw_0xyz
荔枝学姐爱吃荔枝!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系站长|Archiver|手机版|小黑屋|主机论坛

GMT+8, 2025-4-4 22:55 , Processed in 0.074749 second(s), 24 queries .

Powered by 主机论坛 HostSsss.Com

HostSsss.Com

快速回复 返回顶部 返回列表