--- title: "索引主分片数配置" date: 2026-03-22 lastmod: 2026-03-22 description: "控制索引主分片数量的配置项说明" tags: ["索引配置", "分片管理", "性能优化"] summary: "配置项作用 # index.number_of_shards 配置项指定索引的主分片数量。主分片是索引数据的水平切分单位,每个主分片是一个独立的 Lucene 索引。此配置在索引创建时设置,创建后无法修改。 配置项类型 # 该配置项为静态配置,只能在创建索引时设置,创建后无法修改。 默认值 # 1 是否必需 # 可选配置项(有默认值) 取值范围 # 1 ~ 1024(可通过系统属性调整) 配置格式 # # 创建索引时设置 PUT /my_index { "settings": { "index.number_of_shards": 3 } } # 在模板中设置 PUT /_template/my_template { "index_patterns": ["logs-*"], "settings": { "index.number_of_shards": 5 } } 工作原理 # 主分片是数据分布的基本单位: ┌─────────────────────────────────────────────────────────────────┐ │ 索引分片架构 │ └─────────────────────────────────────────────────────────────────┘ 索引: my_index (3 个主分片,1 个副本) │ ├── 主分片 0 (Primary) │ ├── 数据: Doc A, Doc D, Doc G │ └── 副本 0 (Replica) │ ├── 主分片 1 (Primary) │ ├── 数据: Doc B, Doc E, Doc H │ └── 副本 1 (Replica) │ └── 主分片 2 (Primary) ├── 数据: Doc C, Doc F, Doc I └── 副本 2 (Replica) 集群节点分布: ┌──────────┬──────────┬──────────┐ │ 节点 1 │ 节点 2 │ 节点 3 │ ├──────────┼──────────┼──────────┤ │ P0, R1 │ P1, R2 │ P2, R0 │ │ │ │ │ │ (分片分布可以自动平衡) │ └──────────┴──────────┴──────────┘ 分片路由机制 # 文档通过路由算法分配到特定分片:" --- ## 配置项作用 `index.number_of_shards` 配置项指定索引的主分片数量。主分片是索引数据的水平切分单位,每个主分片是一个独立的 Lucene 索引。此配置在索引创建时设置,创建后**无法修改**。 ## 配置项类型 该配置项为**静态配置**,只能在创建索引时设置,创建后无法修改。 ## 默认值 ``` 1 ``` ## 是否必需 **可选配置项**(有默认值) ## 取值范围 ``` 1 ~ 1024(可通过系统属性调整) ``` ## 配置格式 ```yaml # 创建索引时设置 PUT /my_index { "settings": { "index.number_of_shards": 3 } } # 在模板中设置 PUT /_template/my_template { "index_patterns": ["logs-*"], "settings": { "index.number_of_shards": 5 } } ``` ## 工作原理 主分片是数据分布的基本单位: ``` ┌─────────────────────────────────────────────────────────────────┐ │ 索引分片架构 │ └─────────────────────────────────────────────────────────────────┘ 索引: my_index (3 个主分片,1 个副本) │ ├── 主分片 0 (Primary) │ ├── 数据: Doc A, Doc D, Doc G │ └── 副本 0 (Replica) │ ├── 主分片 1 (Primary) │ ├── 数据: Doc B, Doc E, Doc H │ └── 副本 1 (Replica) │ └── 主分片 2 (Primary) ├── 数据: Doc C, Doc F, Doc I └── 副本 2 (Replica) 集群节点分布: ┌──────────┬──────────┬──────────┐ │ 节点 1 │ 节点 2 │ 节点 3 │ ├──────────┼──────────┼──────────┤ │ P0, R1 │ P1, R2 │ P2, R0 │ │ │ │ │ │ (分片分布可以自动平衡) │ └──────────┴──────────┴──────────┘ ``` ## 分片路由机制 文档通过路由算法分配到特定分片: ``` 文档路由公式: shard = hash(_routing) % number_of_primary_shards 示例: number_of_shards = 3 _routing = "user1" (hash = 12345) → shard = 12345 % 3 = 1 _routing = "user2" (hash = 67890) → shard = 67890 % 3 = 0 _routing = "user3" (hash = 13579) → shard = 13579 % 3 = 2 ``` ## 分片数选择指南 **推荐公式:** ``` 目标分片大小 = 20GB - 50GB 分片数 = 预估数据总量 / 目标分片大小 示例: 预估数据 300GB 目标分片大小 30GB 推荐分片数 = 300 / 30 = 10 ``` ## 使用场景 ### 1. 小数据量索引 ```bash PUT /small_index { "settings": { "index.number_of_shards": 1 } } ``` **适用:** 数据量 < 50GB ### 2. 中等数据量索引 ```bash PUT /medium_index { "settings": { "index.number_of_shards": 3 } } ``` **适用:** 数据量 50GB - 500GB ### 3. 大数据量索引 ```bash PUT /large_index { "settings": { "index.number_of_shards": 10 } } ``` **适用:** 数据量 > 500GB ### 4. 超大规模索引 ```bash PUT /huge_index { "settings": { "index.number_of_shards": 30 } } ``` **适用:** 数据量 > 2TB ## 推荐设置建议 | 数据总量 | 推荐分片数 | 单分片大小 | 说明 | |---------|-----------|-----------|------| | < 10GB | 1 | < 10GB | 单分片足够 | | 10-50GB | 1 | 10-50GB | 单分片最优 | | 50-100GB | 2-3 | 25-50GB | 开始分片 | | 100-500GB | 3-10 | 30-50GB | 标准配置 | | 500GB-2TB | 10-30 | 50-100GB | 大型索引 | | > 2TB | 30-100 | 50-100GB | 超大规模 | ## 分片数影响因素 ### 过少分片的影响 ``` 分片数过少 (如 1 个分片): ├── 优点: │ ├── 管理简单 │ ├── 聚合性能好 │ └── 资源开销少 │ └── 缺点: ├── 无法横向扩展 ├── 单点性能瓶颈 └── 存储上限受限 ``` ### 过多分片的影响 ``` 分片数过多 (如 100+ 个分片): ├── 优点: │ ├── 并行处理能力高 │ └── 易于扩展 │ └── 缺点: ├── 管理复杂度高 ├── 资源开销大(每个分片有内存和文件句柄开销) ├── 聚合性能下降 └── 集群状态过大 ``` ## 常见问题 **问题 1:创建后无法修改分片数** ``` 错误: Can't update non-dynamic settings [[index.number_of_shards]] ``` **原因:** `number_of_shards` 是静态配置 **解决方案:** 1. **重建索引**(推荐) ```bash # 创建新索引 PUT /new_index { "settings": { "index.number_of_shards": 5 } } # 重新索引数据 POST /_reindex { "source": { "index": "old_index" }, "dest": { "index": "new_index" } } # 删除旧索引 DELETE /old_index ``` 2. **使用 Split API**(有限制) ```bash # 只能增加为倍数(1→2→4→8) POST /my_index/_split/new_index { "settings": { "index.number_of_shards": 2 } } ``` **问题 2:分片数设置过多** **症状:** - 节点内存使用过高 - 集群响应缓慢 - 文件句柄不足 **解决方案:** - 预先规划好分片数量 - 使用 Rollover 索引管理时间序列数据 - 考虑使用 ILM (Index Lifecycle Management) **问题 3:分片数设置过少** **症状:** - 无法扩展到新节点 - 单分片性能瓶颈 - 存储空间不足 **解决方案:** - 重建索引并增加分片数 - 使用别名平滑过渡 ## 与副本数的关系 ```yaml # 完整配置示例 PUT /my_index { "settings": { "index.number_of_shards": 3, # 主分片数 "index.number_of_replicas": 1 # 每个主分片的副本数 } } # 总分片数 = 主分片数 × (1 + 副本数) # 上述配置: 3 × (1 + 1) = 6 个分片 ``` ## 索引模板配置 ```bash # 为时间序列索引设置合适的分片数 PUT /_template/logs_template { "index_patterns": ["logs-*"], "settings": { "index.number_of_shards": 5, "index.number_of_replicas": 1, "index.lifecycle.name": "logs_policy", "index.lifecycle.rollover_alias": "logs" } } # 使用 Rollover 自动管理索引大小 PUT /logs-000001 { "aliases": { "logs": { "is_write_index": true } } } ``` ## 监控建议 ```bash # 查看索引分片信息 GET /_cat/shards/my_index?v # 查看分片大小 GET /_cat/shards?v&h=index,shard,prirep,state,store&s=store:desc # 查看集群分配 GET /_cat/allocation?v # 查看索引统计 GET /my_index/_stats?pretty ``` ## 分片大小监控 **健康阈值:** | 指标 | 健康 | 警告 | 严重 | |-----|------|------|------| | 单分片大小 | < 30GB | 30-50GB | > 50GB | | 单节点分片数 | < 20 | 20-50 | > 50 | | 集群总分片数 | < 1000 | 1000-3000 | > 3000 | ## 最佳实践 ### 1. 预先规划 ``` 规划步骤: 1. 估算未来 1-2 年的数据量 2. 确定目标分片大小 (20-50GB) 3. 计算所需分片数 4. 验证节点资源是否足够 ``` ### 2. 使用索引模板 ```bash PUT /_template/app_template { "index_patterns": ["app-*"], "settings": { "index.number_of_shards": 5, "index.number_of_replicas": 1 } } ``` ### 3. 时间序列数据使用 Rollover ```bash PUT /_ilm_policy/logs_policy { "policy": { "phases": { "hot": { "actions": { "rollover": { "max_size": "50GB", "max_age": "30d" } } } } } } ``` ### 4. 定期检查分片大小 ```bash # 检查所有索引的分片大小 GET /_cat/shards?v&h=index,shard,prirep,store&s=store:desc ``` ## 注意事项 1. **不可修改**:创建后无法修改分片数 2. **慎重选择**:根据未来数据增长规划 3. **避免过度分片**:分片过多会增加管理开销 4. **目标大小**:单分片保持在 20-50GB 5. **节点限制**:考虑单节点能承载的分片数 6. **集群限制**:默认最大 1024 个分片/索引 7. **使用模板**:通过模板统一管理分片配置