在对集群进行扩容或者替换节点的时候,不可避免会有移动分片的操作,可以使用如下的语句进行操作,首先要关闭自动reshard
cluster.routing.allocation.disable_allocation = false
然后可以使用move、cancel以及allocate进行分片的移动、取消分配以及重新分配没有分配的shard到指定节点。
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
"commands" : [ {
"move" :
{
"index" : "test", "shard" : 0,
"from_node" : "node1", "to_node" : "node2"
}
},
"cancel" :
{
"index" : "test", "shard" : 0, "node" : "node1"
}
},
{
"allocate" : {
"index" : "test", "shard" : 1, "node" : "node3"
}
}
]
}'
当然,推荐使用kopf插件,对以上操作进行可视化操作,更直观容易。
但是以上方式,对于分片很少的情况下是适用的,如果需要转移的节点很多就有些太过于麻烦了。
当然ES默认是开启自动reshard功能的,也就是说设置
cluster.routing.allocation.disable_allocation = true
ES会按照同node不能存相同shard、shard分片分配平均等因素进行重新平衡。如果我们是进行扩容,那么把扩容的节点加进来,然后开启自动reshard功能,我们就可以坐等平衡结束了。
但是如果我们是想要替换掉部分节点,那么如果按照以上操作,会将所有的节点在所有的节点上进行平衡,那么我们要下掉的节点也会平均分布着分片数据。待平衡后,我们想要下掉某个节点,还是需要转移走这部分分片,而且原来的处理方式是手工的。。。很明显,这种方式太原始,而且浪费了之前平衡花费的时间和流量。那么有没有什么配置,让ES平衡节点的时候不向上面分配分片,或者更进一步直接将原有分片“赶出去”呢?
可以尝试使用下面的命令
curl -XPUT 'localhost:9200/_cluster/settings' -d
'{
"transient": {
"cluster.routing.allocation.exclude._ip": "192.168.0.1,192.168.0.2"
}
}'
让ES不再向这两个ip的node进行分片分配。这个配置还可以使用_name以及_host等。可以参考官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/allocation-filtering.html