场景
一个集群中有多台机器,但是机器的配置不同,最好能够让配置好的机器上面的分片多一些,但是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上,所以大量的数据被写到了低配机器上,写入性能还是有瓶颈。