Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

ElasticSearch 分片数规划与计算

🎯 核心结论(先记住)

ElasticSearch 分片数一旦创建就不能修改,所以分片规划的核心目标是:

单个 Primary Shard 的最终大小控制在 20–50GB 之间(日志类更偏 20–30GB)

一、为什么分片数不能改?

分片路由算法:

shard = hash(_routing) % primary_shards
  • 决定数据存入哪个主分片
  • 改分片数 = 全量重建索引
  • ES 没有 “在线拆分主分片” 的能力(只能 shrink 减少)

👉 所以:分片数 = 建索引前必须想清楚的事情

通过对路由值进行哈希计算并取模,保证数据均匀分布在主分片中。这也是为何索引创建后主分片数量不能直接更改的原因。

详细解释:

  • shard:计算出的目标主分片(Primary Shard)的索引号。
  • hash(_routing):对 _routing 值计算哈希值(通常默认为文档的 _id)。这是将文档哈希为一个确定的数字。
  • %:取模运算符,即整除后的余数。
  • primary_shards:当前索引的主分片总数量。

工作流程与关键点:

  • 确定位置:当写入或查询文档时,ES 会根据 _routing 计算出对应的 shard 编号。
  • 数据均匀化:利用哈希函数的随机性,确保文档均匀地分布在所有主分片上。
  • 不可修改性:因为分片数是公式的除数,如果后续修改了主分片数量(如 primary_shards 从 3 变为 4),原有的 hash(_routing) 结果取模后的数值就会改变,导致之前的文档“消失”(因为查找时计算出了错误的分片位置)。

举例:如果有 3 个主分片(P0, P1, P2),_routing 为 id1,假设 hash(“id1”) 的结果为 (10),则 10 % 3 = 1。该文档将存储在 P1 上。

二、分片规划的 4 个关键输入参数(必须知道)

在规划前,你至少要知道这 4 个数:

参数 含义
D 每天数据量(GB/day)
T 索引保留周期(天)
R 副本数(replica)
S 单 shard 目标大小(GB)

三、最重要的公式(必背)

⭐ 分片数计算公式

Primary Shards = ⌈ ( D × T ) / S ⌉

副本不参与计算 primary shard 数量。

四、典型场景实战计算

场景 1:日志系统(最常见)

条件

  • 每天日志:100 GB
  • 索引周期:1 天(daily index)
  • shard 目标:25 GB

计算

Primary Shards = 100 / 25 = 4

结论

"number_of_shards": 4,
"number_of_replicas": 1

👉 最终磁盘:

100GB × (1 + 1) = 200GB

场景 2:大日志系统(热数据 7 天)

条件

  • 每天日志:200 GB
  • Hot 数据保留:7 天
  • shard 目标:30 GB
Primary Shards = (200 × 7) / 30 ≈ 47

⚠️ 不建议单索引 47 shard

👉 正确做法:

  • 使用 daily index + rollover
  • 每天一个索引,每个索引 7 shard

场景 3:业务搜索索引(长期存在)

条件

  • 当前数据量:300 GB
  • 未来一年预计增长到:1 TB
  • shard 目标:40 GB
Primary Shards = 1000 / 40 = 25

👉 创建索引时:

number_of_shards = 24 或 25

五、日志系统的最佳实践(强烈推荐)

❌ 错误做法

1 个索引,100+ shard

✅ 正确做法

daily index + rollover + ILM

示例

"rollover": {
  "max_size": "30gb",
  "max_age": "1d"
}

好处:

  • 分片数自动控制
  • shard 永远不超大
  • 方便冷热分离

六、不同业务类型的 shard 推荐值

场景 shard 大小
高频写入日志 20–30 GB
普通日志 30–40 GB
搜索型业务 30–50 GB
冷数据 50–100 GB

七、集群维度的约束(非常重要)

1️⃣ 每个节点 shard 数上限

经验值:

< 20 shard / GB heap

例如:

  • 32GB heap -> ~600 shard(含 replica)

2️⃣ shard 数不是越多越好

shard 太多 shard 太大
集群状态臃肿 查询慢
内存浪费 merge 压力大
GC 频繁 恢复慢

👉 宁可稍微大一点,也不要太多

八、预留未来扩展(非常关键)

规划时 至少预留 30%–50% 冗余:

预计一年后 1TB -> 按 1.3TB 规划

九、如果现在规划错了怎么办?

1️⃣ 使用 rollover(最优解)

  • 控制 shard 大小
  • 不再关心“单索引分片数”

2️⃣ Reindex

  • 重建索引(代价高)

3️⃣ Shrink(只能减不能增)

POST index/_shrink/index_shrinked

十、总结

ElasticSearch 的主分片数一旦创建就不能修改,所以我在前期会根据 每天数据量 × 保留周期 ÷ 单 shard 目标大小 来计算。

实践中我会把单 shard 控制在 20–50GB, 日志系统用 daily index + rollover + ILM, 同时预留 30% 的增长空间,避免后期重建索引。