11、kafka 实战 - Zookeeper在kafka中的作用

Zookeeper在kafka中的作用

kafka集群中有个一broker会被选举为Controller,负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作。

Controller的管理工作都是依赖于zookeeper的。

broker注册

broker是分布式部署并且相互之间相互独立,但是需要一个注册系统能够将整个集群中的broker管理起来,此时就使用到了zk,在zk上会有一个专门用来进行broker服务器列表记录的节点:

/brokers/ids

每个broker在启动时,都会到zookeeper上进行注册,即到/brokers/ids下创建属于自己的节点,如/brokers/ids/[0~n]

kafka使用了全局唯一的数字来指代每个broker服务器,不同的broker必须使用不同的brokerID进行注册,创建节点完成后,每个broker就会将自己的ip地址和端口信息记录到该节点中去。其中,broker创建的节点类型是临时节点,一旦broker宕机,则对应的临时节点也会自动删除

topic注册

在kafka中,同一个topic的消息会被分成多个分区并将其分布在多个broker上,这些分区信息与broker的对应关系也是由zookeeper维护的,由专门的节点来记录,如:

/brokers/topics

kafka中每个topic都会以/brokers/topics/[topic]的形式被记录。broker服务器启动后,会到对应的Topic节点上注册自己的brokerID并写入针对该topic的分区总数,如/brokers/topics/first/3->2,这个节点表示brokerid为3的一个broker服务器,对于"first"这个topic的消息,提供了2个分区进行消息存储,同样,这个分区节点也是临时节点。

生产者负载均衡

由于同一个topic消息会被分区将其分布在多个broker上,因此,生产者需要将消息合理的发送到这些分布式的broker上

由于每个broker启动时,都会完成broker注册过程,生产者会通过该节点的变化来动态的感知到broker服务器列表的变更,这样就可以实现动态的负载均衡机制。

消费者负载均衡

与生产者类似,kafka中的消费者同样需要进行负载均衡来实现多个消费者合理的从对应的broker服务器上接收消息,每个消费者分组包含若干消费者,每条消息都只会发送给分组中的一个消费者,不同的消费者分组消费自己特定的topic下面的消息,互不干扰。

分区与消费者的关系

消费者组,consumer group有多个消费者consumer

对于每个消费者组,kafka会为其分配一个全局唯一的groupId,group内部的所有消费者共享该id。订阅的topic下的每个分区只能分配给某个group下的一个consumer(当然分区还可以被分配给其他group)

同时,kafka为每个消费者分配一个consumerID,通常采用Hostname:UUID形式表示。

在kafka中,规定了每个消息分区只能被同组的一个消费者进行消费,因此,需要在zookeeper上记录消费分区与consumer之间的关系,每个消费者一旦确定了对一个消息分区的消费权利,需要将其consumerid写入到zookeeper对应消息分区的临时节点上,例如:

/consumers/[group_id]/owners/[topic]/[broker_id-partition_id]

其中,[broker_id-partition_id]就是一个消息分区的标识,节点内容就是该消息分区上消费者的consumerid

消息消费进度offset记录

在消费者对指定消息分区进行消息消费的过程中,需要定时的将消息的消费进度offset记录到zookeeper上,以便在该消费者进行重启或者其他消费者重新接管该消息分区的消息消费后,能够从之前的消费进度开始消费。offset在zookeeper中由一个专门节点进行记录:

/consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]

节点内容就是offset的值

消费者注册

消费者服务器在初始化启动时加入消费者分区的步骤如下:

注册到消费者分组。每个消费者服务器启动时,都会到zookeeper的指定节点下创建一个属于自己的消费者节点,例如:/consumers/[group_id]/ids/[consumer_id],完成节点创建后,消费者就会将自己订阅的topic信息写入该临时节点。

对消费者分组中的消费者的变化注册监听。每个消费者都需要关注所属消费者分组中其他消费者服务器的变化情况,即对/consumers/[group_id]/ids节点注册子节点变化的watcher监听,一旦发现消费者增加或者减少,就触发消费者的负载均衡。

对broker服务器变化注册监听。消费者需要对/broker/ids/[0-N]中的节点进行监听,如果发现broker服务器列表发生变化,那么就根据具体情况来决定是否需要进行消费者负载均衡。

进行消费者负载均衡。为了让同一个topic下不同分区的消息尽量均衡的被多个消费者消费而进行消费者与消息分区分配的过程,通常,对于一个消费者分组,如果组内的消费者服务器发生变化或者broker服务器发生变更,会发出消费者负载均衡。