es 报错 this action would add xx total shards, but this cluster currently has xx maximum shards open

背景

  • java 代码在写入 es 时,报错 Validation Failed: 1: this action would add [6] total shards, but this cluster currently has [3996]/[4000] maximum shards open;
  • 报错原因是要写入的索引需要 6 个分片,但是当前集群的分片上限是 4000,当前已经使用了 3996 个分片,因为可用分片数不够了,导致索引插入 es 失败了,解决方法是通过 curl 命令去配置 /_cluster/settingscluster.max_shards_per_node 参数,把这个参数加大就可以了,下面就这个参数的值,做了一个学习

学习之路

es 7.4 关于 cluster.max_shards_per_node 参数的解释

  • The limit defaults to 1,000 shards per data node
    • 限制默认为每个数据节点1000个分片
  • For example, a 3-node cluster with the default setting would allow 3,000 shards total, across all open indexes. If the above setting is changed to 500, then the cluster would allow 1,500 shards total.
    • 例如,具有默认设置的3节点集群将允许在所有打开的索引中总共有3000个碎片。如果将上述设置更改为500,则集群将总共允许1500个碎片。
  • 从官方文档翻译来看,集群的总分片数,就是 cluster.max_shards_per_node 乘以节点的数量

让我们验证一下

curl 192.168.11.162:19200/_cat/allocation?v

我这里是新部署的一个集群,当前集群没有数据,所以目前分片数都是 0

     0           0b     2.6gb     92.3gb     94.9gb            2 192.168.11.164 192.168.11.164 es-2
     0           0b     2.6gb     92.3gb     94.9gb            2 192.168.11.162 192.168.11.162 es-0
     0           0b     2.6gb     92.3gb     94.9gb            2 192.168.11.163 192.168.11.163 es-1
  • 批量创建 1662 副本 6 分片的索引
    • 1个2副本6分片的索引占用3*6=18个分片
    • 166个2副本6分片的索引占用166*3*6=2988个分片
for i in $(seq -w 1 166);do curl -XPUT "192.168.11.162:19200/20231130${i}" -H 'Content-Type: application/json' -d '{"settings": {"number_of_shards": 6,"number_of_replicas": 2}}';done
  • 按照上面的官方文档来看,我三节点的集群,上限是 3000 个分片,所以:
    • 我创建一个 2副本6分片 的索引时,会创建失败
    • 我创建一个 1副本6分片的索引时,会创建成功
  • 下面我们一一尝试来验证一下
curl -XPUT "192.168.11.162:19200/20231130167" -H 'Content-Type: application/json' -d '{"settings": {"number_of_shards": 6,"number_of_replicas": 2}}'

返回报错

{"error":{"root_cause":[{"type":"validation_exception","reason":"Validation Failed: 1: this action would add [18] total shards, but this cluster currently has [2988]/[3000] maximum shards open;"}],"type":"validation_exception","reason":"Validation Failed: 1: this action would add [18] total shards, but this cluster currently has [2988]/[3000] maximum shards open;"},"status":400}

此时插入一个 1副本6分片的索引试试

curl -XPUT "192.168.11.162:19200/20231130167" -H 'Content-Type: application/json' -d '{"settings": {"number_of_shards": 6,"number_of_replicas": 1}}'

此时是创建成功的,查看一下当前集群的分片总数

curl 192.168.11.162:19200/_cat/allocation?v

可以看到,每个节点刚好 1000 个分片,验证了 cluster.max_shards_per_node 这个参数,默认就是 1000,并且集群的总索引数就是 cluster.max_shards_per_node 乘以节点的数量

shards disk.indices disk.used disk.avail disk.total disk.percent host           ip             node
  1000      276.1kb     2.6gb     92.2gb     94.9gb            2 192.168.11.162 192.168.11.162 es-0
  1000      276.1kb     2.6gb     92.2gb     94.9gb            2 192.168.11.164 192.168.11.164 es-2
  1000      276.1kb     2.6gb     92.2gb     94.9gb            2 192.168.11.163 192.168.11.163 es-1

查看 cluster.max_shards_per_node 的配置

curl -XGET "192.168.11.162:19200/_cluster/settings"

新集群,没有配置过 /_cluster/settings 的情况下,返回的内容如下

{"persistent":{},"transient":{}}
  • /_cluster/settings 中,有三个部分,分别是 persistenttransientdefaults
    • persistent
      • 这是持久性集群设置。它们是永久性的,一旦设置,将一直保持,直到显式更改。这些设置将在集群重新启动后仍然保持。
    • transient
      • 这是瞬时性集群设置。可以在不重新启动整个集群的情况下进行临时性的更改。这些更改将在集群重新启动后失效。
    • defaults
      • 查看 Elasticsearch 预定义的集群设置的默认值。但它并不是一个用于修改集群设置的参数。
      • 查看 defaults 的方法:
        • curl -XGET "<es_ip>:<es_port>/_cluster/settings?include_defaults&flat_settings"
          • include_defaults - 包括集群设置和默认设置
          • flat_settings - 以单层结构呈现参数,更易于阅读

修改 cluster.max_shards_per_node 的配置

这里将 cluster.max_shards_per_node 设置为 2000,表示集群最大索引数是 2000*3=6000

curl -XPUT "192.168.11.162:19200/_cluster/settings" -H 'Content-Type: application/json' -d '
{
  "persistent":
    {
      "cluster.max_shards_per_node": 2000
    }
}'

验证配置,后面的 python 命令不是必须的,这个只是为了格式化 json,看起来更方便点

curl -s -XGET "192.168.11.162:19200/_cluster/settings" | python -m json.tool

可以看到,这里已经有 cluster.max_shards_per_node 的参数了

{
    "persistent": {
        "cluster": {
            "max_shards_per_node": "2000"
        }
    },
    "transient": {}
}

增加索引验证

这个时候,我们再插入 2副本6分片 的索引就不会再报错了

curl -XPUT "192.168.11.162:19200/20231130168" -H 'Content-Type: application/json' -d '{"settings": {"number_of_shards": 6,"number_of_replicas": 2}}'
posted @   月巴左耳东  阅读(169)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2020-11-30 suse 12 配置ip,dns,网关,hostname,ssh以及关闭防火墙
点击右上角即可分享
微信分享提示