事情起因
收到 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