Elasticsearch 分片分配问题:原因与解决方案
通过分配解释、磁盘检查、节点过滤和安全恢复步骤诊断 Elasticsearch 分片分配问题。
Elasticsearch 分片分配问题:原因与解决方案
Elasticsearch 分片分配问题通常表现为集群健康状态为黄色或红色。黄色表示主分片已分配,但至少一个副本未分配。红色表示至少一个主分片未分配,因此某些数据可能不可用,直到您恢复它。
本指南将向您展示如何查找分配阻塞器、读取 Allocation Explain API 的输出,并选择风险最小的修复方案。目标是在不加剧数据丢失的情况下恢复分配。
理解分片状态和集群健康
分片是 Elasticsearch 跨数据节点放置的单位。它们可以处于几种状态:
- STARTED:分片处于活动状态并正在处理请求。
- RELOCATING:分片正在从一个节点移动到另一个节点。
- INITIALIZING:分片正在创建或恢复。
- UNASSIGNED:分片存在于集群元数据中,但未分配到任何节点。
集群健康状态遵循这些分片状态:
- Green:所有主分片和副本分片都已分配。
- Yellow:所有主分片都已分配,但一个或多个副本未分配。
- Red:一个或多个主分片未分配。搜索可能会返回部分结果或对受影响的索引失败,并且对这些索引的写入可能会失败。
分片分配失败的常见原因
Elasticsearch 在放置分片之前使用分配决策器。单个 NO 决策可能会使分片保持未分配状态。
磁盘水位线
磁盘压力是最常见的原因之一。Elasticsearch 使用磁盘水位线来避免填满节点。一旦节点超过低水位线或高水位线,分配决策就会变得更加严格。在洪水水位线阶段,Elasticsearch 可以向受影响的索引添加只读块,以保护节点免于磁盘耗尽。
| 设置 | 常见默认值 | 效果 |
|---|---|---|
cluster.routing.allocation.disk.watermark.low |
85% | 避免将额外的分片分配到超过此阈值的节点。 |
cluster.routing.allocation.disk.watermark.high |
90% | 尝试将分片移走,并避免将分片放置在该节点上。 |
cluster.routing.allocation.disk.watermark.flood_stage |
95% | 可以阻止对受影响索引的写入。 |
在更改任何内容之前,请确认集群的实际设置:
GET /_cluster/settings?include_defaults=true&filter_path=**.disk.watermark*
然后检查节点磁盘使用情况:
GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total,shards
释放空间、添加磁盘、添加数据节点、删除旧索引或减少副本压力。如果设置了洪水阶段块,请在修复磁盘压力后仅将其删除:
PUT /my_index/_settings
{
"index.blocks.read_only_allow_delete": null
}
节点角色和分配过滤器
索引分片仅分配到具有数据角色和匹配分配过滤器的节点。如果您将节点属性用于热/暖层、机架、区域或存储类型,则拼写错误可能会导致分片搁浅。
例如,具有 index.routing.allocation.require.box_type: high_io 的索引将仅分配到配置了 node.attr.box_type: high_io 的节点。
检查索引过滤器和节点属性:
GET /my_index/_settings?filter_path=*.settings.index.routing.allocation
GET /_cat/nodeattrs?v
GET /_cat/nodes?v&h=name,roles,disk.used_percent
修复索引设置或添加合格的数据节点。不要随意在多区域集群中移除分配感知;它可能会将分片的所有副本放置在同一个故障域中。
缺少主分片
如果主分片未分配,则持有活动主分片的节点可能已消失,索引可能刚刚恢复,或者分配规则可能正在阻止每个符合条件的节点。在 Allocation Explain API 告诉您 Elasticsearch 无法分配分片的原因之前,不要假设数据已丢失。
常见场景包括:
- 持有唯一良好主分片副本的节点崩溃。
- 分配过滤器排除了所有可以托管主分片的数据节点。
- 快照恢复或索引创建正在等待符合条件的节点。
- 存在过时的分片副本,但 Elasticsearch 不会在没有明确接受数据丢失的情况下提升它。
首先尝试恢复丢失的节点、恢复快照或修复分配阻塞器。仅当您了解哪个副本已过时或您已接受该分片的数据丢失时,才使用强制主分配。
分片限制
每个节点的分片限制也可能阻止分配。常见设置包括 index.routing.allocation.total_shards_per_node 和 cluster.routing.allocation.total_shards_per_node。
检查这些限制:
GET /_cluster/settings?include_defaults=true&filter_path=**.total_shards_per_node
GET /my_index/_settings?filter_path=*.settings.index.routing.allocation.total_shards_per_node
添加节点、减少副本数量、合并小索引或谨慎提高相关限制。每个节点分片过多可能会增加堆压力并减慢集群状态操作。
使用 Allocation Explain API 进行诊断
Allocation Explain API 是回答“为什么这个分片没有分配?”的最佳工具。
GET /_cluster/allocation/explain?pretty
{
"index": "my_data",
"shard": 0,
"primary": true
}
要让 Elasticsearch 选择一个当前未分配的分片,请在没有请求体的情况下调用 API:
GET /_cluster/allocation/explain?pretty
首先阅读这些字段:
can_allocate:高级答案。allocate_explanation:通俗易懂的摘要。node_allocation_decisions:每个节点的决策。deciders:返回NO或THROTTLE的确切规则。
NO 决策是阻塞器。THROTTLE 决策通常意味着 Elasticsearch 可以分配分片,但正在限制并发恢复工作。
安全故障排除顺序
从宽泛开始,然后缩小范围。
1. 检查集群健康和未分配的分片
GET /_cluster/health?pretty
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason,node
查看 unassigned.reason。诸如 NODE_LEFT、INDEX_CREATED、CLUSTER_RECOVERED 或 ALLOCATION_FAILED 之类的值会告诉您下一步该看哪里。
2. 检查磁盘和节点资格
GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total
GET /_cat/nodes?v&h=name,roles,heap.percent,ram.percent,cpu,disk.used_percent
如果节点接近高水位线,请在更改分配设置之前修复磁盘压力。
3. 运行 Allocation Explain
使用受影响的索引、分片编号和主/副本标志。输出应命名阻止分配的名称、节点条件或决策器。
4. 在了解原因之前避免有风险的重新路由
手动重新路由命令适用于特定的恢复情况。它们不是磁盘压力、错误过滤器或过多副本的通用修复方法。
如果过时的主副本是唯一可行的恢复路径,则命令如下所示:
POST /_cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "index_name",
"shard": 0,
"node": "node_name_with_stale_copy",
"accept_data_loss": true
}
}
]
}
accept_data_loss: true 是必需的,这是有原因的。只有在检查了快照、尝试恢复丢失的节点并确认哪个节点持有过时副本之后,才使用它。
5. 单独处理黄色健康状态
如果只有副本未分配,集群仍然可以服务主数据。首先修复底层资源约束。添加数据节点、清理磁盘或更正分配过滤器通常可以让 Elasticsearch 自动分配副本。
如果您必须暂时在没有副本的情况下运行,请减少受影响索引的副本数量:
PUT /my_index/_settings
{
"index.number_of_replicas": 0
}
这可以使健康状态变为绿色,因为 Elasticsearch 不再期望该索引有副本。它也会降低可用性,因此在您添加容量或修复分配后,请将副本设置回所需的值。
预防分配问题
- 在节点超过高磁盘水位线之前发出警报。
- 为您的副本数量和分配感知规则保留足够的数据节点。
- 使用适合您的堆、数据量和恢复目标的分片计数。
- 审查索引模板,以便新索引不会继承错误的副本计数或分配过滤器。
- 在事件发生之前测试节点替换和快照恢复步骤。
要点
您最安全的路径很简单:识别未分配的分片,运行 Allocation Explain,修复返回 NO 的决策器,并避免强制分配,除非您已接受数据丢失的权衡。