0%

变为只读问题

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
2
flood stage disk watermark [95%] exceeded on [node-id][node-name][/path/to/data] 
free: 1.9gb[4%], all indices on this node will be marked read-only

此时,所有写入、更新操作会失败,仅查询和删除操作可用。

解决步骤:恢复读写能力

紧急处理:释放磁盘空间

首先需释放足够的磁盘空间(建议至少保留 10% 以上空闲空间):

  • 删除无用的索引、日志文件或临时文件。
  • 迁移部分数据到其他存储(如冷数据归档)。

关闭磁盘水位线检查(临时)

若无法立即扩容,可临时关闭磁盘阈值检查,允许 Elasticsearch 忽略水位线限制:

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.threshold_enabled": "false" // 关闭阈值检查
}
}
  • persistent 表示配置永久生效(重启集群后仍有效);若需临时生效,可改用 transient

解除索引只读状态

磁盘空间释放后,需手动移除索引的只读标记:

1
2
3
4
5
6
7
8
9
10
11
// 解除所有索引的只读状态
PUT _all/_settings
{
"index.blocks.read_only_allow_delete": null // 设为null清除该限制
}

// 仅解除指定索引的只读状态(推荐)
PUT my_index/_settings
{
"index.blocks.read_only_allow_delete": null
}
  • read_only_allow_delete 是 Elasticsearch 在 flood_stage 时自动添加的限制,允许删除但禁止写入,需手动清除。

恢复磁盘水位线检查(可选)

磁盘扩容或空间充足后,建议重新开启磁盘阈值检查,保障集群稳定性:

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.threshold_enabled": "true" // 重新开启
}
}

优化配置:避免再次触发

1. 调整水位线阈值

根据业务需求调整水位线参数(如将 flood_stage 从 95% 降至 90%,提前预警):

1
2
3
4
5
6
7
8
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "80%",
"cluster.routing.allocation.disk.watermark.high": "85%",
"cluster.routing.allocation.disk.watermark.flood_stage": "90%"
}
}

2. 配置磁盘检查频率

调整 Elasticsearch 检查磁盘使用率的间隔(默认 30 秒):

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.info.update.interval": "1m" // 每1分钟检查一次
}
}

3. 自动清理过期数据

通过索引生命周期管理(ILM) 自动删除或归档过期数据,避免磁盘占满:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 创建ILM策略:7天后删除索引
PUT _ilm/policy/auto_delete_policy
{
"policy": {
"phases": {
"delete": {
"min_age": "7d",
"actions": {
"delete": {}
}
}
}
}
}

// 为索引应用ILM策略
PUT my_index/_settings
{
"index.lifecycle.name": "auto_delete_policy"
}

预防措施

  1. 监控磁盘使用率:通过 Kibana Monitoring 或 Prometheus 监控节点磁盘使用率,设置阈值告警(如超过 85% 时告警)。
  2. 定期清理数据:删除无用索引、压缩历史数据,或迁移到低成本存储(如 S3)。
  3. 合理规划索引生命周期:使用 ILM 自动管理索引(滚动、归档、删除),避免数据无限增长。
  4. 预留充足空间:确保集群磁盘容量满足至少 3 个月的数据增长需求,并及时扩容

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10