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)