Elasticsearch運維指南

西门运维發表於2024-03-20

1.常用監控工具

1.1 cerebro⼯具

地址:https://github.com/lmenezes/cerebro

1.2 Kibana Stack Monitoring

地址: https://www.elastic.co/guide/en/kibana/current/xpack-monitoring.html

2. 關鍵指標監控

2.1 叢集健康維度:分⽚和節點

透過GET _cluster/health監視群集時,可以查詢叢集的狀態、節點數和活動分⽚計數的資訊。還可

以檢視重新定位分⽚,初始化分⽚和未分配分⽚的計數。

{
  "cluster_name" : "my_cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 43,
  "active_shards" : 77,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 2,
  "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" : 97.46835443037975
}

叢集運⾏的重要指標:

Status:狀態群集的狀態。紅⾊:部分主分⽚未分配。⻩⾊:部分副本分⽚未分配。綠⾊:所有

分⽚分配ok。

Nodes:群集中的節點總數。

Shards:活動分⽚計數。叢集中活動分⽚的數量。 Relocating Shards:重定位分⽚。由於節

點丟失⽽移動的分⽚計數。

Initializing Shards:初始化分⽚。由於新增索引等⽽初始化的分⽚計數。

Unassigned Shards:未分配的分⽚。尚未建立或分配副本的分⽚計數。

未分配狀態及原因解讀:

1)INDEX_CREATED
 Unassigned as a result of an API creation of an index.
(2)CLUSTER_RECOVERED
 Unassigned as a result of a full cluster recovery.
(3)INDEX_REOPENED
 Unassigned as a result of opening a closed index.
(4)DANGLING_INDEX_IMPORTED
 Unassigned as a result of importing a dangling index.
(5)NEW_INDEX_RESTORED
 Unassigned as a result of restoring into a new index.
(6)EXISTING_INDEX_RESTORED
 Unassigned as a result of restoring into a closed index.
(7)REPLICA_ADDED
 Unassigned as a result of explicit addition of a replica.
(8)ALLOCATION_FAILED
 Unassigned as a result of a failed allocation of the shard.
(9)NODE_LEFT
 Unassigned as a result of the node hosting it leaving the cluste
r.
(10)REROUTE_CANCELLED
 Unassigned as a result of explicit cancel reroute command.
(11)REINITIALIZED
When a shard moves from started back to initializing, for exampl
e, with shadow replicas.
(12)REALLOCATED_REPLICA
A better replica location is identified and causes the existing r
eplica allocation to be cancelled.

2.2 搜尋效能維度:請求率和延遲

透過測量系統處理請求的速率和每個請求的使⽤時間可以衡量叢集的有效性;

當叢集收到請求時,可能需要跨多個節點訪問多個分⽚中的資料。系統處理和返回請求的速率、當

前正在進⾏的請求數以及請求的持續時間等核⼼指標是衡量叢集健康重要因素。

請求過程本身分為兩個階段:

第⼀是查詢階段(query phase),叢集將請求分發到索引中的每個分⽚(主分⽚或副本分

⽚)。

第⼆個是獲取階段(fetch phrase),查詢結果被收集,處理並返回給⽤戶。

透過GET blogs_analyzed/_stats可以檢視對應目標索引的狀態,search狀態查詢的結果如下:

 "search" : {
        "open_contexts" : 0,
        "query_total" : 0,
        "query_time_in_millis" : 0,
        "query_current" : 0,
        "fetch_total" : 0,
        "fetch_time_in_millis" : 0,
        "fetch_current" : 0,
        "scroll_total" : 0,
        "scroll_time_in_millis" : 0,
        "scroll_current" : 0,
        "suggest_total" : 0,
        "suggest_time_in_millis" : 0,
        "suggest_current" : 0
      }

請求檢索效能相關的重要指標如下:

  • query_current:當前正在進⾏的查詢數。叢集當前正在處理的查詢計數。
  • fetch_current:當前正在進⾏的fetch次數。叢集中正在進⾏的fetch計數。
  • query_total:查詢總數。叢集處理的所有查詢的聚合數。
  • query_time_in_millis:查詢總耗時。所有查詢消耗的總時間(以毫秒為單位)。
  • fetch_total:提取總數。叢集處理的所有fetch的聚合數。
  • fetch_time_in_millis:fetch所花費的總時間。所有fetch消耗的總時間(以毫秒為單位)。

2.3 索引效能維度:重新整理(refresh)和合並(Merge)時間

監視⽂檔的索引速率( indexing rate )和合並時間(merge time)有助於在開始影響叢集效能之

