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

配置项作用 #

index.number_of_replicas 配置项指定每个主分片的副本数量。副本分片是主分片的完整复制,提供数据冗余、高可用性和读取吞吐量的扩展。

配置项类型 #

该配置项为动态配置,可以在运行时通过索引设置 API 进行修改。

默认值 #

1(每个主分片有 1 个副本)

是否必需 #

可选配置项(有默认值)

取值范围 #

0 ~ 正整数

配置格式 #

# 创建索引时设置
PUT /my_index
{
  "settings": {
    "index.number_of_replicas": 2
  }
}

# 动态修改
PUT /my_index/_settings
{
  "index.number_of_replicas": 2
}

# 禁用副本
PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

工作原理 #

副本分片提供数据冗余和读取扩展:

┌─────────────────────────────────────────────────────────────────┐
│                      副本分片架构                                │
└─────────────────────────────────────────────────────────────────┘

索引: my_index (1 个主分片,2 个副本)
│
├── 主分片 0 (Primary) - 节点 1
│   └── 数据: Doc A, Doc B, Doc C
│
├── 副本 0 (Replica) - 节点 2
│   └── 数据: Doc A, Doc B, Doc C (同步)
│
└── 副本 1 (Replica) - 节点 3
    └── 数据: Doc A, Doc B, Doc C (同步)

写入流程:
客户端 → 主分片 → 同步到所有副本 → 确认成功

读取流程:
客户端 → 可以从主分片或任意副本读取

副本类型 #

主分片 (Primary Shard):

  • 处理所有写入操作
  • 写入成功后同步到副本
  • 可处理读取请求

副本分片 (Replica Shard):

  • 从主分片同步数据
  • 只处理读取请求
  • 主分片故障时可提升为主分片

使用场景 #

1. 高可用性(推荐生产环境) #

index.number_of_replicas: 1

效果:

  • 至少 2 个节点(1 主 + 1 副本)
  • 单节点故障不丢失数据
  • 自动故障转移

2. 更高可用性 #

index.number_of_replicas: 2

效果:

  • 至少 3 个节点
  • 允许 2 个节点故障
  • 更好的读取扩展

3. 最高可用性 #

index.number_of_replicas: 3

效果:

  • 至少 4 个节点
  • 允许 3 个节点故障
  • 最佳读取性能

4. 单节点/测试环境 #

index.number_of_replicas: 0

效果:

  • 无副本
  • 无高可用保障
  • 用于测试或单节点部署

使用示例 #

创建索引时设置:

# 高可用配置(2 副本)
PUT /production_index
{
  "settings": {
    "index.number_of_shards": 3,
    "index.number_of_replicas": 2
  }
}

# 总分片数 = 3 × (1 + 2) = 9

动态修改副本数:

# 增加副本数
PUT /my_index/_settings
{
  "index.number_of_replicas": 2
}

# 减少副本数
PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

# 恢复默认
PUT /my_index/_settings
{
  "index.number_of_replicas": 1
}

临时禁用副本(批量导入优化):

# 导入前
PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

# 执行导入...

# 导入后恢复
PUT /my_index/_settings
{
  "index.number_of_replicas": 1
}

推荐设置建议 #

场景副本数最小节点数可用性说明
测试/开发01无高可用
生产环境(默认)12单节点故障不丢数据
高可用生产23双节点故障不丢数据
极致可用34三节点故障不丢数据

副本数影响分析 #

副本数存储空间写入性能读取性能高可用性
01x最高
12x单点容错
23x双点容错
34x最高三点容错

写入流程详解 #

写入请求流程:
┌─────────────────────────────────────────────────────────────────┐
│                    写入一致性保证                                │
└─────────────────────────────────────────────────────────────────┘

客户端请求
    │
    ▼
主分处理
    │
    ├── 写入 Translog
    ├── 写入 Lucene
    └── 转发到副本
         │
         ├── 副本 1 写入
         ├── 副本 2 写入
         └── 副本 N 写入
              │
              ▼
         所有副本确认
              │
              ▼
         返回成功响应

故障转移机制 #

主分片故障:
┌─────────────────────────────────────────────────────────────────┐
│                      故障转移流程                                │
└─────────────────────────────────────────────────────────────────┘

正常状态:
节点1 [主分片] → 节点2 [副本1], 节点3 [副本2]
    │
    ▼
节点1 故障
    │
    ▼
集群检测到主分片不可用
    │
    ▼
从副本中选出新主分片 (节点2)
    │
    ▼
新主分片: 节点2 [主分片] → 节点3 [副本1]
    │
    ▼
创建新副本: 节点1 恢复后或新节点加入

与分片数的关系 #

# 完整配置
PUT /my_index
{
  "settings": {
    "index.number_of_shards": 3,     # 主分片数(创建后不可修改)
    "index.number_of_replicas": 1     # 副本数(可动态修改)
  }
}

# 计算总分片数
总分片数 = 主分片数 × (1 + 副本数)
         = 3 × (1 + 1)
         = 6

# 分片分布
P0, R0, P1, R1, P2, R2

索引模板配置 #

# 生产环境模板
PUT /_template/production_template
{
  "index_patterns": ["prod-*"],
  "settings": {
    "index.number_of_shards": 5,
    "index.number_of_replicas": 2,
    "index.auto_expand_replicas": "0-2"
  }
}

# 自动扩展副本
PUT /my_index/_settings
{
  "index.auto_expand_replicas": "0-4"
}
# 根据数据节点数量自动调整副本数

监控建议 #

# 查看副本配置
GET /my_index/_settings?filter_path=*.index.number_of_replicas

# 查看分片健康状态
GET /_cat/shards/my_index?v&h=index,shard,prirep,state,node

# 查看集群健康
GET /_cluster/health

# 查看未分配的副本
GET /_cat/shards?v&h=index,shard,prirep,state,node&s=state

常见问题 #

问题 1:副本分片未分配

GET /_cluster/allocation/explain

可能原因:

  • 节点数不足
  • 磁盘空间不足
  • 分片分配规则限制

解决方案:

  1. 增加节点
  2. 清理磁盘空间
  3. 调整分配设置

问题 2:写入性能差

可能原因: 副本数过多,每次写入需要同步到所有副本

解决方案:

# 临时减少副本数
PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

问题 3:节点资源不足

可能原因: 副本数过多导致存储和内存压力

解决方案:

# 减少副本数
PUT /my_index/_settings
{
  "index.number_of_replicas": 1
}

批量导入优化 #

# 步骤 1: 减少副本
PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

# 步骤 2: 执行批量导入
# (使用 bulk API)

# 步骤 3: 恢复副本
PUT /my_index/_settings
{
  "index.number_of_replicas": 1
}

# 步骤 4: 等待副本恢复完成
GET /_cluster/health?wait_for_relocating_shards=0

集群规划指南 #

节点数与副本数规划:

最小节点数 = 主分片数 + (主分片数 × 副本数)

示例:
3 个主分片,1 个副本
最小节点数 = 3 + (3 × 1) = 6

实际建议:
- 同一节点的副本分片应分布在其他节点
- 确保有足够的节点来分散分片
- 考虑未来节点故障时的可用性

注意事项 #

  1. 动态更新:副本数可动态修改
  2. 节点要求:确保有足够节点分配副本分片
  3. 存储空间:副本数越多,所需存储空间越大
  4. 写入性能:副本数增加会降低写入性能
  5. 读取性能:副本数增加可以提高读取吞吐量
  6. 高可用性:至少 1 个副本用于生产环境
  7. 恢复时间:副本数越多,恢复时间越长