为什么这个错误发生 #
delay_recovery_exception 表示分片恢复操作被延迟。这通常是一个临时性异常,表示系统决定推迟恢复操作而不是立即失败。
这个错误可能由以下原因引起:
- 节点过载:目标节点正在进行大量恢复操作,过载可能导致性能问题
- 并发恢复限制:同时进行的恢复操作数量达到限制
- 资源紧张:CPU、内存或磁盘 I/O 资源不足
- 分片迁移中:分片正在迁移,恢复需要等待迁移完成
- 集群状态不稳定:集群正在重新平衡或选举,暂时无法执行恢复
- 磁盘高水位线:节点磁盘接近高水位线,延迟新的恢复操作
如何修复这个错误 #
1. 检查恢复状态 #
# 查看正在进行的恢复操作
GET /_cat/recovery?v&active_only=true
# 查看恢复详细状态
GET /_cat/recovery?v
2. 检查节点资源使用情况 #
# 查看 JVM 和 CPU 使用
GET /_nodes/stats/jvm,process,os
# 查看磁盘使用
GET /_cat/allocation?v
# 查看线程池状态
GET /_cat/thread_pool?v&h=name,active,queue,rejected
3. 调整恢复并发设置 #
# 增加并发恢复数量(如果资源充足)
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.node_concurrent_recoveries": 4,
"indices.recovery.max_concurrent_file_chunks": 4
}
}
# 或减少并发数量(如果资源不足)
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.node_concurrent_recoveries": 2
}
}
4. 调整恢复速率 #
# 限制恢复速率以降低节点负载
PUT /_cluster/settings
{
"transient": {
"indices.recovery.max_bytes_per_sec": "20mb"
}
}
5. 等待并重试 #
# 这个错误通常是临时的,等待后重试
# 可以手动触发重试
POST /_cluster/reroute?retry_failed=true
6. 检查磁盘水位线 #
# 查看磁盘水位线设置
GET /_cluster/settings?filter_path=*.disk.watermark*
# 如果触发水位线,清理空间或调整设置
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "98%"
}
}
7. 分批恢复分片 #
# 如果有大量分片需要恢复,考虑分批进行
# 可以临时禁用某些索引的恢复,优先恢复关键索引
POST /<index>/_settings
{
"index": {
"routing": {
"allocation": {
"enable": "none"
}
}
}
}
# 恢复后再启用
PUT /<index>/_settings
{
"index": {
"routing": {
"allocation": {
"enable": "all"
}
}
}
}
8. 检查集群健康状态 #
# 等待集群稳定后再执行恢复
GET /_cluster/health?wait_for_status=yellow&timeout=50s
预防措施 #
- 监控节点资源使用情况,避免过载
- 配置合理的恢复并发数和速率限制
- 在非高峰时段执行大规模恢复操作
- 为集群预留足够的资源缓冲
- 使用增量恢复策略,避免同时恢复大量分片
- 定期检查磁盘水位线,确保有足够空间





