Elasticsearch 索引变为只读问题:原因与解决方案
当 Elasticsearch 集群磁盘空间不足时,可能会触发内置的磁盘保护机制,将索引强制设置为只读状态,导致无法写入或修改数据。本文详细解析这一问题的成因、解决步骤及预防措施。
问题根源:磁盘水位线(Watermark)保护机制
Elasticsearch 为防止磁盘空间耗尽,通过磁盘水位线机制监控节点磁盘使用率,并在达到阈值时采取保护措施:
水位线参数 | 默认值 | 触发行为 |
---|---|---|
cluster.routing.allocation.disk.watermark.low |
85% | 磁盘使用率超过 85% 时,不再向该节点分配新分片。 |
cluster.routing.allocation.disk.watermark.high |
90% | 磁盘使用率超过 90% 时,将该节点上的分片迁移到其他节点。 |
cluster.routing.allocation.disk.watermark.flood_stage |
95% | 磁盘使用率超过 95% 时,将节点上所有索引设置为只读(read_only_allow_delete ),仅允许删除操作。 |
触发只读的典型日志
当达到 flood_stage
水位线时,日志会显示类似以下内容:
1 | flood stage disk watermark [95%] exceeded on [node-id][node-name][/path/to/data] |
此时,所有写入、更新操作会失败,仅查询和删除操作可用。
解决步骤:恢复读写能力
紧急处理:释放磁盘空间
首先需释放足够的磁盘空间(建议至少保留 10% 以上空闲空间):
- 删除无用的索引、日志文件或临时文件。
- 迁移部分数据到其他存储(如冷数据归档)。
关闭磁盘水位线检查(临时)
若无法立即扩容,可临时关闭磁盘阈值检查,允许 Elasticsearch 忽略水位线限制:
1 | PUT _cluster/settings |
persistent
表示配置永久生效(重启集群后仍有效);若需临时生效,可改用transient
。
解除索引只读状态
磁盘空间释放后,需手动移除索引的只读标记:
1 | // 解除所有索引的只读状态 |
read_only_allow_delete
是 Elasticsearch 在flood_stage
时自动添加的限制,允许删除但禁止写入,需手动清除。
恢复磁盘水位线检查(可选)
磁盘扩容或空间充足后,建议重新开启磁盘阈值检查,保障集群稳定性:
1 | PUT _cluster/settings |
优化配置:避免再次触发
1. 调整水位线阈值
根据业务需求调整水位线参数(如将 flood_stage
从 95% 降至 90%,提前预警):
1 | PUT _cluster/settings |
2. 配置磁盘检查频率
调整 Elasticsearch 检查磁盘使用率的间隔(默认 30 秒):
1 | PUT _cluster/settings |
3. 自动清理过期数据
通过索引生命周期管理(ILM) 自动删除或归档过期数据,避免磁盘占满:
1 | // 创建ILM策略:7天后删除索引 |
预防措施
- 监控磁盘使用率:通过 Kibana Monitoring 或 Prometheus 监控节点磁盘使用率,设置阈值告警(如超过 85% 时告警)。
- 定期清理数据:删除无用索引、压缩历史数据,或迁移到低成本存储(如 S3)。
- 合理规划索引生命周期:使用 ILM 自动管理索引(滚动、归档、删除),避免数据无限增长。
- 预留充足空间:确保集群磁盘容量满足至少 3 个月的数据增长需求,并及时扩容
v1.3.10