kafka 非常难,难在 broker 有角色之分,controller 起控制作用,难在副本有角色之分,leader 提供读写服务,所以 broker 会有状态的切换,副本也有状态的切换。
从一个具体的场景切入,4 节点集群(b1, b2, b3, b4),存在 1 个分区 tp0 分布在 (b1, b2) 上,现在通过执行命令行,希望使 tp0 的副本迁移到 (b3, b4) 上。
命令行程序把副本分配的方案写入 zk,controller 监听 zk 的变化,并处理这个请求,代码入口:
// kafka.controller.KafkaController#onPartitionReassignment
* AR leader/isr * {1,2} 1/{1,2} (initial state) * {1,2,3,4} 1/{1,2} (step 2) * {1,2,3,4} 1/{1,2,3,4} (step 4) * {1,2,3,4} 3/{1,2,3,4} (step 7) * {1,2,3,4} 3/{3,4} (step 8) * {3,4} 3/{3,4} (step 10)
副本在 kafka 集群中的变化如上图,其中涉及的主要单元操作包括:新建副本,选举,停止副本。
副本的状态由 controller 进行管理,controller 决定副本的状态,并通知各 broker 做实际操作。
LeaderAndIsrRequest
controller 通知 broker,指定分区的 leader, isr 列表,replica 列表。
这个请求对应的职责:新建副本,通知副本切换成 leader,通知副本切换成 follower。
StopReplicaRequest
通知 broker 停止副本