# 查询集群各节点角色
$ curl http://127.0.0.1:9200/_cat/nodes?pretty
192.168.2.24 46 92 32 2.89 2.56 2.35 mdi - 192.168.2.24
192.168.2.26 63 99 10 0.34 0.54 0.50 mdi - 192.168.2.26
192.168.2.25 60 90 10 1.06 1.11 1.10 mdi * 192.168.2.25
# 查询集群状态
$ curl http://127.0.0.1:9200/_cluster/health?pretty
{
"cluster_name" : "TEST",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 470,
"active_shards" : 943,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
# 查询集群配置
$ curl -XGET "http://127.0.0.1:9200/_cluster/settings?pretty"
{
"persistent" : { },
"transient" : {
"cluster" : {
"routing" : {
"rebalance" : {
"enable" : "all"
},
"allocation" : {
"cluster_concurrent_rebalance" : "4",
"enable" : "all"
}
}
},
"indices" : {
"recovery" : {
"max_bytes_per_sec" : "200mb"
}
}
}
}
# 关闭shard自平衡
curl -XPUT http://xx.xx.xx.x:9200/_cluster/settings -d '{
"transient" : {
"cluster.routing.allocation.enable" : "none"
}
}'
# 开启shard自平衡
curl -XPUT http://xx.xx.xx.x:9200/_cluster/settings -d '{
"transient" : {
"cluster.routing.allocation.enable" : "all"
}
}'
#查看所有分片
curl -XGET http://xx.xx.xx.xx:9200/_cat/shards
# 查看所有分片状态
curl -XGET http://127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason,details
# 查看所有主分片状态
curl -XGET http://127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason,details | grep -w "p"
# 查看所有副本片状态
curl -XGET http://127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason,details | grep -w "r"
# 查看所有 unassigned 状态 分片
curl -XGET http://127.0.0.1:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason,details | grep "UNASSIGNED
"
# 设置的延迟分片分配时间
当一个 点从集群中下线了, es 有一个延迟拷贝机制, 默认是等一分钟之后再开始处理 unassigned 的分片, 该做 rebalance的去 rebalance,只所以这样, 是因为es担心如果一个点只是中断了片刻, 或者临时下线某台机器,就立马大动干。
curl -XPUT 'http://xx.xx.xx.xx:9200/<INDEX_NAME>/_settings' -d '
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "60s"
}
}'
# 设置副本数
## 只要主分片
curl -XPUT 'http://xx.xx.xx.xx:9200/<INDEX_NAME>/_settings' -d '{"number_of_replicas": 0}'
## 主分片+ 1个副本分片
curl -XPUT 'http://xx.xx.xx.xx:9200/<INDEX_NAME>/_settings' -d '{"number_of_replicas": 1}'
# 查看各节点磁盘使用情况
curl -s 'localhost:9200/_cat/allocation?v'
shards disk.indices disk.used disk.avail disk.total disk.percent host ip node
315 19.7gb 415.8gb 591.9gb 1007.7gb 41 192.168.218.26 192.168.218.26 192.168.218.26
314 15gb 91.3gb 400.6gb 492gb 18 192.168.218.25 192.168.218.25 192.168.218.25
314 17.3gb 168.4gb 323.5gb 492gb 34 192.168.218.24 192.168.218.24 192.168.218.24
# 设置 low disk watermark的磁盘使用比(默认满85%,就无法分配副本)
curl -XPUT 'http://xx.xx.xx.xx:9200/_cluster/settings' -d
'{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "90%"
}
}'
# 提升重启后的恢复速度
增大这个设置项的值:cluster.routing.allocation.node_initial_primaries_recoveries
含义:一个节点上,同时处于初始化过程的主分片数量默认为4,给大一点
curl -XPUT "http://xx.xx.xx.xx:9200/_cluster/settings" \
-H "Content-type: application/json" \
-d '{
"transient":
{
"cluster.routing.allocation.node_initial_primaries_recoveries":12
}
}'
# 重新分配失败的分片
默认索引的尝试次数为5,可以将此参数调大尝试reroute,或许有奇效
curl -XPUT http://xx.xx.xx.xx:9200/<INDEX_NAME>/_settings -d '{
"index": {
"allocation": {
"max_retries": 20
}
}
}'
# 对指定分片做主机迁移
curl -XPUT http://xx.xx.xx.xx:9200_cluster/reroute -d '
{
"commands": [
{
"move": {
"index": "test",
"shard": 17,
"from_node": "pt01-pte-10-2-4-22",
"to_node": "pt01-pte-10-2-4-25"
}
}
]
}'
# 每个分片只有 一个 主分片,没有其他副本, 数据没有副本, 集群检测到这个分片的 全局状态文件,但是没有找到原始数据, 就没法进行恢复。
这个时候,你可以考虑下,是继续等待原来的那台机器恢复然后加入集群,还是重新强制分配 这些 unassigned 的分片, 重新分配的时候也可以使用备份数据
如果你打算重新强制分配主分片,可以使用下面的命令 , 记得带上"allow_primary": "true"
curl -XPOST 'xx.xx.xx.xx:9200/_cluster/reroute' -d '{
"commands": [
{
"allocate": {
"index": "test",
"shard": 0,
"node": "<NODE_NAME>",
"allow_primary": "true"
}
}
]
}'
# 你可以在重新强制分配主分片的时候,可以创建一个 empty 的主分片,也就是老数据不要了
这个时候,如果失联的 node 重新加入集群后, 就把自己降级了, 片的数据也分会使用 这个 empty 的主分片覆盖, 因为它已经变成过时的版本了
如果此分片的主副都已经损坏,则可将此分片置为空以保留索引其他分片数据:
{
"commands": [
{
"allocate_empty_primary": {
"index": "<INDEX_NAME>",//索引名
"shard": 3,//操作的分片id
"node": "node1",//空分片要分配的节点
"accept_data_loss": true//提示数据可能会丢失
}
}
]
}
curl -XPOST 'xx.xx.xx.xx:9200/_cluster/reroute' -d '
{
"commands": [
{
"allocate_empty_primary": {
"index": "test",
"shard": 0,
"node": "<NODE_NAME>",
"accept_data_loss": true
}
}
]
}'
# 查看索引存储状态
curl -X GET http://xx.xx.xx.xx:9200/_shard_stores?pretty
{
"indices" : { }
}
$ curl -X GET http://xx.xx.xx.xx:9200/<INDEX_NAME>/_shard_stores?pretty
{
"indices" : { }
}
# 如果索引损坏导致api失效,则需要人工去数据目录进行查找副本分片位置,目录结构如下:
数据目录下为节点号 -> 索引文件夹 -> 索引ID -> 分片号
data/nodes/0/indices/Z60wvPOWSP6Qbk79i757Vg/0
# 如果集群存在大量索引分片无法恢复,则可以使用脚本将全部分片置空,可以基于下面的脚本修改:
#!/bin/bash
master=$(curl -s 'http://localhost:9200/_cat/master?v' | grep -v ' ip ' | awk '{print $1}')
for index in $(curl -s 'http://localhost:9200/_cat/shards' | grep UNASSIGNED | awk '{print $1}' | sort | uniq); do
for shard in $(curl -s 'http://localhost:9200/_cat/shards' | grep UNASSIGNED | grep $index | awk '{print $2}' | sort | uniq); do
echo $index $shard
curl -XPOST -H 'Content-Type: application/json' 'http://localhost:9200/_cluster/reroute' -d '{
"commands" : [ {
"allocate_empty_primary" : {
"index" : "'$index'",
"shard" : "'$shard'",
"node" : "'$master'",
"accept_data_loss" : true
}
}
]
}'
sleep 1
done
done
# 查看unassigned shards 原因
$ curl -X GET http://xx.xx.xx.xx:9200/_cluster/allocation/explain?pretty
{
"error" : {
"root_cause" : [
{
"type" : "illegal_state_exception",
"reason" : "unable to find any unassigned shards to explain [ClusterAllocationExplainRequest[useAnyUnassignedShard=true,includeYesDecisions?=false]"
}
],
"type" : "illegal_state_exception",
"reason" : "unable to find any unassigned shards to explain [ClusterAllocationExplainRequest[useAnyUnassignedShard=true,includeYesDecisions?=false]"
},
"status" : 500
}
参考
ES实战-分片分配失败解决方案
https://www.jianshu.com/p/ffe4761dc79a
彻底解决 es 的 unassigned shards 症状
https://www.cnblogs.com/lvzhenjiang/p/14196973.html
网友评论