__consumer_offsets

__consumer_offsets 是 kafka 自行创建的,和普通的 topic 相同。它存在的目的之一就是保存 consumer 提交的位移

__consumer_offsets 的每条消息格式大致如图所示:

可以想象成一个 KV 格式的消息,key 就是一个三元组:group.id+topic+分区号,而 value 就是 offset 的值。

考虑到一个 kafka 生成环境中可能有很多 consumer 和 consumer group,如果这些 consumer 同时提交位移,则必将加重 __consumer_offsets 的写入负载,因此 kafka 默认为该 topic 创建了50个分区,并且对每个 group.id 做哈希求模运算,从而将负载分散到不同的 __consumer_offsets 分区上


一般情况下,当集群中第一次有消费者消费消息时会自动创建 __consumer_offsets,它的副本因子受 offsets.topic.replication.factor 参数的约束,默认值为3(注意:该参数的使用限制在0.11.0.0版本发生变化),分区数可以通过 offsets.topic.num.partitions 参数设置,默认值为50。

OffsetCommitRequest

客户端提交消费位移是使用 OffsetCommitRequest请求实现的,OffsetCommitRequest 的结构如下图所示。

请求体第一层中的 group_id、generation_id 和 member_id 表示消费者具体信息, retention_time 表示当前提交的消费位移所能保留的时长,不过对于消费者而言这个值置为1。也就是说,按照 broker 端的配置 offsets.retention.minutes 来确定保留时长,默认为10080,即7天,超过这个时间后消费位移的信息就会被删除(使用墓碑消息和日志压缩策略)。
注意:这个参数在2.0.0版本之前的默认值为1440,即1天。

OffsetCommitRequest 中的其余字段大抵也是按照分区的粒度来划分消费位移的,注意还有一个 metadata 字段。metadata 是自定义的元数据信息,如果不指定这个参数,那么就会被设置为空字符串,注意 metadata 的长度不能超过 broker 端参数 offset.metadata.max.bytes 参数所配置的大小,默认值为4096。

Key 和 Value

同消费组的元数据信息一样,最终提交的消费位移也会以消息的形式发送至 __consumer_offsets,与消费位移对应的消息只定义了 key和 value 字段的具体内容,它不依赖于具体版本的消息格式,以此做到与具体的消息格式无关。

下图中展示了消费位移对应的消息内容格式,上面是消息的 key,下面是消息的 value。可以看到 key 和 value 中都包含了 version 字段,这个用来标识具体的 key 和 value 的版本信息,不同的版本对应的内容格式可能并不相同。到当前版本版本(2.x)而言 key 和 value 的 version 值都为1。

Key

key 中除了 version 字段还有 grouptopicpartition 字段,分别表示消费组的 groupId、topic 和 partition 编号。虽然 key 中包含了4个字段,但最终确定这条消息所要存储的分区还是根据单独的 group 字段来计算的,这样就可以保证消费位移信息与消费组对应的 GroupCoordinator 处于同一个 broker 节点上,省去了中间轮转的开销,这一点与消费组的元数据信息的存储是一样的。

Value

value 中包含了5个字段,除 version 字段外,其余的 offsetmetadatacommit_timestampexpire_timestamp 字段分别表示消费位移、自定义的元数据信息、位移提交到 Kafka 的时间戳、消费位移被判定为超时的时间戳。其中 offset 和 metadata 与 OffsetCommitRequest 请求体中的offset 和metadata 对应,而 commit_timestamp 和 OffsetCommitRequest 请求体中的 retention_time 也有关联,commit_timestamp 值与 offsets.retention.minutes 参数值之和即为 expire_timestamp (默认情况下)。

OffsetCommitResponse

在处理完消费位移之后,Kafka 返回 OffsetCommitResponse 给客户端,OffsetCommitResponse 的结构如下图所示。

查看__consumer_offsets中的消息

可以通过 kafka-console-consumer.sh 脚本来查看 __consumer_offsets 中的内容,不过要设定 --formatter 参数为kafka.coordinator.group.GroupMetadataManager$OffsetsMessageFormatter
注意,该参数在0.11.0版本之前为 kafka.coordinator.GroupMetadataManager$OffsetsMessageFormatter

示例:
./kafka-console-consumer.sh --bootstrap-server 10.163.198.134:9092 --topic __consumer_offsets --partition 35 --from-beginning --formatter 'kafka.coordinator.group.GroupMetadataManager$OffsetsMessageFormatter'

一般情况下, 使用 OffsetsMessageFormatter 打印的格式可以概括为:

"[%s,%s,%d]::[OffsetMetadata[%d,%s],CommitTime %d,ExpirationTime %d]".format(group, topic, partition, offset, metadata, commitTimestamp, expireTimestamp)

如果某个 key( version + group + topic +partition 的组合)对应的消费位移过期了,那么对应的 value 就会被设置为 null,也就是墓碑消息(__consumer_offsets 使用的是日志压缩策略)。对应的打印结果也会变成如下的形式:

"[%s,%s,%d]::NULL".format(group, topic, partition)

当在查看主题 __consumer_offsets 中的内容时出现下面这种情况:
[consumer_test,testTopic,0]::NULL
这说明对应的消费位移己经过期了。

在 Kafka 中有一个名为“delete-expired-group-metadata”的定时任务来负责清理过期的消费位移,这个定时任务的执行周期由参数 offsets.retention.check.interval.ms 控制,默认值为600000,即10分钟。

还有 metadata,一般情况下它的值要么为 null 要么为空字符串,OffsetsMessageFormatter 会把它展示为 NO_METADATA,否则就按实际值进行展示。

 

  • 13
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值