📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

配置项作用 #

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   │
│          │          │          │
│ (分片分布可以自动平衡)          │
└──────────┴──────────┴──────────┘

分片路由机制 #

文档通过路由算法分配到特定分片:

文档路由公式:
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. 小数据量索引 #

PUT /small_index
{
  "settings": {
    "index.number_of_shards": 1
  }
}

适用: 数据量 < 50GB

2. 中等数据量索引 #

PUT /medium_index
{
  "settings": {
    "index.number_of_shards": 3
  }
}

适用: 数据量 50GB - 500GB

3. 大数据量索引 #

PUT /large_index
{
  "settings": {
    "index.number_of_shards": 10
  }
}

适用: 数据量 > 500GB

4. 超大规模索引 #

PUT /huge_index
{
  "settings": {
    "index.number_of_shards": 30
  }
}

适用: 数据量 > 2TB

推荐设置建议 #

数据总量推荐分片数单分片大小说明
< 10GB1< 10GB单分片足够
10-50GB110-50GB单分片最优
50-100GB2-325-50GB开始分片
100-500GB3-1030-50GB标准配置
500GB-2TB10-3050-100GB大型索引
> 2TB30-10050-100GB超大规模

分片数影响因素 #

过少分片的影响 #

分片数过少 (如 1 个分片):
├── 优点:
│   ├── 管理简单
│   ├── 聚合性能好
│   └── 资源开销少
│
└── 缺点:
    ├── 无法横向扩展
    ├── 单点性能瓶颈
    └── 存储上限受限

过多分片的影响 #

分片数过多 (如 100+ 个分片):
├── 优点:
│   ├── 并行处理能力高
│   └── 易于扩展
│
└── 缺点:
    ├── 管理复杂度高
    ├── 资源开销大(每个分片有内存和文件句柄开销)
    ├── 聚合性能下降
    └── 集群状态过大

常见问题 #

问题 1:创建后无法修改分片数

错误: Can't update non-dynamic settings [[index.number_of_shards]]

原因: number_of_shards 是静态配置

解决方案:

  1. 重建索引(推荐)
# 创建新索引
PUT /new_index
{
  "settings": {
    "index.number_of_shards": 5
  }
}

# 重新索引数据
POST /_reindex
{
  "source": { "index": "old_index" },
  "dest": { "index": "new_index" }
}

# 删除旧索引
DELETE /old_index
  1. 使用 Split API(有限制)
# 只能增加为倍数(1→2→4→8)
POST /my_index/_split/new_index
{
  "settings": {
    "index.number_of_shards": 2
  }
}

问题 2:分片数设置过多

症状:

  • 节点内存使用过高
  • 集群响应缓慢
  • 文件句柄不足

解决方案:

  • 预先规划好分片数量
  • 使用 Rollover 索引管理时间序列数据
  • 考虑使用 ILM (Index Lifecycle Management)

问题 3:分片数设置过少

症状:

  • 无法扩展到新节点
  • 单分片性能瓶颈
  • 存储空间不足

解决方案:

  • 重建索引并增加分片数
  • 使用别名平滑过渡

与副本数的关系 #

# 完整配置示例
PUT /my_index
{
  "settings": {
    "index.number_of_shards": 3,     # 主分片数
    "index.number_of_replicas": 1     # 每个主分片的副本数
  }
}

# 总分片数 = 主分片数 × (1 + 副本数)
# 上述配置: 3 × (1 + 1) = 6 个分片

索引模板配置 #

# 为时间序列索引设置合适的分片数
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
    }
  }
}

监控建议 #

# 查看索引分片信息
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

分片大小监控 #

健康阈值:

指标健康警告严重
单分片大小< 30GB30-50GB> 50GB
单节点分片数< 2020-50> 50
集群总分片数< 10001000-3000> 3000

最佳实践 #

1. 预先规划 #

规划步骤:
1. 估算未来 1-2 年的数据量
2. 确定目标分片大小 (20-50GB)
3. 计算所需分片数
4. 验证节点资源是否足够

2. 使用索引模板 #

PUT /_template/app_template
{
  "index_patterns": ["app-*"],
  "settings": {
    "index.number_of_shards": 5,
    "index.number_of_replicas": 1
  }
}

3. 时间序列数据使用 Rollover #

PUT /_ilm_policy/logs_policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "50GB",
            "max_age": "30d"
          }
        }
      }
    }
  }
}

4. 定期检查分片大小 #

# 检查所有索引的分片大小
GET /_cat/shards?v&h=index,shard,prirep,store&s=store:desc

注意事项 #

  1. 不可修改:创建后无法修改分片数
  2. 慎重选择:根据未来数据增长规划
  3. 避免过度分片:分片过多会增加管理开销
  4. 目标大小:单分片保持在 20-50GB
  5. 节点限制:考虑单节点能承载的分片数
  6. 集群限制:默认最大 1024 个分片/索引
  7. 使用模板:通过模板统一管理分片配置