ES集羣red狀態排查與恢復

語言: CN / TW / HK

ES集羣red狀態排查與恢復

問題描述

ElasticSearch開箱即用,本身並沒有太多需要配置、調整的參數,平時使用中最大的問題應該就是red狀態的處理恢復了。現某用户使用的ES集羣報health狀態為red要求技術支持。我們首先看到用户提供的狀態信息:

json { "cluster_name" : "real_cluster", "status" : "red", "timed_out" : false, "number_of_nodes" : 101, "number_of_data_nodes" : 98, "active_primary_shards" : 12345, "active_shards" : 23456, "relocating_shards" : 0, "initializing_shards" : 40, "unassigned_shards" : 51, "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": 99.704321 }

上述信息後台可以通過命令獲取:

``` curl -X GET "localhost:9200/_cluster/health?pretty"

如果開啟Xpack了,需要帶上密碼訪問

curl -X GET -k -u username:passwd "https://localhost:9200/_cluster/health?pretty" ```

上述GET命令也可以直接粘貼在瀏覽器裏獲得結果。

問題定位

  1. 界面觀察

    已知信息是生產環境實際上的ES的數據節點(data node)理論上是99個,現在是98個,master節點是3個。

    用户已經反饋從管理界面上觀察ES所有實例服務狀態全部正常,但集羣health是red,這裏的差異在於管理頁面是檢查進程pid判斷是否存活的,而ES集羣內部則需要心跳發現機制,因此Web頁面顯示ES狀態ok,但health顯示少一個ES節點,表明有一個ES的數據節點(這裏稱為Slave節點)失聯了。

現在的首要任務就是找到99個es實例裏誰在濫竽充數,假裝活着!

  1. 後台日誌

後台先去查看ES的master的real_cluster.log,沒有找到關於連接的異常信息,裏面查不到ERROR。

後台再去看個ES的slave的日誌real_cluster.log,直接翻到最後,發現有連接類的錯誤出現了。

關鍵內容摘要如下:

shell xxx-slave failed to connect to xxx2-slave7 ConnectTransportException xxx2-slave7 general node connection failure ……省略很長一串at ……

這裏的關鍵信息就是一個slave報告説連不上【xxx2-slave7】,這就找到了。

查看更多其他slave節點的日誌,也都是報連不上xxx2-slave7

  1. 綜上,這個ES實例的名字知道了,順藤摸瓜,節點是xxx2,實例編號是slave7,這種錯誤一般是集羣壓力大,心跳通信出問題,我們需要去重啟這個ES實例。

問題處理

  1. 恢復失聯的那個ES實例:上一步我們已經定位到了問題節點,需要通過管理頁面重啟。

  2. 頁面顯示重啟該ES Slave成功(實際上沒有成),過一會兒觀察該實例並未在啟動狀態,ES仍是red,node仍然少一個。

  3. 再次啟動該ES實例,顯示成功不久後又掛掉了,屬於後台進程啟動不久後失敗,此時去後台查該實例的日誌發現有報錯:

shell # 關鍵詞 failed to bind service IOException: failed to find metadata for existing index xxx …… [locaton: xxx]

  1. 該問題處理辦法是刪除實例對應的manifest文件。

這個文件的位置在該ES實例的數據存儲目錄下,如/data/es/slave7/nodes/0/_state,其中nodes/0/_state這幾個目錄應該是不變的,前面的路徑隨配置。

這個_state下面有manifest-xxx.st文件,直接刪除或者備份後刪除該文件。

  1. 再次重啟該ES實例,如果等一會還未加入ES集羣,日誌裏顯示該節點頻繁add、remove,再次重啟該實例。

  2. 觀察health,好了ES的節點數完全恢復了(從98變回了99),集羣狀態很快從red變成yellow了。

  3. 重點觀察,initializing_shardsunassigned_shards一般逐漸減小,分片正在恢復中。

shell "initializing_shards" : 40, "unassigned_shards" : 51, …… "active_shards_percent_as_number": 99.884321

集羣活躍分片百分比升高,等所有分片恢復完成,則集羣會恢復green

索引分片數據量很大時,恢復需要花費幾個小時。

後續處理

  • 如果initializing_shards減小到0了,還有未分配的分片(unassigned_shards不是0),首先應查看未分配的原因,但一般情況可以先執行reroute命令:

shell # 尤其在報錯原因裏提示分配失敗是因為達到最大分配次數時,可使用這個命令。 POST /_cluster/reroute?retry_failed=true&pretty

  • 其他根據explain的原因對症下藥。

shell # 這個命令用來查看分片不分配的原因: curl -XGET -k -u name:pass https:esip:9200/_cluster/allocation/explain?pretty # 輸出的內容可能很多,可以保存到文件查看。

ES集羣異常修復與進階實踐 - 掘金 (juejin.cn)