重新梳理了 assignReplicasToBrokersRackUnaware() 和 assignReplicasToBrokersRackAware() 两个方法的思路。如有错误或不当欢迎指出。
未指定机架的分配策略
主要介绍是未指定机架信息的分配策略,Kafka 版本是 2.0.0,具体实现为 kafka.admin.AdminUtils.scala 文件中的 assignReplicasToBrokersRackUnaware() 方法,该方法的内容如下:
private def assignReplicasToBrokersRackUnaware(nPartitions: Int,//分区数replicationFactor: Int,//副本因子brokerList: Seq[Int],//集群中broker列表fixedStartIndex: Int,//起始索引,即第一个副本分配的位置,默认值为-1startPartitionId: Int): Map[Int, Seq[Int]] = {//起始分区编号,默认值为-1 // fixedStartIndex表示第一个副本分配的位置,默认为-1 // startPartitionId表示起始分区编号,默认为-1 // ret表示 的关系 val ret = mutable.MapInt, Seq[Int]//保存分配结果的集合 val brokerArray = brokerList.toArray //brokerId的列表 // 如果起始索引fixedStartIndex小于0,则根据broker列表长度随机生成一个,以此来保证是有效的brokerId val startIndex = if (fixedStartIndex >= 0) fixedStartIndex else rand.nextInt(brokerArray.length)
// 确保起始分区号不小于0 var currentPartitionId = math.max(0, startPartitionId)
// 指定了副本的间隔,目的是为了更均匀地将副本分配到不同的broker上 var nextReplicaShift = if (fixedStartIndex >= 0) fixedStartIndex else rand.nextInt(brokerArray.length)
// 轮询所有分区,将每个分区的副本分配到不同的broker上 for (_
//只有分区编号大于0且刚好分区编号已经轮流一遍broker时才递增下一个副本的间隔 if (currentPartitionId > 0 && (currentPartitionId % brokerArray.length == 0))
nextReplicaShift += 1
val firstReplicaIndex = (currentPartitionId + startIndex) % brokerArray.length
val replicaBuffer = mutable.ArrayBuffer(brokerArray(firstReplicaIndex))
// 保存该分区所有副本分配的broker集合 for (j
// 为其余的副本分配broker replicaBuffer += brokerArray(replicaIndex(firstReplicaIndex, nextReplicaShift, j, brokerArray.length))
// 保存该分区所有副本的分配信息 ret.put(currentPartitionId, replicaBuffer)
// 继续为下一个分区分配副本 currentPartitionId += 1
}
ret
}
该方法参数列表中的 fixedStartlndex 和 startPartitionld 值是从上游的方法 中调用传下来的,默认都是 -1 ,分别表示第一个副本分配的位置和起始分区编号。 assignReplicasToBrokersRackUnaware() 方法的核心是遍历每个分区 partition , 然后从 brokerArra