前提前識別異常和相關問題。將這些指標與每個節點的運⾏狀況並⾏考慮,這些指標為系統內的潛

問題提供重要線索,為效能最佳化提供重要參考。

可以透過GET /_nodes/stats獲取索引效能指標,並可以在節點,索引或分⽚級別進⾏彙總。

        "merges" : {
          "current" : 0,
          "current_docs" : 0,
          "current_size_in_bytes" : 0,
          "total" : 184,
          "total_time_in_millis" : 23110,
          "total_docs" : 1017919,
          "total_size_in_bytes" : 342535815,
          "total_stopped_time_in_millis" : 0,
          "total_throttled_time_in_millis" : 0,
          "total_auto_throttle_in_bytes" : 524288000
        },
        "refresh" : {
          "total" : 1842,
          "total_time_in_millis" : 20327,
          "external_total" : 1583,
          "external_total_time_in_millis" : 19195,
          "listeners" : 0
        },
        "flush" : {
          "total" : 21,
          "periodic" : 0,
          "total_time_in_millis" : 131
        },

索引效能維度相關重要指標:

  • refresh.total:總重新整理計數。重新整理總數的計數。
  • refresh.total_time_in_millis:重新整理總時間。彙總所有花在重新整理的時間(以毫秒為單位進⾏測
  • 量)。
  • merges.current_docs:⽬前的合併。合併⽬前正在處理中。
  • merges.total_docs:合併總數。合併總數的計數。
  • merges.total_time_in_millis。合併花費的總時間。合併段的所有時間的聚合。

2.4 節點運⾏狀況維度:記憶體,磁碟和CPU指標

Elasticsearch是⼀個嚴重依賴記憶體 以實現效能的系統,因此密切關注記憶體使⽤情況與每個節點的

運⾏狀況和效能相關。改進指標的相關配置更改也可能會對記憶體分配和使⽤產⽣負⾯影響,因此記

住從整體上檢視系統運⾏狀況⾮常重要。

監視節點的CPU使⽤情況並查詢峰值有助於識別節點中的低效程序或潛在問題。CPU效能與Java虛

擬機(JVM)的垃圾收集過程密切相關。

GET /_cat/nodes?v&h=id,disk.total,disk.used,disk.avail,disk.used_percent,ram.current,ram.percent,ram.max,cpu
id   disk.total disk.used disk.avail disk.used_percent ram.current ram.percent ram.max cpu
jg1X     19.9gb    16.2gb      3.7gb             81.15       1.8gb          96   1.9gb   0
ZnpM     19.9gb    16.4gb      3.4gb             82.52       1.7gb          91   1.9gb   0
Hyt2     19.9gb    16.2gb      3.7gb             81.16       1.8gb          96   1.9gb   0

節點運⾏的重要指標:

  • disk.total :總磁碟容量。節點主機上的總磁碟容量。
  • disk.used:總磁碟使⽤量。節點主機上的磁碟使⽤總量。
  • avail disk:可⽤磁碟空間總量。
  • disk.avail disk.used_percent:使⽤的磁碟百分⽐。已使⽤的磁碟百分⽐。
  • ram:當前的RAM使⽤情況。當前記憶體使⽤量(測量單位)。
  • percent ram:RAM百分⽐。正在使⽤的記憶體百分⽐。
  • max : 最⼤RAM。 節點主機上的記憶體總量
  • cpu:中央處理器。正在使⽤的CPU百分⽐。

2.4.1 如何檢視io壓⼒

1 iostat -d -k 1 10     #檢視TPS和吞吐量資訊(磁碟讀寫速度單位為KB)
2 iostat -d -m 2        #檢視TPS和吞吐量資訊(磁碟讀寫速度單位為MB)
3 iostat -d -x -k 1 10  #檢視裝置使⽤率(%util)、響應時間(await)
4 iostat -c 1 10        #檢視cpu狀態例項分析

可以根據 iowait , ioutil 等值來綜合判斷. 當iowait⻓期接近100%基本代表io系統出現瓶頸了。這時候可

以⽤iotop命令來診斷出具體是什麼程序在消耗io資源。

2.5 JVM運⾏狀況維度:堆,GC和池⼤⼩(Pool Size)

作為基於Java的應⽤程式,Elasticsearch在Java虛擬機器(JVM)中運⾏。JVM在其“堆”分配中管

理其記憶體,並透過garbage collection進⾏垃圾回收處理。

如果應⽤程式的需求超過堆的容量,則應⽤程式開始強制使⽤連線的儲存介質上的交換空間。雖然

