記錄ElasticSearch分片被鎖定導致無法分配處理過程

2023-11-07 12:00:42
本篇文章記錄最近ES做節點替換,從shard遷移過程中被鎖定導致無法分配,主shard正常,希望可以幫助其它人
failed to create shard,failed to obtain in-memory shard lock,ShardLockObtainFailedException

一、問題描述

這次遇到的問題比較特殊,嘗試過以下幾種手段都沒有恢復:

  1. _cluster/reroute手動分片shard
  2. 由於是從shard無法分片,所以當時試過將所以的副本改成0,然後再設定成1,想通過重新生成副本來解決,結果也失敗

接下來是排查問題的過程:

1、通過「GET _cat/shards/indexname」錯誤資訊如下,從shard無法分配,主shard正常,正常的shard未展示出來:
indexname                3     r      UNASSIGNED                                 
indexname                4     r      UNASSIGNED                                 
indexname                1     r      UNASSIGNED                                 

之前在運維過程中也遇到過UNASSIGNED這種從shard無法分配的問題,通過"allocate_replica"命令手動分配可以解決,這類問題一般都是因為node節點重啟或者失聯導致的shard分片異常

2、通過「GET _cluster/allocation/explain」錯誤資訊如下:

"index": "indexname",
  "shard": 3,
  "primary": false,
  "current_state": "unassigned",
  "unassigned_info": {
    "reason": "ALLOCATION_FAILED",
    "at": "2023-11-02T18:43:14.758Z",
    "failed_allocation_attempts": 300,
    "details": "failed shard on node [4MMOUt8-SMatWGCzX1asAQ]: failed to create shard, failure IOException[failed to obtain in-memory shard lock]; nested: ShardLockObtainFailedException[[indexname][3]: obtaining shard lock timed out after 5000ms]; ",
    "last_allocation_status": "no_attempt"
  },
  "can_allocate": "no",
  "allocate_explanation": "cannot allocate because allocation is not permitted to any of the nodes",

大多數情況下shard的allocate相關的問題都可以通過「GET _cluster/allocation/explain」命令獲取到有用的關鍵資訊,從返回的內容來分析是索引的第3個shard導致的,在node節點[4MMOUt8-SMatWGCzX1asAQ]被鎖定。

二、處理過程

知道問題原因了就有方法解決了,我準備了三套方案,如下:

前置工作

  1. 業務將索引的讀寫請求切走
  2. 建立一個測試索引驗證shard是否都正常
  3. 備份索引資料

方案1:重啟索引

--重新整理索引
POST indexname/_flush
--關閉索引
POST indexname/_close
---開啟索引
POST indexname/_open

在本次處理過程中,使用了方案1重啟索引就已經把問題解決了,但是方案一還是的業務配合將讀寫請求切走,否則索引close會導致應用的請求報錯

方案2:重啟節點node節點

[4MMOUt8-SMatWGCzX1asAQ]

PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "none"
}
}

PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "all"
}
}

方案2重啟鎖定shard的節點理論上來說也是可以解決這個問題,但是因為方案一已經解決了問題就沒機會做測試

方案3.重建索引

  1. 先還原備份到一個臨時索引,驗證資料沒問題
  2. 刪除當前索引,還原建立新索引
方案3是最後的方案了,如果方案1和2都解決不了的話只能通過方案3進行索引重建來解決,通過備份還原的方式來恢復索引其實也是很快的

三、思考總結

其實整個問題處理過程中還有一些其它的細節在文中沒有提到,就是叢集在預設開啟自動shard均衡過程中由於shard多長嘗試分片無法成功,達到預設的5次重試之後就會報錯,這個時候其實可以嘗試將叢集的自動分片關閉"cluster.routing.allocation.enable": "none",然後執行"POST /_cluster/reroute?retry_failed=true"來重置計數,最後通過手動分片shard的方式來做遷移也有可能能解決問題。只不過在每次遇到問題的時候需要結合當時的最佳場景去做判斷,尋找影響範圍最小的方案;

 

備註:

    作者:pursuer.chen

    部落格:http://www.cnblogs.com/chenmh

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連結。

《歡迎交流討論》