轻拔琴弦|Kafka设计原理详解

Kafka核心总控制器Controller在Kafka集群中会有一个或者多个broker , 其中有一个broker会被选举为控制器(Kafka Controller) , 它负责管理整个集群中所有分区和副本的状态 。

  • 当某个分区的leader副本出现故障时 , 由控制器负责为该分区选举新的leader副本 。
  • 当检测到某个分区的ISR集合发生变化时 , 由控制器负责通知所有broker更新其元数据信息 。
  • 当使用kafka-topics.sh脚本为某个topic增加分区数量时 , 同样还是由控制器负责让新分区被其他节点感知到 。
Controller选举机制在kafka集群启动的时候 , 会自动选举一台broker作为controller来管理整个集群 , 选举的过程是集群中每个broker都会尝试在Zookeeper上创建一个 /controller 临时节点 , zookeeper会保证有且仅有一个broker能创建成功 , 这个broker就会成为集群的总控器controller 。当这个controller角色的broker宕机了 , 此时zookeeper临时节点会消失 , 集群里其他broker会一直监听这个临时节点 , 发现临时节点消失了 , 就竞争再次创建临时节点 , 就是我们上面说的选举机制 , zookeeper又会保证有一个broker成为新的controller 。
  • 监听broker相关的变化 。 为Zookeeper中的/brokers/ids/节点添加BrokerChangeListener , 用来处理broker增减的变化 。
  • 监听topic相关的变化 。 为Zookeeper中的/brokers/topics节点添加TopicChangeListener , 用来处理topic增减的变化;为Zookeeper中的/admin/delete_topics节点添加TopicDeletionListener , 用来处理删除topic的动作 。
  • 从Zookeeper中读取获取当前所有与topic、partition以及broker有关的信息并进行相应的管理 。 对于所有topic所对应的Zookeeper中的/brokers/topics/[topic]节点添加PartitionModificationsListener , 用来监听topic中的分区分配变化 。
  • 更新集群的元数据信息 , 同步到其他普通的broker节点中 。
Partition副本选举Leader机制controller感知到分区leader所在的broker挂了(controller监听了很多zk节点可以感知到broker存活) , controller会从每个parititon的 replicas 副本列表中取出第一个broker作为leader , 当然这个broker需要也同时在ISR列表里 。
消费者消费消息的offset记录机制每个consumer会定期将自己消费分区的offset提交给kafka内部topic:__consumer_offsets , 提交过去的时候 , key是consumerGroupId+topic+分区号 , value就是当前offset的值 , kafka会定期清理topic里的消息 , 最后就保留最新的那条数据 , 因为__consumer_offsets可能会接收高并发的请求 , kafka默认给其分配50个分区(可以通过offsets.topic.num.partitions设置) , 这样可以通过加机器的方式抗大并发 。
消费者Rebalance机制消费者rebalance就是说如果consumer group中某个消费者挂了 , 此时会自动把分配给他的分区交给其他的消费者 , 如果他又重启了 , 那么又会把一些分区重新交还给他 。
注意:rebalance只针对subscribe这种不指定分区消费的情况 , 如果通过assign这种消费方式指定了分区 , kafka不会进行rebanlance 。
如下情况可能会触发消费者rebalance
  • consumer所在服务重启或宕机了
  • 动态给topic增加了分区
  • 消费组订阅了更多的topic
Rebalance过程第一阶段:选择组协调器
组协调器GroupCoordinator:每个consumer group都会选择一个broker作为自己的组协调器coordinator , 负责监控这个消费组里的所有消费者的心跳 , 以及判断是否宕机 , 然后开启消费者rebalance 。
consumer group中的每个consumer启动时会向kafka集群中的某个节点发送 FindCoordinatorRequest 请求来查找对应的组协调器GroupCoordinator , 并跟其建立网络连接 。


推荐阅读