這可以防⽌系統崩潰,但它可能會對叢集的效能造成嚴重破壞。監視可⽤堆空間以確保系統具有⾜

夠的容量對於叢集的健康⾄關重要。

JVM記憶體分配給不同的記憶體池。您需要密切注意這些池中的每個池,以確保它們得到充分利⽤並且

沒有被超限利⽤的⻛險。

垃圾收集器(GC)很像物理垃圾收集服務。我們希望讓它定期運⾏,並確保系統不會讓它過載。理

想情況下,GC效能檢視應類似均衡波浪線⼤⼩的常規執⾏。尖峰和異常可以成為更深層次問題的指

標。

可以透過GET /_nodes/stats 命令檢索JVM度量標準。

      "jvm" : {
        "timestamp" : 1623964232904,
        "uptime_in_millis" : 5786635,
        "mem" : {
          "heap_used_in_bytes" : 294418688,
          "heap_used_percent" : 28,
          "heap_committed_in_bytes" : 1038876672,
          "heap_max_in_bytes" : 1038876672,
          "non_heap_used_in_bytes" : 167878480,
          "non_heap_committed_in_bytes" : 181440512,
          "pools" : {
            "young" : {
              "used_in_bytes" : 153960136,
              "max_in_bytes" : 279183360,
              "peak_used_in_bytes" : 279183360,
              "peak_max_in_bytes" : 279183360
            },
            "survivor" : {
              "used_in_bytes" : 12341536,
              "max_in_bytes" : 34865152,
              "peak_used_in_bytes" : 34865136,
              "peak_max_in_bytes" : 34865152
            },
            "old" : {
              "used_in_bytes" : 128117016,
              "max_in_bytes" : 724828160,
              "peak_used_in_bytes" : 128117016,
              "peak_max_in_bytes" : 724828160
            }
          }
        },
        "threads" : {
          "count" : 108,
          "peak_count" : 114
        },
        "gc" : {
          "collectors" : {
            "young" : {
              "collection_count" : 256,
              "collection_time_in_millis" : 2136
            },
            "old" : {
              "collection_count" : 2,
              "collection_time_in_millis" : 151
            }
          }
        },

JVM運⾏的重要指標如下:

  • mem:記憶體使⽤情況。堆和⾮堆程序和池的使⽤情況統計資訊。
  • threads:當前使⽤的執行緒和最⼤數量。
  • gc:垃圾收集。算和垃圾收集所花費的總時間。

3. 常⽤命令清單

3.1 檢視叢集狀態

# 叢集狀態檢視
GET _cluster/health
# 找到對應的索引,health可選值green, yellow, red
GET /_cat/indices?v&health=red
# 詳細檢視未分配原因
GET _cluster/allocation/explain
# 檢視具體的索引,分⽚以及未分配原因
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason&v
# 檢視資料分佈情況
GET _cat/allocation?v

3.2 節點間分⽚移動

⼿動移動分配分⽚。將啟動的分⽚從⼀個節點移動到另⼀節點。

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "indexname",
        "shard": 1,
        "from_node": "nodename",
        "to_node": "nodename"
      }
    }
  ]
}

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "test",
        "shard": 0,
        "from_node": "node1",
        "to_node": "node2"  # 將test 的shard 0分⽚從node1移動到nod
e2
      }
    },
    {
      "allocate_replica": {
        "index": "test",
        "shard": 1,
        "node": "node3"   # test索引的shard 1 分配到node3
      }
    },
    {
      "cancel": {
        "index": "test",
        "shard": 0,
        "node": "node2"   # 取消在node2上⾯分配test的shard 0 分⽚
      }
    }
  ]
}

allocate_stale_primary:以叢集記憶體在的陳舊的分⽚內容,再次分配。
allocate_empty_primary:分配空內容的分⽚

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_stale_primary": {
        "index": "dcvs_aps",
        "shard": 3,
        "node": "MYSQL2",
        "accept_data_loss": true
      }
    }
  ]
}

設定分配的最⼤失敗重試次數,預設是5次,當然系統分配到達重試次數後,可以⼿動分配分⽚ 。"index.allocation.max_retries" : "5",

POST _cluster/reroute?retry_failed

3.3 叢集節點優雅下線

保證叢集顏⾊綠⾊的前提下,將某個節點優雅下線。

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.exclude._ip": "192.168.248.1"
  }
}

3.4 強制重新整理

重新整理索引是確保當前僅儲存在事務⽇志中的所有資料也永久儲存在Lucene索引中。

注意:7.6及之後版本會廢棄同步重新整理改⽤_flush

 # >=7.6版本
 POST /_flush

 # <7.6版本使⽤同步重新整理
 POST /_flush/synced

