Kafka如何记录Offset

一、消费者如何知道消费到哪个Offset了?

消费位移的存储位置

消费位移存储在Kafka内部的一个特殊Topic中:__consumer_offsets,这个Topic是Kafka自动创建和管理的:

位移在__consumer_offsets中的存储格式
__consumer_offsetsTopic中消息的Key-Value结构:

Key: [消费者组名, Topic名, 分区号]
Value: [位移值, 元数据, 时间戳]

例如

Key: ["my-consumer-group", "order-topic", 0]
Value: [1567, metadata, timestamp]

Key: ["my-consumer-group", "order-topic", 1]  
Value: [2034, metadata, timestamp]

消费者查找位移的过程

当消费者启动或重平衡时:
向Broker查询位移:消费者向__consumer_offsetsTopic对应的Coordinator查询
Coordinator返回位移:Coordinator从__consumer_offsets中读取该消费者组的位移
如果没有位移:根据auto.offset.reset配置决定:
						earliest:从最早的消息开始
						latest:从最新的消息开始(默认)
						none:抛出异常

Broker挂掉重启后的恢复过程

Broker重启对消费位移的影响

重要结论:Broker重启通常不会导致消费位移丢失!

原因:位移存储在__consumer_offsets中:这是普通的Kafka Topic,具有多副本冗余, 位移信息是持久的:即使Broker重启,只要__consumer_offsets的副本还在,位移就不会丢失

二、服务端的offset什么时候更新?

首先消费者本地也会存储一个offset

消费者客户端都会在本地维护一个已消费位移的记录。这个记录通常是一个映射,键是主题+分区,值是当前消费到的位移,这个保存只是为了记录,到时候提交给服务端的offset,没什么实际作用。

服务端的更新取决于消费者上送过来的offSet, 消费者每次消息后会给服务端提交offset,分为手动提交和自动提价。

自动提交

由消费者客户端在后台自动完成,默认是开启的。提交的频率由参数auto.commit.interval.ms控制(默认5秒)。消费者会在每次轮询(poll)消息时检查是否到了该提交offset的时间,如果是,则提交上一次poll返回的offset。
对于自动提交,消费者客户端在后台有一个定时任务,定期将本地记录的最新位移提交到Kafka的__consumer_offsets主题中。自动提交的触发是在调用poll方法时,那么就会在拉取消息之前先提交上一次poll的消息位移。

手动提交

开发者通过调用commitSync或commitAsync方法主动提交offset。就是消费一条,做业务处理,只有业务处理成功,消费方法才返回SUCCESS或者FAIL。

三、消费者本地存储了Offset,而broker也存储了offset,当服务端重启或者消费端重启,到底以谁的offset为准?

我们首先需要明确:Kafka的位移管理机制中,消费者本地存储的offset和Broker端存储的offset分别是什么角色,以及它们如何协同工作。

在Kafka中,位移提交的本质是将消费者消费的进度(即offset)保存到Broker端的内部topic(__consumer_offsets)中。而消费者本地也会维护一份位移信息,但这份本地位移信息有两层含义:

消费者会从Broker端获取当前已经提交的位移(也就是上次消费的进度),然后从这个位移开始消费。在消费过程中,消费者会实时更新本地的位移状态(即position),但是这些更新并不会立即同步到Broker端,而是根据提交策略(自动提交或手动提交)来同步到Broker。

因此,当服务端重启或者消费端重启时,位移的确定遵循以下原则:

以Broker端存储的已提交位移为准。

具体过程如下:

1、消费者启动时(无论是第一次启动还是重启),会向Broker发送请求,获取它之前提交的位移(即从__consumer_offsets topic中读取)。
2、如果Broker端存在该消费者组的位移记录,那么消费者将从该位移开始消费。
3、如果Broker端没有该消费者组的位移记录(比如第一次启动,或者位移数据过期被删除),那么消费者将根据配置参数auto.offset.reset来决定从何处开始消费(最早还是最晚)。

那么,消费者本地的位移信息起什么作用呢?

消费者本地的位移信息主要用于消费过程中的进度跟踪。在运行过程中,消费者会维护每个分区的消费位置(position),这个位置是消费者下一次要读取的消息的offset。当消费者拉取消息后,会更新这个position。当消费者提交位移时,实际上就是将本地的position提交到Broker。

但是,如果消费者在运行过程中崩溃了,那么它本地维护的position可能会丢失(因为是在内存中)。而Broker端存储的位移是消费者最后一次提交的位移,可能不是最新的消费位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信仰_273993243

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值