Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

  • Redis

  • Keydb

  • TiDB

  • MongoDB

  • Elasticsearch

    • Elasticsearch 运维知识地图:从安装配置到排障加速恢复
    • Elasticsearch 安装配置
    • 给Elasticsearch集群添加用户密码
    • Elasticsearch 分片和副本:容量怎么规划,改分片数为什么这么麻烦
      • 1. 分片(shard)和副本(replica)分别解决什么问题
      • 2. 分片数为什么创建后几乎不能改
      • 3. 副本数则可以随时动态调整
      • 4. 容量规划:分片数该设多少
      • 5. 坑
      • 6. 可复用要点
    • 单节点分片达到默认上限解决办法
    • Elasticsearch集群节点磁盘使用分配不均解决办法
    • Elasticsearch的模板template和映射mapping
    • Elasticsearch 分页查询三种方案:from/size、search_after、scroll 怎么选
    • Elasticsearch字符串搜索方式
    • Elasticsearch使用wildcard字段模糊匹配
    • ES数据迁移工具esm
    • Nginx Mirror 模块实现三套ES写入网关
    • ES单机多节点集群docker-compose一键安装
    • ElasticSearch 动态模板 使用方法
    • ES排障两件套:慢查询日志阈值配置 + tcpdump 抓包看真实请求
    • ES 集群恢复太慢?三个参数加速节点/分片恢复
    • Elasticsearch 常用 DSL 语句
    • Logstash迁移ES数据
  • Kafka

  • victoriametrics

  • BigData

  • Sqlserver

  • 数据库
  • Elasticsearch
Carry の Blog
2022-03-17
目录

Elasticsearch 分片和副本:容量怎么规划,改分片数为什么这么麻烦

版本说明

本文基于 Elasticsearch 7.x/8.x,分片数不可变的机制自 ES 诞生起从未改变。

# 1. 分片(shard)和副本(replica)分别解决什么问题

Elasticsearch 是分布式搜索引擎,一个索引的数据不会整体存在一台机器上,而是拆成若干分片分散到不同节点——这是它能水平扩展、并行处理查询的基础:分片数越多,理论上能并行处理的查询并发度越高(但不是越多越好,见下文)。

副本是分片的完整拷贝,解决的是另一个正交的问题:可用性和读吞吐。某个节点挂了,它上面的主分片如果有副本在别的节点上,集群可以直接把副本提升为主分片,数据不丢;同时查询请求可以分摊到主分片和副本上,提高读并发能力。

一句话区分:分片数决定写入和存储的水平扩展能力,副本数决定容错能力和读吞吐,两者独立配置,互不替代。

# 2. 分片数为什么创建后几乎不能改

PUT /my_index/_settings
{
  "settings": {
    "number_of_shards": 3
  }
}
1
2
3
4
5
6

这条命令实际上会报错——number_of_shards 是索引创建时就固定死的静态设置,_settings API 只能修改动态设置,不能用来改分片数。这是一个常见的误解,根源在于分片的物理机制:每个分片本质上是一个独立的 Lucene 索引实例,文档路由到哪个分片是通过 hash(routing) % number_of_shards 计算的——一旦分片数变了,这个哈希公式的结果全变,所有已经写入的文档理论上都要重新计算归属、重新分布,这就不是一个简单的"改配置"能完成的操作。

真的需要调整分片数,有两条路:

# 方式一:Reindex 到一个新建的、分片数不同的索引
PUT /my_index_v2
{ "settings": { "number_of_shards": 6 } }

POST /_reindex
{
  "source": { "index": "my_index" },
  "dest": { "index": "my_index_v2" }
}

# 方式二:用 Split/Shrink API(分片数必须是原数量的整数倍/因数关系)
POST /my_index/_split/my_index_v2
{
  "settings": { "number_of_shards": 6 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

_reindex 最灵活但需要重新写一遍全部数据,耗时耗资源;_split/_shrink 更轻量,但对分片数的倍数关系有限制(_split 要求新分片数是原分片数的整数倍,_shrink 反过来要求原分片数能被新分片数整除)。这也是为什么"分片数规划"必须在创建索引前就想清楚——事后补救的成本远高于事前规划。

# 3. 副本数则可以随时动态调整

PUT /my_index/_settings
{
  "settings": {
    "number_of_replicas": 2
  }
}
1
2
3
4
5
6

这条命令是有效的——副本数不影响文档路由算法,只是"多复制几份"或"少复制几份",ES 会在后台自动完成副本的创建或移除,不需要重建索引。

# 4. 容量规划:分片数该设多少

没有万能公式,但有一个业界常用的经验起点:单个分片大小控制在 20GB~50GB 之间。

建议分片数 ≈ 预计索引总数据量 / 单分片目标大小(如 30GB)
1

比如预计这个索引未来会累积到 300GB 数据,除以 30GB,大致 10 个主分片是合理起点。这个经验值背后的原因:分片太大,单个分片的查询和 merge 开销会显著增加,恢复/迁移这个分片时也更慢;分片太多,则每个分片自带的元数据开销(如 Lucene segment、集群状态里的分片元信息)会累积成不可忽视的额外负担,过多的小分片反而会拖累集群整体性能(俗称"分片过度" oversharding)。

一个常见反例:给一个预计只有几百 MB 数据的小索引设置成 20 个分片。这样做的后果是每个分片只有几十 MB 数据,远低于合理下限,集群要维护 20 份分片的元数据和 Lucene 实例开销,纯粹是浪费——小索引应该只给 1 个主分片(ES 7.0+ 的默认值已经改成了 1,早期版本默认是 5,这也是很多旧集群"分片过度"问题的历史根源)。

# 5. 坑

  • 修改分片和副本数量都可能触发数据重新分配/迁移(副本数增加时需要复制数据,分片重建需要 reindex),这个过程会占用集群 I/O 和网络资源,生产环境操作应安排在非高峰期。
  • 副本数不是越多越安全——每增加一份副本,就多一份存储和写入开销(写入需要同步到所有副本才算成功),单纯堆副本数不是免费的高可用。
  • 规划分片数时要结合节点数量:单个节点如果承载了同一索引的主分片和它的副本,节点故障时两份数据同时不可用,规划时要确认集群的分片分配策略(allocation.awareness 等)能让主副分片分散到不同节点/可用区。

# 6. 可复用要点

  1. 分片数创建后基本不可变,规划要"事前想清楚"而不是"事后再调";副本数可以随时动态调整。
  2. 单分片大小经验值控制在 20GB~50GB,用预计数据总量倒推分片数,避免分片过大或过度分片。
  3. 小索引不要给过多分片——分片数量本身有固定的元数据开销,过度分片是常见的性能反模式。
#Elasticsearch#搜索引擎
上次更新: 7/29/2026

← 给Elasticsearch集群添加用户密码 单节点分片达到默认上限解决办法→

最近更新
01
Nginx 运维知识地图:从配置基础到反向代理实战 原创
07-29
02
MySQL 运维知识地图:从入门配置到高可用排障 原创
07-29
03
单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」 原创
07-29
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式