--- title: "索引副本数配置" date: 2026-03-05 lastmod: 2026-03-05 description: "控制索引每个主分片的副本数量配置项说明" tags: ["索引配置", "高可用", "数据安全"] summary: "配置项作用 # 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):" --- ## 配置项作用 `index.number_of_replicas` 配置项指定每个主分片的副本数量。副本分片是主分片的完整复制,提供数据冗余、高可用性和读取吞吐量的扩展。 ## 配置项类型 该配置项为**动态配置**,可以在运行时通过索引设置 API 进行修改。 ## 默认值 ``` 1(每个主分片有 1 个副本) ``` ## 是否必需 **可选配置项**(有默认值) ## 取值范围 ``` 0 ~ 正整数 ``` ## 配置格式 ```yaml # 创建索引时设置 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. 高可用性(推荐生产环境) ```yaml index.number_of_replicas: 1 ``` **效果:** - 至少 2 个节点(1 主 + 1 副本) - 单节点故障不丢失数据 - 自动故障转移 ### 2. 更高可用性 ```yaml index.number_of_replicas: 2 ``` **效果:** - 至少 3 个节点 - 允许 2 个节点故障 - 更好的读取扩展 ### 3. 最高可用性 ```yaml index.number_of_replicas: 3 ``` **效果:** - 至少 4 个节点 - 允许 3 个节点故障 - 最佳读取性能 ### 4. 单节点/测试环境 ```yaml index.number_of_replicas: 0 ``` **效果:** - 无副本 - 无高可用保障 - 用于测试或单节点部署 ## 使用示例 **创建索引时设置:** ```bash # 高可用配置(2 副本) PUT /production_index { "settings": { "index.number_of_shards": 3, "index.number_of_replicas": 2 } } # 总分片数 = 3 × (1 + 2) = 9 ``` **动态修改副本数:** ```bash # 增加副本数 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 } ``` **临时禁用副本(批量导入优化):** ```bash # 导入前 PUT /my_index/_settings { "index.number_of_replicas": 0 } # 执行导入... # 导入后恢复 PUT /my_index/_settings { "index.number_of_replicas": 1 } ``` ## 推荐设置建议 | 场景 | 副本数 | 最小节点数 | 可用性说明 | |-----|-------|-----------|-----------| | 测试/开发 | 0 | 1 | 无高可用 | | 生产环境(默认) | 1 | 2 | 单节点故障不丢数据 | | 高可用生产 | 2 | 3 | 双节点故障不丢数据 | | 极致可用 | 3 | 4 | 三节点故障不丢数据 | ## 副本数影响分析 | 副本数 | 存储空间 | 写入性能 | 读取性能 | 高可用性 | |-------|---------|---------|---------|---------| | 0 | 1x | 最高 | 低 | 无 | | 1 | 2x | 高 | 中 | 单点容错 | | 2 | 3x | 中 | 高 | 双点容错 | | 3 | 4x | 低 | 最高 | 三点容错 | ## 写入流程详解 ``` 写入请求流程: ┌─────────────────────────────────────────────────────────────────┐ │ 写入一致性保证 │ └─────────────────────────────────────────────────────────────────┘ 客户端请求 │ ▼ 主分处理 │ ├── 写入 Translog ├── 写入 Lucene └── 转发到副本 │ ├── 副本 1 写入 ├── 副本 2 写入 └── 副本 N 写入 │ ▼ 所有副本确认 │ ▼ 返回成功响应 ``` ## 故障转移机制 ``` 主分片故障: ┌─────────────────────────────────────────────────────────────────┐ │ 故障转移流程 │ └─────────────────────────────────────────────────────────────────┘ 正常状态: 节点1 [主分片] → 节点2 [副本1], 节点3 [副本2] │ ▼ 节点1 故障 │ ▼ 集群检测到主分片不可用 │ ▼ 从副本中选出新主分片 (节点2) │ ▼ 新主分片: 节点2 [主分片] → 节点3 [副本1] │ ▼ 创建新副本: 节点1 恢复后或新节点加入 ``` ## 与分片数的关系 ```yaml # 完整配置 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 ``` ## 索引模板配置 ```bash # 生产环境模板 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" } # 根据数据节点数量自动调整副本数 ``` ## 监控建议 ```bash # 查看副本配置 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:副本分片未分配** ```bash GET /_cluster/allocation/explain ``` **可能原因:** - 节点数不足 - 磁盘空间不足 - 分片分配规则限制 **解决方案:** 1. **增加节点** 2. **清理磁盘空间** 3. **调整分配设置** **问题 2:写入性能差** **可能原因:** 副本数过多,每次写入需要同步到所有副本 **解决方案:** ```bash # 临时减少副本数 PUT /my_index/_settings { "index.number_of_replicas": 0 } ``` **问题 3:节点资源不足** **可能原因:** 副本数过多导致存储和内存压力 **解决方案:** ```bash # 减少副本数 PUT /my_index/_settings { "index.number_of_replicas": 1 } ``` ## 批量导入优化 ```bash # 步骤 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. **恢复时间**:副本数越多,恢复时间越长