问题描述
在使用 Elasticsearch 时出现分片未被分配的情况是比较常见的,尤其是在节点出现故障或重启的情况下。上面的错误日志表明,某个分片由于无法获得锁,导致恢复失败,并且分配失败,最终被丢弃。这种问题通常发生在 Elasticsearch 集群中的一个或多个节点无法成功分配或恢复特定的分片。
{"state": "UNASSIGNED","primary": true,"node": null,"relocating_node": null,"shard": 11,"index": "indexname_v1","recovery_source": {"type": "EXISTING_STORE","bootstrap_new_history_uuid": false},"unassigned_info": {"reason": "ALLOCATION_FAILED","at": "2025-01-06T01:17:43.145Z","failed_attempts": 5,"failed_nodes": ["urcKrynQRCWctIZnYVww9A"],"delayed": false,"details": "failed shard on node [urcKrynQRCWctIZnYVww9A]: failed to create shard, failure IOException[failed to obtain in-memory shard lock]; nested: ShardLockObtainFailedException[[indexname_v1][11]: obtaining shard lock timed out after 5000ms, previous lock details: [shard creation] trying to lock for [shard creation]]; ","allocation_status": "deciders_no"}
}
错误分析
日志中的关键部分如下:
- “state”: “UNASSIGNED”: 分片当前处于未分配状态。
- “reason”: “ALLOCATION_FAILED”: 分片分配失败。
- “failed_attempts”: 5: 该分片尝试恢复了 5 次都失败了。
- “details”: 错误详情显示,分片在节点 [urcKrynQRCWctIZnYVww9A] 上恢复失败,原因是无法创建分片,导致无法获得内存锁。具体错误为
ShardLockObtainFailedException
。 - “allocation_status”: “deciders_no”: 这是分片没有被分配的最终原因,表示分配决策被拒绝。
从上述错误信息来看,问题的根源是分片锁定超时,即在恢复分片时,Elasticsearch 试图锁定该分片以便进行恢复操作,但由于某些原因(可能是磁盘压力、内存不足或节点负载过高等),无法在规定时间内获得锁,导致恢复失败。
解决方案
针对该问题,Elasticsearch 提供了一个简单的命令来重新恢复失败的分片:
POST /_cluster/reroute?retry_failed=true
这个命令的作用是让集群重新尝试恢复那些已经失败的分片,通常在执行该命令后,分片会重新分配并开始恢复,集群的状态也会恢复为绿色(表示所有分片都已经成功分配并处于健康状态)。