下面以三个节点,主分片为3,副本为1的情况进行说明:
核心逻辑是通过计算权重来分配分片到节点,权重计算逻辑:首先计算分片的权重(节点的分片数量-每个节点的平均分片),然后是索引的权重(节点上索引的分片数量减去每个节点对应索引的平均分片数);最终的权重值就是:0.45(分片平衡因子的默认值)*分片的权重+0.55(索引平衡因子的默认值)*索引的权重,得到的结果即为权重值;另外在计算权重值的时候es首先假设将此分片分配到这个节点上,然后进行计算,计算完之后会remove掉。第一个主分片循环
1.循环第一个节点的时候->计算权重值为-1(分片的权重为-1,索引的权重为-1,最终计算就是-1),因为-1小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
2.循环第二个节点->计算权重值为-1(分片的权重为-1,索引的权重为-1,最终计算就是-1),因为-1等于minWeight并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合继续下一个节点,符合条件就像前面那样赋值)。3.第三个节点->计算权重值为-1,因为-1等于minWeight并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合跳出节点循环(此时就是跳出循环不赋值),符合条件就像前面那样赋值。跳出循环之后,如果minNode不为空,则将此分片分配到这个节点上,并进行初始化等操作。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0
第二个主分片开始循环
1.循环第一个节点的时候->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
2.循环第二个节点->计算权重值为-1(分片的权重为-1,索引的权重为-1,最终计算就是-1),因为-1小于minWeight(此时minWeight已是0)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。3.第三个节点->计算权重值为-1,因为-1等于minWeight并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合跳出节点循环(此时就是跳出循环不赋值),符合条件就像前面那样赋值。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0
N57J9WrZQPCEL6GvbXEonQ 1
第三个主分片开始循环
1.循环第一个节点的时候->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
2.循环第二个节点->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0等于minWeight(此时minWeight已是0)并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合跳出节点循环(此时就是跳出循环不赋值),符合条件就像前面那样赋值。3.第三个节点->计算权重值为-1,因为-1小于minWeight(此时minWeight已是0)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0
N57J9WrZQPCEL6GvbXEonQ 1
Ckva8gbbSpuFvlecvw5p5Q 2
此时主分片已经分配完,开始副本分配;在分配副本分片的时候,会调用decision判断主分片是否已经激活,如果没有得需要等到副本分片对应的主分片分配完之后才能分配副本分片。
第一个副本分片开始循环
1.循环第一个节点的时候->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision是NO(因为相同分片不能分配到相同节点),所以此处没有赋值,继续循环。
2.循环第二个节点->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。3.第三个节点->计算权重值为0,因为0等于minWeight(此时minWeight已是0)并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合跳出节点循环(此时就是跳出循环不赋值),符合条件就像前面那样赋值。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0
N57J9WrZQPCEL6GvbXEonQ 1 0
Ckva8gbbSpuFvlecvw5p5Q 2
第二个副本分片开始循环
1.循环第一个节点的时候->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
2.循环第二个节点->计算权重值为1(分片的权重为1,索引的权重为1,最终计算就是1),因为1大于minWeight(minWeight此时为0)直接跳出继续循环下一个节点。3.第三个节点->计算权重值为0,因为0等于minWeight(此时minWeight已是0)并且decision都是YES,然后进行下列复杂的判断(此处见最后的说明),不符合跳出节点循环,符合条件就像前面那样赋值(此时符合条件)。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0
N57J9WrZQPCEL6GvbXEonQ 1 0
Ckva8gbbSpuFvlecvw5p5Q 2 1
第三个副本分片开始循环
1.循环第一个节点的时候->计算权重值为0(分片的权重为0,索引的权重为0,最终计算就是0),因为0小于minWeight(minWeight为1.0f / 0.0f)并且decision都是YES,所以把当前节点赋给minNode,把当前权重赋给minWeight,把当前的decision结果赋给decision。
2.循环第二个节点->计算权重值为1(分片的权重为1,索引的权重为1,最终计算就是1),因为1大于minWeight(minWeight此时为0)直接跳出继续循环下一个节点。3.第三个节点->计算权重值为1(分片的权重为1,索引的权重为1,最终计算就是1),因为1大于minWeight(minWeight此时为0)直接跳出继续循环下一个节点。
节点名称 主分片 副本分片
lrUOpMcLT4eEAVAm2zGcpA 0 2
N57J9WrZQPCEL6GvbXEonQ 1 0
Ckva8gbbSpuFvlecvw5p5Q 2 1
复杂判断代码如下:
这段代码的主要作用就是:诸如上面的情形,当主分片0,1,2分别分配到了节点a,b,c上的时候,会避免出现如下情形,副本1,0分别分配到了a,b节点上,由于相同分片不能分配到相同节点上,并且每个节点要保持分片数相同,那么这样就会导致副本分片2无处分片,这段代码的作用正在于此。