kafka关于consumer的auto-offset-reset的earliest 和latest属性到底含义是什么?

慕容紫枫 发表于: 2020-02-15   最后更新时间: 2021-09-22 18:33:44   11,606 游览

请问关于consumer的auto-offset-reset earliestlatest 到底含义是什么?

去查阅了下官网资料

What to do when there is no initial offset in Kafka or if the current offset does not exist any more on the server (e.g. because that data has been deleted):
earliest: automatically reset the offset to the earliest offset
latest: automatically reset the offset to the latest offset

(机翻。。。)

当Kafka中没有初始偏移量或服务器上不再存在当前偏移量时(例如因为该数据已被删除),该怎么办:

  • 最早:将偏移量自动重置为最早的偏移量
  • 最新:自动将偏移量重置为最新偏移量

测试数据截图

当前kafka集群中的数据

有三个分区

screenshot

当前有三个消费组 且都已消费完毕

screenshot

screenshot

关闭消费者服务 当设置为earliest 生产者新增5个数据

screenshot

此时打开消费者查看消费详情

screenshot

发现并没有从头开始消费 而是从当前的offset之后开始消费了5个数据

关闭消费者服务 当设置为latest 继续生产5个数据

screenshot

screenshot

此时打开消费者查看消费详情

screenshot

结论 :当存在offset时 设置为earliest或latest 都是从当前的offset之后开始消费

测试一下新建的消费组 还是新生产5个数据 然后设置为latest时 开启消费服务

创建一个新的消费组 并订阅当前topic
screenshot

当设置为latest时 开启消费服务

screenshot
结果发现并不会消费新的数据 因为创建的5个数据 在新的消费服务启动前就已经创建了 而当前的消费者没有提交过offset 且模式设置为latest 直接设置当前的offset为 3056 (分区0最后一个是3055)和 8529(分区2最后一个是8528)

重新生产5个数据 此时查看到消费者获取到了新的5条数据

screenshot

此时查看当前的集群状态
多了一个c1_4 新增的消费组 并且已经更新到最新的offset
screenshot

新建消费组c1_5 新增5个数据 并设置为earliest时 然后开启消费服务

screenshot

打开消费者服务查看 消费详情

screenshot

发现之前的数据也消费了 id 14996 14998 14999 15000 等
此时查看kafka集群状态
screenshot

多了一个新的消费组c1_5 并且已经到最新的offset

screenshot

结论:

当Kafka中没有初始偏移量或服务器上不再存在当前偏移量时(例如因为该数据已被删除)时设置auto-offset-reset属性:
earliest :会从最早的开始拉取
latest : 会从当前最新的开始拉取 即当前offset 之后的第一个开始拉取

当存在已经提交的offset时 两者都是从最后一次提交记录的 offset开始拉取数据。

记录一下仅供大家参考 ,欢迎大佬指正错误,第一次写不太会排版见谅。。。

入坑kafka几天的萌新,现在才搭建完项目跑起来,发现我这个写的用消费者的springboot默认自带的key分区模式 结果数据分区不平衡 0 1 2 分区 2分区爆满 1分区基本没咋用。。。 想写个自定义的分区策略结果不了解整个加载流程 还在爬坑中。希望大佬多多指教。

发表于 2020-02-15
添加评论

你需要固定消费者组名。你这个消费者组名是随机生成的,每次重启都是新的。只有固定了组名。
测试就正常了。

慕容紫枫 -> 半兽人 4年前

组名是我用的 @KafkaListener(groupId = "c1_5") 注入的 这种的 应该是固定 消费者组名的

半兽人 -> 慕容紫枫 4年前

你测试的时候,不要换组名呀。
还是跟之前一样?

慕容紫枫 -> 半兽人 4年前

我测的时候 是这样的 之前有三个分组 c1_1 c1_2 c1_3 而且这三个已经消费过了
(1) 使用这3个消费者分组 然后分了两次 每次生产5条消息 先模拟 有offset记录的消费者设置earliest 然后在模拟有offset的消费者 设置latest 结果都是从上一次提交的offset之后拉取数据 每次都只会拉取5条。
(2)之后我又分两次 每次生产5条消息 第一次先用一个新的消费者组 c1_4 设置latest 模拟 无offset记录的latest的情况 发现消费者offset会直接到最新的位置 上面有截图,然后第二次创建一个新的消费组c1_5 设置 earliest 模拟无offset 的 earliest 的情况 发现消费者会直接把分区中的数据从头开始拉取了一遍。
这个不换组名是什么意思? 我这样测的结果是和 官网文档保持一致的 这个属性和 消费者之前有没有 offset记录是有关系的

半兽人 -> 慕容紫枫 4年前

你测试的结果不是对了吗?还有啥疑惑呢?

earliest从头开始消费,不管你的offset。
latest从你提交的offset开始消费,保持消费最新的。

就跟你定报纸一样,你告诉报社我要定报纸,报社才知道你要开始定报纸,以后有新的报纸都给你。旧的的报纸当然不会给你了。

当你要求(earliest)我要老的报纸,这样报社就会把之前所有的报纸都给你。

慕容紫枫 -> 半兽人 4年前

哈哈这个栗子很形象,我是觉得earliest从头开始消费(不管你的offset)括号里这句好像不太对 。

earliest:如果一个消费者之前提交过offset。 假设这个消费者中途断过,那当它恢复之后重新连接到队列集群 此时应该是从 它在集群中之前提交的offset点开始继续消费,而不是从头消费。 而一个消费者如果之前没有offset记录并设置earliest ,此时才会从头消费。

按照栗子来说就是 之前订过1月份的报纸(存在offset记录)然后设置earliest此时是不管用的,报社还是会给你发1月之后的报纸(不会从头消费),而如果你是一个新用户(不存在offset) 当你订阅报纸并设置earliest 此时报社才会从头开始发送所有的报纸。

latest:当集群中存在消费者之前提交的offset记录时 队列集群会从之前记录的offset点开始发送 「记录的offset点,+无穷」。 而当消费者之前在集群中不存在offset记录点时 会从队列中最新的记录开始消费。

按照栗子来说就是 之前订过1月份的报纸(存在offset记录)然后设置latest,报社会给你发1月之后的报纸,而如果你是一个新用户(不存在offset) 当你订阅报纸并设置latest 此时报社会发送最新的报纸。

半兽人 -> 慕容紫枫 4年前

你说的是对的,(不管你的offset)是错的。

慕容紫枫 -> 半兽人 4年前

好的 再次感谢大佬回答 近期业务暴增,刚入坑kafka 有很多问题到时候还希望大佬不吝赐教~~~

不错不错哟

个人觉得应该分清 commitedOffset 和 endOffset, 如果只是说 offset, 会让人同意混淆新加入的 consumer group的起始消费位置

你的答案

查看kafka相关的其他问题或提一个您自己的问题