3.5 更改併發分⽚的數量以平衡叢集

控制在叢集範圍內允許多少併發分⽚重新平衡。預設值為2。

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.cluster_concurrent_rebalance": 2
  }
}

3.6 開啟和關閉分片自動重均衡

Elasticsearch在業務高峰期進行分片重均衡會造成網路延遲或者io異常等現象,所以可以選擇在業務低峰期開啟ES分片自動均衡。

關閉ES自動重均衡
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.rebalance.enable":"none"
  }
}
開啟ES自動重均衡
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.rebalance.enable":"all"
  }
}

註釋:

  • transient:臨時調整叢集配置,整個叢集重啟後,對應引數失效;
  • persistent: 永久調整叢集配置,整個叢集重啟後,對應引數仍然有效;

3.7 更改每個節點同時恢復的分⽚數量

如果節點已從叢集斷開連線,則其所有分⽚將都變為未分配狀態。經過⼀定的延遲後,分⽚將分配到其他

位置。每個節點要恢復的併發分⽚數由該設定確定。

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.node_concurrent_recoveries": 6
  }
}

3.8 調整恢復速度

為了避免叢集過載,Elasticsearch限制了分配給恢復的速度。你可以仔細更改該設定,以使其恢復更快。

如果此值調的太⾼,則正在進⾏的恢復可能會消耗過多的頻寬和其他資源,這可能會使叢集不穩定。

PUT /_cluster/settings
{
  "transient": {
    "indices.recovery.max_bytes_per_sec": "80mb"
  }
}

3.9 清除節點上的快取

如果節點達到較⾼的JVM值,則可以在節點級別上調⽤該API 以使 Elasticsearch 清理快取。

注意:這會降低效能,但可以使你擺脫OOM(記憶體不⾜)的困擾。

 # 清除所有索引的所有快取
 POST /_cache/clear

 # 清除特定索引的特定cache
 POST /my-index-000001/_cache/clear?fielddata=true
 POST /my-index-000001/_cache/clear?query=true
 POST /my-index-000001/_cache/clear?request=true

3.10 調整斷路器

斷熔器透過內部檢查(欄位的型別、基數、⼤⼩等等)來估算⼀個查詢需要的記憶體。它然後檢查要求載入的 fielddata 是否會導致 fielddata 的總量超過堆的配置⽐例。

如果估算查詢的⼤⼩超出限制,就會觸發斷路器,查詢會被中⽌並返回異常。這都發⽣在資料載入之前,也就意味著不會引起 OutOfMemoryException 。

#1.檢視斷路器
GET /_nodes/stats/breaker?pretty
GET /_cluster/settings?include_defaults&flat_settings

#2.⽗斷路器:預設95%,所有斷路器的⽗斷路器,保證所有的heap使⽤率不會超過該值
indices.breaker.total.limit

#3.fielddata斷路器:fielddata斷路器可以估算每⼀個field的所有資料被載入到記憶體中,需要耗費多⼤的記憶體。
 # 預設40%heap,7.9之前是60%
 indices.breaker.fielddata.limit
 #可以配置估算因⼦,估算出來的值會乘以這個估算因⼦,留⼀些buffer,預設是1.03。
 indices.breaker.fielddata.overhead
indices.breaker.fielddata.limit 必須⼤於 indices.fielddata.cache.size,否則只會觸發fielddata
circuit breaker,⽽不會剔除舊的fielddata。

#4.request circuit breaker
request circuit breaker可以阻⽌由於某個請求對應的⼀些資料結構造成的OOM(⽐如⼀個聚合請求可能
會⽤jvm記憶體來做⼀些彙總計算)。
indices.breaker.request.limit # 預設 60%

#5.in flight request circuit breaker
flight request circuit breaker可以限制當前所有進來的transport或http層的請求所使⽤記憶體總量,這個
記憶體的使⽤量就是請求⾃⼰本身的⻓度。
network.breaker.inflight_requests.limit # 預設100%
設定方法如下:
PUT /_cluster/settings
{
  "persistent": {
    "indices.breaker.total.limit": "40%"
  }
}

3.11 ElasticSearch 使⽤低速裝置的 Tips

單個分⽚上⼀次合併的最⼤執行緒數。該引數影響lucene後臺的合併執行緒數量,預設設定只適合SDD。如果多個合併執行緒可能導致io壓⼒過⼤。

PUT movies/_settings
{
  "index.merge.scheduler.max_thread_count":1
}

3.12 限制每個節點分⽚數

