kafka的offset存储位置以及offset的提交方式

本文介绍了Kafka消费者从0.9版本开始如何存储offset在内置的__consumer_offsets主题中,以及手动和自动提交offset的详细过程。自动提交可通过配置enable.auto.commit和auto.commit.interval.ms参数实现,手动提交则分为同步和异步两种方式,同步提交确保可靠性但可能降低效率,异步提交则提高吞吐量但不保证提交成功。

一 offset的存储位置

1.1 存储位置

1.从0.9版本开始,consumer默认将offset保存在Kafka 一个内置的topic中,该topic__consumer_offsets
2.Kafka0.9版本之前,consumer默认将offset保存在Zookeeper中。

 

__consumer_offsets 主题里面采用 key 和 value 的方式存储数据key 是 group.id+topic+
分区号value 就是当前 offset 的值。每隔一段时间,kafka 内部会对这个 topic 进行
compact,也就是每个 group.id+topic+分区号就保留最新数据

1.2 消费offset案例

1.首先在配置文件 config/consumer.properties 中添加配置 exclude.internal.topics=false

默认是 true,表示不能消费系统主题。为了查看该系统主题数据,所以该参数修改为 false。
2.采用命令行方式,创建一个新的 topic
bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --create --topic atguigu --partitions 2 --
replication-factor 2
3.启动生产者往 atguigu 生产数据
bin/kafka-console-producer.sh --topic  atguigu --bootstrap-server hadoop102:9092
4.消费数据
bin/kafka-console-consumer.sh  -- bootstrap-server hadoop102:9092 --topic atguigu --group test
注意:指定消费者组名称,更好观察数据存储位置(key group.id+topic+分区号)。
5.查看消费者消费主题__consumer_offsets

 二  offset的提交方式

2.1 自动提交方式

为了使我们能够专注于自己的业务逻辑,Kafka提供了自动提交offset的功能。
自动提交offset的相关参数:
enable.auto.commit是否开启自动提交offset功能,默认是true
auto.commit.interval.ms自动提交offset的时间间隔,默认是5s

 

 2.1.1 代码部分设置

// 是否自动提交 offset
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,
true);
// 提交 offset 的时间周期 1000ms,默认 5s
properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,
1000);

2.2 手动提交方式

虽然自动提交offset十分简单便利,但由于其是基于时间提交的,开发人员难以把握offset提交的时机。因 此Kafka还提供了手动提交offsetAPI
手动提交offset的方法有两种:分别是commitSync(同步提交)commitAsync(异步提交)。两者的相 同点是,都会将本次提交的一批数据最高的偏移量提交;不同点是,同步提交阻塞当前线程,一直到提交成功,并且会自动失败重试(由不可控因素导致,也会出现提交失败);而异步提交则没有失败重试机制,故 有可能提交失败。
commitSync(同步提交):必须等待offset提交完毕,再去消费下一批数据。并且会自动失败重试
commitAsync(异步提交) :发送完提交offset请求后,就开始消费下一批数据了。没有失败重试机制

2.2.1 同步提交

由于同步提交 offset 有失败重试机制,故更加可靠,但是由于一直等待提交结果,提
交的效率比较低。以下为同步提交 offset 的示例

 

 2.3.2 异步提交

虽然同步提交 offset 更可靠一些,但是由于其会阻塞当前线程,直到提交成功。因此
吞吐量会受到很大的影响。因此更多的情况下,会选用异步提交 offset 的方式。

 

### Kafka Offset 的概念与管理 Kafka 中的 Offset 是一个重要的概念,它用于标识消费者在某个分区中的消费位置。每个消息在分区中都有一个唯一的 Offset 值[^1]。Offset存储模型是按照 `groupid-topic-partition -> offset` 的方式组织的[^2]。这意味着每个消费者组(Consumer Group)在每个主题(Topic)的每个分区(Partition)上都有一个独立的 Offset 记录。 #### Offset 的查询与管理 Kafka 支持通过 Offset 查询消息,但不支持直接根据消息键(Key)进行查询[^2]。Offset 的管理经历了从 Zookeeper 到 Kafka 内部存储的变化。早期版本中,Kafka 使用 Zookeeper 存储消费者的消费状态和 Offset 信息[^3]。然而,由于 Zookeeper 的性能限制和潜在的单点问题,新版本的 Kafka 引入了内部的 Group Coordination 协议,减少了对 Zookeeper 的依赖[^3]。 #### Offset 的重置策略 在 Kafka 消费者配置中,`auto.offset.reset` 参数定义了当消费者没有找到对应的 Offset 时的行为[^5]。该参数有三个可选值: - `earliest`:从最早的 Offset 开始消费。 - `latest`:从最新的 Offset 开始消费。 - `none`:抛出异常给消费者。 #### 示例代码:配置 Kafka Consumer 以下是一个使用 Spring Boot 配置 Kafka Consumer 的示例代码[^4]: ```java import org.apache.kafka.clients.consumer.ConsumerConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import java.util.HashMap; import java.util.Map; @EnableKafka @Configuration public class KafkaConsumerConfig { @Bean public ConsumerFactory<String, String> consumerFactory() { Map<String, Object> config = new HashMap<>(); config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); config.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); config.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); // 设置 Offset 重置策略 return new DefaultKafkaConsumerFactory<>(config); } } ``` #### 解决 Offset 相关问题 如果遇到 Offset 相关的问题,可以尝试以下方法: 1. **Offset 手动提交**:通过手动控制 Offset 提交,确保消费者在正确的时间点提交 Offset[^3]。 2. **Offset 重置**:根据业务需求调整 `auto.offset.reset` 参数的值。 3. **监控工具**:使用 Kafka 自带的工具或第三方监控工具(如 Confluent Control Center)查看 Offset 状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值