一、消费者如何知道消费到哪个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端存储的位移是消费者最后一次提交的位移,可能不是最新的消费位置。
1294

被折叠的 条评论
为什么被折叠?



