Kafka的偏移量offset存放在哪?为什么?

Kafka的偏移量offset存放在哪?为什么?

[TOC]

​ 从Kafka-0.9版本之后,Kafka的消费者组和offset信息就不存在zookeeper了,而是存在到了broker服务器上。所以,如果你为某个消费者指定了一个消费者组名称(group.id)。那么,一旦这个消费者启动,这个消费者组名和它要消费的那个topic的offset信息就会被记录在broker服务器上。

1、概述

​ Kafka版本【0.10.1.1】,已经默认将消费的 offset 迁入到 Kafka 一个名为__consumer_offsets 的topic中。其实,早在 0.8.2.2 版本中,已经支持存入消费的 offset 到 topic 中,只是那时候默认是将消费的 offset 存放在 Zookeeper 集群中。那现在,官方默认将消费的 offset 存储在 Kafka 的 topic 中, 同时,也保留了存储在 Zookeeper 的接口, 通过 offset.storage 属相来了进行设置。

2、内容

​ 其实,官方这样推荐,也是有道理的。

​ 之前的版本中,Kafka其实存在一个比较大的隐患,就是利用 Zookeeper 来存储记录每个消费者/组的消费进度。虽然在使用的过程当中,JVM帮助我们完成了一些优化,但是消费者需要频繁的去与 Zookeeper 进行交互,而利用 ZKClient 的 API 操作 Zookeeper 频繁的Write 其本身就是一个比较低效的 Action,对于后期水平扩展也是一个比较头疼的问题。如果区间 Zookeeper 集群发生变化,那 Kafka 集群的吞吐量也跟着受影响。

​ 在此之后,官方其实很早就提出了迁移到 Kafka 的概念,只是之前是一直默认储存在 Zookeeper 集群中,需要手动的设置,如果对Kafka的使用不是很熟悉的话,一般我们就接受了默认的储存(即:存在ZK中)。在新版的 Kafka 级以后的版本中。Kafka 消费的 offset都会默认存放在 Kafka 集群中一个叫 __consumer_offsets 的topic中

3、总结

​ Kafka的offset以前存放在ZK里,由于zookeeper不适合为服务提供负载高写(如偏移量更新),于是移除了,改成存储在主题里,原因如下:

1
2
Zookeeper is not a good way to service a high-write load such as offset updates because zookeeper routes each write though every node and hence has no ability to partition or otherwise scale writes. We have always known this, but chose this implementation as a kind of “marriage of convenience” since we already depended on zk.
译文:Zookeeper不是为高写负载(比如偏移量更新)提供服务的好方法,因为Zookeeper通过每个节点路由每个写操作,因此无法进行分区或扩展写操作。我们一直都知道这一点,但选择这个实现作为一种“方便的联姻”,因为我们已经依赖于zk。

​ 目前消费者提交偏移量时,会发送到一个_comsumer_offsets的topic里,并保持一个内存结构:组/主题/分区,映射到最新的偏移量,方便快速检索。

​ 磁盘里也可以看到类似如下文件:

1
2
3
_comsumer_offsets-1
_comsumer_offsets-2
_comsumer_offsets-3

__consumer_offset 是一个Kafka自动创建的 Topic,用来存储消费者消费的 offset (偏移量)信息,默认 Partition数为50。而就是这个Topic,它的默认副本数为1。