Elasticsearch index read-only 问题解决办法

事情起因

收到 Zabbix 上 Elasticsearch 空间报警,当时没着急处理,过了一段时间 Kibana 查询发现其中的一个比较大的索引没有最新数据,当时的集群状态信息如下:

curl http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "docker-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 9,
  "number_of_data_nodes" : 9,
  "active_primary_shards" : 2756,
  "active_shards" : 4336,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 1176,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 78.66473149492018
}

集群状态为 yellow,且有大量未分配的分片。当前使用的 ES 集群是在 docker 中运行,ES 版本为 7.3,一共 9 个节点。

排查过程

登录 ES 服务器,排查发现 ES 容器的 json.log 日志文件中不断有大量日志,主要是:
[FORBIDDEN/12/index read-only / allow delete (api)]

Google 之后首先清理了部分旧索引以及 json.log 后,在 Kibana 页面的 Dev Tools 中使用 GET _settings 查看索引中 read_only_allow_delete 值为 true ,需要将其设置为 false 来解除索引只读限制。

PUT _settings 
{
    "index":{
        "blocks":{
            "read_only_allow_delete":"false"
        }
    }
}

解除只读限制后,再次查看 ES 容器中的 json.log,read-only 相关报错就没有了,索引也有新的数据产生了,问题暂时解决。

总结

引起该问题的主要原因是没有及时清理旧的索引数据,导致磁盘空间不足,进而触发了 ES 自身基于磁盘的分片策略。

关于 ES 中的磁盘分配决策策略:

cluster.routing.allocation.disk.threshold_enabled 默认为 true,设置为 false 禁用磁盘分配决定器。

cluster.routing.allocation.disk.watermark.low 控制磁盘使用率的低水位线。它的默认值为 85%,这意味着 Elasticsearch 不会将分片分配给使用了超过 85% 磁盘的节点。

cluster.routing.allocation.disk.watermark.high 控制高水位线。默认为 90%,表示 Elasticsearch 将尝试将分片从磁盘使用率超过 90% 的节点移到其他节点。

cluster.routing.allocation.disk.watermark.flood_stage 默认为 95%,这意味着在每个节点上分配了一个或多个分片的每个索引上强制执行一个只读索引块(),一旦有足够的磁盘空间可用于继续进行索引操作,则必须手动解除限制。

cluster.info.update.interval 默认为 30s,Elasticsearch 应该多久检查一次集群中每个节点的磁盘使用情况。

参考:https://www.elastic.co/guide/en/elasticsearch/reference/7.3/disk-allocator.html

目前的 EFK 也只是搭建了一个集群收集日志,没有任何优化设置,打算先写个脚本定期删除旧的索引数据。也不知道后续还有什么坑会踩到,再慢慢优化调整吧。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注