自定义分片分配

场景

一个集群中有多台机器,但是机器的配置不同,最好能够让配置好的机器上面的分片多一些,但是es自己的策略貌似不会考虑到机器的配置,配置高低的机器上分片的数量差不多

自定义分片分配数量

对于一个索引来说,配置高的机器上分片更多一些

分配策略:排除低配节点

ES提供了api,可以排除低配的节点,但是不能所有的索引都排除某个低配节点,假设现在有三个索引,三个低配节点,那么可以采用如下的排除策略:

  • 索引1排除低配节点2、3
  • 索引2排除低配节点1、3
  • 索引3排除低配节点1、2

最终的效果是:三个索引,每个索引由原来占用三个低配节点变成只占用一个低配节点,低配节点的压力降低了2/3

分配策略:手动移动分片

  • 先采用默认的索引创建策略,在所有的节点上创建分片
高配1 高配2 高配3 低配1 低配2 低配3
2、4 1、3 0 3 0、1 2、4
  • 需要进行分片移动的节点为低配1、2、3,按照分片数量进行排序,按照总分片数量从多到少开始遍历移动
  • 对高配节点1、2、3的分片数量进行排序(或者根据磁盘空间占用进行排序更合理?
  • 遍历低配节点,按照总分片数量从多到少遍历,从高配节点中分片数量最少的节点开始移动分片
    • 低配1上面的分片3,需要优先移动到高配3上
    • 低配2上的分片0、1中的一个分片移动到高配2,因为1有冲突,所以移动0
    • 低配3上的分片2、4跟高配1上的分片完全冲突,所以无法移动,不进行移动

移动完成的结果为:

高配1 高配2 高配3 低配1 低配2 低配3
2、4 1、3、0 0、3 - 1 2、4

发现上面这种方式并不是所有情况试用,有可能最后剩下低配3和高配1,但是两者的分片完整互为主备,所以无法移动

此时可以通过进行递归迭代再对失败的节点进行重新分配:

  • 失败的节点为低配3,按照分片从多到少排序
  • 高配节点1、2、3,按照分片从少到多排序
  • 低配3优先选择高配1,但是分片冲突,不进行分配
  • 继续选择高配3,发现可以分派,所以将分片2分配到高配3上

最终移动完成的结果为:

高配1 高配2 高配3 低配1 低配2 低配3
2、4 1、3、0 0、3、2 - 1 4

自定义分片的数据量

配置高低的机器上的分片数量还是按照默认的策略,也就是说大概相同,但是通过自定义的路由策略,让配置高的机器上的分片的数据量更大一些

实现方式

shard_num = hash(_routing) % num_primary_shards

  • 获取分片的总数
  • 获取各个节点上的分片的编号

这种方案有问题:

因为分片都是有副本的,假设分片0分配制高配机器1上,那么通过指定路由,将大部分数据写在分片0上,但是分片0的副本可能在低配机器2上,所以大量的数据被写到了低配机器上,写入性能还是有瓶颈。