突然接到客户反馈,说设备在某天0点开始没有数据。经过确认各个模块运作正常,就是数据写入不了数据库,查询看没有当天的索引,这就很奇怪了。需要捕获一下es返回的错误:

"reason":"Validation Failed:1:this action would add [3] shards,but this cluster currently has [1000]/[1000] maximum normal shards open;"
因为ES默认允许活动的分片总数(包括主分片和副分片)是有限制的,导致无法创建新的索引。
Elasticsearch 中与打开索引数量相关的默认设置有一个:cluster.max_shards_per_node
,这个值默认为1000个(从7.4版本开始),这个值直接影响的是每个节点上可以拥有的打开的分片(包括主分片和副本分片)的最大数量,而不是直接限制索引的数量。也就是说,关闭索引的分片数不在这个限制值的统计范围以内,一旦因为达到max_shards_per_node
值而不能创建索引了,那么只要关闭一些索引就可以了。
统计当前打开的(活动的)分片总数
并没有现成的指令可以直接输出当前打开着的分片总数,_/cluster/stats统计出的是总分片数(包括没打开的),然而只要打开着的分片数小于cluster.max_shards_per_node的值就能创建新的索引,所以我们需要把活动中的分片数自己统计一下。
curl -sku $ES_USER:$ES_PASSWORD https://127.0.0.1:9200/_cat/indices?h=status,pri,rep | awk '{if ($1 =="open") print $2+$3}' | paste -sd+ | bc
_cat/indices查看所有索引这个api就会有pri(主分片数),rep(副分片数)2个字段,我们只调取 status , pri , rep 三列就好了,然后把 pri + rep 就是索引的总分片数,然后再把每一个索引的总分片数用 + 号连起来,bc计算一下结果,就是总的当前打开着的分片总数了。
可能有人问,cluster.max_shards_per_node
的值是不是能修改成更大的,答案当然是能。
curl -sku $ES_USER:$ES_PASSWORD "https://127.0.0.1:9200/_cluster/settings?include_defaults=true&filter_path=*.cluster.max_shards_per_node"
//{"defaults":{"cluster":{"max_shards_per_node":"1000"}}}
这里不加include_defaults=true,可能不会有返回结果,ES默认的配置项默认情况下不返回。
curl -XPUT -sku $ES_USER:$ES_PASSWORD "https://127.0.0.1:9200/_cluster/settings" -H 'Content-Type: application/json' -d '
{
"persistent": {
"cluster.max_shards_per_node": 2000
}
}'
_cluster/settings的设置可以冠以持久生效(persistent)和临时生效(transient)2种前缀包裹,持久生效设置会在集群重启后仍然有效,而临时生效设置只在集群运行期间有效,重启后会恢复到之前的设置。
上面将 cluster.max_shards_per_node 外层包裹在 persistent 下,也就是持久生效。要想临时生效,就将persistent换成transient。