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

文章讲述了在Java代码向Elasticsearch写入索引时遇到的分片数量限制问题,通过调整`cluster.max_shards_per_node`配置解决。作者详细介绍了该参数的作用、验证过程以及如何修改配置以适应更多分片需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

  • 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}}'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值