Kafka消费者组和offset

新版Kafka已将consumer的位移信息保存在Kafka内部的topic中,即__consumer_offsets topic。如何将多个consumer组成消费者组?同时组成消费者组在消费消息时,对应的offset文件是如何变化的?本文的生产消费模型图如下,一个生产者生产,两个消费者消费:

1、启动zookeeper和kafka,并创建一个名为topicC的topic,不设备份,partition为3

#进入到zookeeper目录后,再启动zookeeper
bin/zkServer.sh start

#进入到kafka目录后,再启动kafka
bin/kafka-server-start.sh config/server.properties

#另启一个终端,进入到kafka目录后,创建一个名为topicC的topic
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 3 --topic topicC

2、启动生产者和消费者

#启动生产者
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic topicC

想要把不同的消费者创建成一个消费者组,需要对配置文件进行修改,并且在命令行中指定该配置文件,否则命令行会默认执行--new-consumer,使得每个消费者单独组成消费者组

配置文件的路径:{kafka目录}/config/consumer.properties。我们将消费者组命名为topicCgroup

 打开两个终端,使用相同的命令,启动两个消费者

#启动消费者,指定同一个配置文件,或者不同的配置文件中配置相同的group.id
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic topicC --from-beginning --consumer.config config/consumer.properties

3、生产消费结果

可以看到consumer1消费一个partition,consumer2消费两个partition

4、如果消费者组意外崩溃,如何从上一次的offset继续消费,而不是重头开始

我们进行模拟,手动终止consumer1和consumer2,而生产者仍继续发送了11,12,13,14,15。然后在此时,我们再启动consumer,指定相同的group.id,即可继续消费

 另有两点值得注意:

(1)消费顺序并不是11-12-13-14-15,这印证了topic中partition之间无序,partition内有序

(2)重启的消费者同时消费了所有的partition

5、实际存储原理

要实现上述操作,那么有两个信息是kafka内部必然要存储的(1)消费者组id;(2)每个partition的offset。只有两者结合,才能明确某一个消费者组具体的消费进度。

在新版kafka中,用名为__consumer_offsets的topic来进行存储上述两个信息,默认的partition是50,因此在保存节点的文件夹中(同样可以在配置文件中指定节点的保存位置),可以看到

 如何确定topicCgroup保存在哪个partition?依赖最早在consumer.properties中指定的group.id属性,本文就为topicCgroup。如果忘记了自己的group.id,可以通过以下命令查询

#获取该consumer group的group id
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list --new-consumer

通过计算器计算,公式如下 ,numPartitions默认为50

Math.abs(groupID.hashCode()) % numPartitions

比如topicCgroup的计算结果就为45。说明在__consumer_offset-45这个partition中。然后,我们就可查看该partition的位移信息

#获取指定consumer group的位移信息 
bin/kafka-simple-consumer-shell.sh -topic __consumer_offsets --partition 45 --broker-list localhost:9092 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter"

查询结果如下,一开始只有10条消息,所以partition0,1,2的offset分别为4,3,3。在消费者重新启动后,消息共有15条,所以partition0的offset从4更新到5,partition1的offset从3更新到5,partition2的offset从3更新到5。从结果上看,就是把之前未消费的5条消息消费了。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值