afka在所有broker中选出一个controller,所有Partition的Leader选举都由controller决定。controller会将Leader的改变直接通过RPC的方式(比Zookeeper Queue的方式更高效)通知需为此作出响应的Broker。同时controller也负责增删Topic以及Replica的重新分配。
当有broker fari over controller的处理过程如下:
1.Controller在Zookeeper注册Watch,一旦有Broker宕机(这是用宕机代表任何让系统认为其die的情景,包括但不限于机器断电,网络不可用,GC导致的Stop The World,进程crash等),其在Zookeeper对应的znode会自动被删除,Zookeeper会fire Controller注册的watch,Controller读取最新的幸存的Broker
2.Controller决定set_p,该集合包含了宕机的所有Broker上的所有Partition
3.对set_p中的每一个Partition
3.1 从/brokers/topics/[topic]/partitions/[partition]/state读取该Partition当前的ISR
3.2 决定该Partition的新Leader。如果当前ISR中有至少一个Replica还幸存,则选择其中一个作为新Leader,新的ISR则包含当前ISR中所有幸存的Replica(选举算法的实现类似于微软的PacificA)。否则选择该Partition中任意一个幸存的Replica作为新的Leader以及ISR(该场景下可能会有潜在的数据丢失)。如果该Partition的所有Replica都宕机了,则将新的Leader设置为-1。
3.3 将新的Leader,ISR和新的leader_epoch及controller_epoch写入/brokers/topics/[topic]/partitions/[partition]/state。注意,该操作只有其version在3.1至3.3的过程中无变化时才会执行,否则跳转到3.1
- 直接通过RPC向set_p相关的Broker发送LeaderAndISRRequest命令。Controller可以在一个RPC操作中发送多个命令从而提高效率。
再平衡
建election.json文件
{"partitions":[{"topic":"topic_replica_test","partition":0},{"topic":"topic_replica_test","partition":1},{"topic":"topic_replica_test","partition":2}]}
使用election.json文件执行优先副本选举
/opt/cloudera/parcels/KAFKA/lib/kafka/bin/kafka-preferred-replica-election.sh --zookeeper zk1:2181 --path-to-json-file election.json
再次查看topic的partition分布情况,发现partition为2的分区leader已经调整成151为leader了。
/opt/cloudera/parcels/KAFKA/lib/kafka/bin/kafka-topics.sh --zookeeper zk1:2181 --topic topic_replica_test --describe
[一次因为kafka分区的leader不为优先副本导致的消费堆积问题的原因排查及问题解决方法(https://blog.csdn.net/cndotaci/article/details/106869798)