index級別上設定index.routing.allocation.total_shards_per_node 避免同⼀個index的多個shard分配到同⼀個node

# index級別
index.routing.allocation.total_shards_per_node

# node級別,所有索引
cluster.routing.allocation.total_shards_per_node

3.13 檢視任務tasks

返回叢集中⼀個或多個節點上當前執⾏的任務資訊。

 GET _tasks
 GET _tasks?nodes=nodeId1,nodeId2
 GET _tasks?nodes=nodeId1,nodeId2&actions=cluster:*


 # task詳情
 GET /_tasks/<task_id>
 GET _tasks/oTUltX4IQMOUUVeiohTt8A:124
 GET _tasks?actions=*search&detailed

3.14 取消任務

 POST _tasks/oTUltX4IQMOUUVeiohTt8A:12345/_cancel
 POST _tasks/_cancel?nodes=nodeId1,nodeId2&actions=*reindex

3.15 檢視pending tasks

返回尚未執⾏的叢集級更改列表,如建立索引、更新對映、分配碎⽚等。

 GET /_cluster/pending_tasks
 GET /_cat/pending_tasks

3.16 叢集級別分⽚分配

# 啟⽤或禁⽤對特定種類的分⽚的分配
cluster.routing.allocation.enable: all # 預設all
all -(預設值)允許為所有型別的分⽚分配分⽚。
primaries -僅允許為主分⽚分配。
new_primaries -僅允許為新索引的主分⽚分配。
none -不允許對任何索引進⾏任何型別的分⽚分配。
# ⼀個節點上允許進⾏多少併發的傳⼊分⽚恢復
 cluster.routing.allocation.node_concurrent_incoming_recoveries #
認2
 # ⼀個節點上允許進⾏多少併發的傳出分⽚恢復
 cluster.routing.allocation.node_concurrent_outgoing_recoveries #
認2
 # 同時設定以上兩個值
 cluster.routing.allocation.node_concurrent_recoveries
 # 節點初始化主分⽚數
 cluster.routing.allocation.node_initial_primaries_recoveries #
預設4

3.17 分⽚平衡配置

群集的平衡僅取決於每個節點上的分⽚數量以及這些分⽚所屬的索引

 # 為特定種類的分⽚啟⽤或禁⽤重新平衡
 cluster.routing.rebalance.enable
 all -(預設值)允許所有種類的分⽚進⾏分⽚平衡。
 primaries -僅允許對主要分⽚進⾏分⽚平衡。
 replicas -僅允許對副本分⽚進⾏分⽚平衡。
 none -任何索引都不允許任何形式的分⽚平衡。

 # 允許控制在叢集範圍內允許多少併發分⽚重新平衡。預設為2
 cluster.routing.allocation.cluster_concurrent_rebalance

3.18 基於磁碟的分⽚分配

# 預設為true。設定為false禁⽤磁碟分配決定器。
cluster.routing.allocation.disk.threshold_enabled
cluster.routing.allocation.disk.threshold_enabled # 預設true,啟⽤磁碟空間閾值檢查
cluster.routing.allocation.disk.watermark.low # 預設85%,分⽚不會分配(除新建的索引的主分⽚不受影響)
cluster.routing.allocation.disk.watermark.high # 預設90%,達到該值,ES會做relocate,影響所有分⽚
cluster.routing.allocation.disk.watermark.flood_stage # 預設95%, index.blocks.read_only_allow_delete,當磁碟使⽤率低於95%,(>=7.4)⾃動釋放index.blocks
cluster.info.update.interval # 預設30s設定多久檢查⼀次磁碟
# 可以配置具體⼤⼩
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "100gb",
    "cluster.routing.allocation.disk.watermark.high": "50gb",
    "cluster.routing.allocation.disk.watermark.flood_stage": "10gb",
    "cluster.info.update.interval": "1m"
  }
}

 # 或者使⽤百分⽐
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "85%",
    "cluster.routing.allocation.disk.watermark.high": "90%",
    "cluster.routing.allocation.disk.watermark.flood_stage": "95%",
    "cluster.info.update.interval": "1m"
  }
}
 # 當磁碟使⽤率超過flood_stage閾值是索引被設定為只讀,可透過以下命令⼿動恢復讀寫
 PUT /my-index-000001/_settings
 {
 "index.blocks.read_only_allow_delete": null
 }

3.19 Segment檢視段/合併段

GET /twitter/_segments
POST /twitter/_forcemerge?max_num_segments=1

3.20 關閉模糊_all / *刪除(避免誤刪)

 PUT _cluster/settings
{
"persistent": {
"action.destructive_requires_name":true
}
}

相關文章