在 Elasticsearch 中,副本(Replica) 是实现 高可用、读性能扩展和容灾恢复 的核心机制。理解副本的工作原理、配置策略和最佳实践,是构建稳定、高性能集群的关键。
本文将全面详解 Elasticsearch 副本(Replica)的各个方面。
一、什么是副本(Replica)?
副本分片(Replica Shard) 是主分片(Primary Shard)的完整拷贝,每个主分片可以有 0 个或多个副本。
✅ 副本的作用:
- 高可用:主分片故障时,副本可提升为主,服务不中断;
- 读性能提升:搜索和获取文档可负载均衡到主或副本;
- 数据冗余:防止数据丢失。
二、副本的核心特性
| 特性 | 说明 |
|---|---|
| 异步复制 | 主分片写入成功后,再同步到副本(可配置为同步) |
| 可动态调整 | 副本数可随时增减,无需重启或 reindex |
| 不参与写入 | 所有写操作必须经过主分片 |
| 自动故障转移 | 主分片宕机后,选举副本为新主 |
| 可位于不同节点 | 避免单点故障 |
三、副本的工作原理
1. 写入流程(Indexing)
默认行为:
- 主分片先写入本地 Lucene;
- 然后并行发送请求到所有副本;
- 等待所有副本确认后,返回成功。
⚠️ 如果副本写入失败,主分片会标记该副本为“失败”,并重试。
2. 读取流程(Search / Get)
- 查询请求可发送到主分片或任意副本;
- 实现读负载均衡;
- 副本越多,读吞吐越高。
四、副本数配置
1. 设置副本数
创建索引时:
PUT /my-index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
动态修改(推荐):
PUT /my-index/_settings
{
"number_of_replicas": 2
}
✅ 可随时调整,立即生效。
2. 副本数建议
| 场景 | 建议副本数 | 说明 |
|---|---|---|
| 开发/测试环境 | 0~1 | 节省资源 |
| 生产环境 | ≥1 | 保证高可用 |
| 高可用要求 | 2 | 支持单节点故障 + 滚动升级 |
| 读多写少 | 2~3 | 提升查询吞吐 |
| 写密集型 | 1 | 减少写放大(write amplification) |
📌 副本数 = N 表示:每个主分片有 N 个副本,总分片数 = 主分片 × (1 + N)
五、副本分配策略
Elasticsearch 自动确保:
- 主分片与其副本不在同一节点;
- 副本均匀分布在集群节点上;
- 支持基于节点属性(如
zone、rack)实现机架感知。
示例:跨可用区部署
PUT /_cluster/settings
{
"cluster.routing.allocation.awareness.attributes": "zone"
}
节点配置:
# node-1
node.attr.zone: east
# node-2
node.attr.zone: west
✅ 确保主副本分布在不同
zone,提升容灾能力。
六、副本同步机制
1. 同步 vs 异步
| 模式 | 配置 | 说明 |
|---|---|---|
| 默认(准同步) | wait_for_active_shards=all | 等待所有可用副本确认 |
| 强一致性 | ?wait_for_active_shards=all | 写入前等待全部副本在线 |
| 高性能 | ?wait_for_active_shards=1 | 只等主分片成功 |
示例:强一致性写入
PUT /my-index/_doc/1?wait_for_active_shards=all
{
"title": "高可用文档"
}
⚠️ 如果副本离线,写入会阻塞或失败。
2. 副本恢复(Recovery)
当节点重启或网络恢复后,Elasticsearch 会自动执行 增量恢复:
- 比对主副本的事务日志(translog);
- 补齐缺失的操作;
- 恢复完成后重新参与读写。
可通过
GET /_recovery查看恢复进度。
七、常见问题与解决方案
Q1:副本未分配(UNASSIGNED)怎么办?
常见原因:
- 磁盘空间不足;
- 节点离线;
cluster.routing.allocation.enable被禁用;- 主分片未就绪。
排查命令:
GET /_cluster/allocation/explain
解决方案:
- 清理磁盘;
- 启用分配:
PUT /_cluster/settings { "cluster.routing.allocation.enable": "all" } - 手动迁移:
POST /_cluster/reroute
Q2:副本同步延迟高?
原因:
- 网络带宽不足;
- 副本节点负载高(CPU、IO);
- 写入速率过高。
优化:
- 升级网络;
- 增加副本节点资源;
- 降低
refresh_interval减少刷新开销。
Q3:能否关闭副本以提升写入性能?
✅ 可以临时关闭:
PUT /my-index/_settings
{
"number_of_replicas": 0
}
适用于:
- 批量导入数据;
- 临时性能压测。
⚠️ 完成后必须恢复:"number_of_replicas": 1
Q4:副本会影响写入性能吗?
✅ 会,因为:
- 每次写入需同步到所有副本;
- 副本越多,写放大越严重(Write Amplification);
- 网络延迟影响整体响应时间。
建议:写密集型场景,副本数设为 1。
八、高级配置与调优
1. 控制副本分配
PUT /my-index/_settings
{
"index.routing.allocation.include._zone": "east",
"index.routing.allocation.exclude._ip": "192.168.1.100"
}
2. 调整恢复速度
PUT /_cluster/settings
{
"indices.recovery.max_bytes_per_sec": "50mb"
}
防止恢复过程占用过多带宽。
3. 副本读取偏好(preference)
控制查询路由到特定副本:
GET /my-index/_search?preference=_shards:0
GET /my-index/_search?preference=_only_local # 优先本地副本
用于优化局部性或调试。
九、副本与集群健康状态
| 集群状态 | 说明 |
|---|---|
green | 所有主分片和副本都正常分配 |
yellow | 主分片正常,副本未全部分配(如副本数=0 或节点不足) |
red | 有主分片未分配,数据不可用 |
✅ 生产环境应尽量保持
green。
十、最佳实践总结 ✅
| 场景 | 建议 |
|---|---|
| 生产环境 | 副本数 ≥ 1 |
| 高可用 | 副本数 ≥ 2 |
| 写密集 | 副本数 = 1,导入时可临时设为 0 |
| 读密集 | 副本数 = 2~3,提升吞吐 |
| 多可用区 | 配置 awareness.attributes 实现跨区容灾 |
| 监控 | 定期检查 _cat/shards、恢复状态、磁盘使用率 |
十一、扩展建议
- 使用 CCR(Cross-Cluster Replication) 实现跨集群副本;
- 对只读索引使用 shrink 后再增加副本,节省资源;
- 结合 ILM 在 warm 阶段降低副本数(如从 2 → 1);
- 监控
thread_pool.bulk.queue防止副本同步阻塞。
1708

被折叠的 条评论
为什么被折叠?



