--- title: "对等恢复未找到异常 (peer_recovery_not_found_exception) 错误排查与解决" date: 2026-03-18 lastmod: 2026-03-18 description: "peer_recovery_not_found_exception 表示在查找对等恢复时失败,通常由恢复 ID 无效、目标节点故障或恢复被取消引起。" tags: ["分片恢复", "数据恢复"] summary: "为什么这个错误发生 # peer_recovery_not_found_exception 表示在查找对等恢复(peer recovery)时失败。对等恢复是指从一个节点向另一个节点复制分片数据的过程。 这个错误可能由以下原因引起: 恢复 ID 无效:指定的恢复 ID 不存在或已过期 目标节点故障:目标节点发生故障或离线 恢复已完成:恢复过程已经完成,状态已清理 恢复被取消:恢复操作被取消 分片重新分配:分片已被重新分配到其他节点 超时:恢复操作超时导致资源被清理 节点重启:节点重启导致恢复状态丢失 并发恢复冲突:同时存在多个恢复操作导致冲突 分配 ID 不匹配:目标分配 ID 与预期不符 集群状态变更:集群状态变更导致恢复信息失效 如何修复这个错误 # 1. 查看恢复状态 # # 查看当前正在进行的恢复 GET /_cat/recovery?v&active_only=true # 查看所有恢复状态 GET /_cat/recovery?v # 查看特定分片的恢复状态 GET /<index>/_recovery?detailed=true 2. 检查分片状态 # # 查看分片状态 GET /_cat/shards?v&h=index,shard,prirep,state,node,recovering_node # 查看特定索引的分片 GET /_cat/shards/<index>?v 3. 等待恢复完成 # # 如果恢复正在进行,等待其完成 GET /_cat/recovery?v&active_only=true # 等待集群健康 GET /_cluster/health?wait_for_status=green&timeout=300s 4." --- ## 为什么这个错误发生 `peer_recovery_not_found_exception` 表示在查找对等恢复(peer recovery)时失败。对等恢复是指从一个节点向另一个节点复制分片数据的过程。 这个错误可能由以下原因引起: 1. **恢复 ID 无效**:指定的恢复 ID 不存在或已过期 2. **目标节点故障**:目标节点发生故障或离线 3. **恢复已完成**:恢复过程已经完成,状态已清理 4. **恢复被取消**:恢复操作被取消 5. **分片重新分配**:分片已被重新分配到其他节点 6. **超时**:恢复操作超时导致资源被清理 7. **节点重启**:节点重启导致恢复状态丢失 8. **并发恢复冲突**:同时存在多个恢复操作导致冲突 9. **分配 ID 不匹配**:目标分配 ID 与预期不符 10. **集群状态变更**:集群状态变更导致恢复信息失效 ## 如何修复这个错误 ### 1. 查看恢复状态 ```bash # 查看当前正在进行的恢复 GET /_cat/recovery?v&active_only=true # 查看所有恢复状态 GET /_cat/recovery?v # 查看特定分片的恢复状态 GET //_recovery?detailed=true ``` ### 2. 检查分片状态 ```bash # 查看分片状态 GET /_cat/shards?v&h=index,shard,prirep,state,node,recovering_node # 查看特定索引的分片 GET /_cat/shards/?v ``` ### 3. 等待恢复完成 ```bash # 如果恢复正在进行,等待其完成 GET /_cat/recovery?v&active_only=true # 等待集群健康 GET /_cluster/health?wait_for_status=green&timeout=300s ``` ### 4. 重新触发恢复 ```bash # 取消现有的恢复并重新开始 POST /_cluster/reroute { "commands": [ { "cancel": { "index": "", "shard": 0, "node": "" } } ] } # 然后重新分配 POST /_cluster/reroute { "commands": [ { "allocate_replica": { "index": "", "shard": 0, "node": "" } } ] } ``` ### 5. 从快照恢复 ```bash # 如果恢复失败,可以从快照恢复 POST /_snapshot///_restore { "indices": "", "include_global_state": false } ``` ### 6. 重启节点 ```bash # 如果恢复卡住,可以重启相关节点 sudo systemctl restart easysearch # 等待节点加入集群 GET /_cat/nodes?v ``` ### 7. 检查节点状态 ```bash # 确保源节点和目标节点都在线 GET /_cat/nodes?v&h=name,status,heap.percent,cpu # 查看节点详细信息 GET /_nodes ``` ### 8. 查看恢复详情 ```bash # 查看详细的恢复信息 GET //_recovery?active_only=true&human&detailed=true # 查看恢复的文件和字节 GET /_recovery?human&filter_path=**.files,**.bytes ``` ### 9. 检查网络连接 ```bash # 测试节点间的网络连接 ping telnet 9300 # 检查防火墙规则 sudo iptables -L -n | grep 9300 ``` ### 10. 调整恢复配置 ```yaml # 在 easysearch.yml 中调整恢复配置 cluster.routing.allocation.node_concurrent_recoveries: 4 cluster.routing.allocation.node_initial_primaries_recoveries: 6 indices.recovery.max_bytes_per_sec: 100mb ``` ### 11. 限制并发恢复 ```bash # 如果太多并发恢复导致问题,限制并发数 PUT /_cluster/settings { "transient": { "cluster.routing.allocation.node_concurrent_recoveries": 2 } } ``` ### 12. 查看错误日志 ```bash # 查看恢复相关错误日志 grep -i "recovery.*fail\|peer.*recovery" /path/to/easysearch/logs/easysearch.log | tail -100 # 查看分片相关错误 grep -i "shard.*error" /path/to/easysearch/logs/easysearch.log | tail -50 ``` ### 13. 切换恢复源 ```bash # 如果特定节点的恢复失败,可以尝试从其他节点恢复 # 先取消现有恢复 POST /_cluster/reroute { "commands": [ { "cancel": { "index": "", "shard": 0, "node": "" } } ] } # 分配到新节点 POST /_cluster/reroute { "commands": [ { "move": { "index": "", "shard": 0, "from_node": "", "to_node": "" } } ] } ``` ### 14. 验证分片完整性 ```bash # 查看分片存储信息 GET //_shard_stores?status=green,yellow # 验证分片是否可用 GET //_search?size=0 ``` ### 15. 重建分片 ```bash # 如果恢复持续失败,可能需要重建分片 # 删除并从副本重建 DELETE / # 然后从数据源重新索引或从快照恢复 POST /_snapshot///_restore { "indices": "" } ``` ### 预防措施 - 优雅关闭节点 - 保持网络稳定 - 配置合理的恢复速度 - 监控恢复进度 - 使用快照备份 - 配置足够的副本 - 避免频繁的分片迁移 - 监控节点资源使用 - 配置合理的超时时间 - 定期检查集群健康状态