问题描述
在使用 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
这个命令的作用是让集群重新尝试恢复那些已经失败的分片,通常在执行该命令后,分片会重新分配并开始恢复,集群的状态也会恢复为绿色(表示所有分片都已经成功分配并处于健康状态)。