Elasticsearch集群異常狀態(tài)(RED、YELLOW)分析
集群狀態(tài)為什么會(huì)異常?
想知道這個(gè),我們首先需要了解一下集群的幾種狀態(tài)。
Elasticsearch 集群健康狀態(tài)分為三種:
- GREEN
- YELLOW
- RED
GREEN是最健康的狀態(tài),說(shuō)明所有的分片包括副本都可用。這種情況Elasticsearch集群所有的主分片和副本分片都已分配,Elasticsearch集群是100%可用的。
那么,集群狀態(tài)在什么情況下發(fā)生RED和YELLOW呢?
YELLOW:主分片可用,但是副本分片不可用。這種情況Elasticsearch集群所有的主分片已經(jīng)分配了,但至少還有一個(gè)副本是未分配的。不會(huì)有數(shù)據(jù)丟失,所以搜索結(jié)果依然是完整的。不過(guò),集群高可用性在某種程度上會(huì)被弱化。可以把yellow想象成一個(gè)需要關(guān)注的warnning,該情況不影響索引讀寫(xiě),一般會(huì)自動(dòng)恢復(fù)。
RED:存在不可用的主分片。此時(shí)執(zhí)行查詢雖然部分?jǐn)?shù)據(jù)仍然可以查到,但實(shí)際上已經(jīng)影響到索引讀寫(xiě),需要重點(diǎn)關(guān)注。這種情況Elasticsearch集群至少一個(gè)主分片(以及它的全部副本)都在缺失中。這意味著索引已缺少數(shù)據(jù),搜索只能返回部分?jǐn)?shù)據(jù),而分配到這個(gè)分片上的請(qǐng)求都返回異常。
查看集群狀態(tài)
使用kibana開(kāi)發(fā)工具,查看集群狀態(tài):
GET /_cluster/health

這里可以看到,當(dāng)前集群狀態(tài)為red,有9個(gè)未分配的分片
ES健康接口返回內(nèi)容官方解釋
|
指標(biāo) |
含義 |
|---|---|
|
cluster_name |
集群的名稱 |
|
status |
集群的運(yùn)行狀況,基于其主要和副本分片的狀態(tài)。狀態(tài)為:– green所有分片均已分配。– yellow所有主分片均已分配,但未分配一個(gè)或多個(gè)副本分片。如果群集中的某個(gè)節(jié)點(diǎn)發(fā)生故障,則在修復(fù)該節(jié)點(diǎn)之前,某些數(shù)據(jù)可能不可用。– red未分配一個(gè)或多個(gè)主分片,因此某些數(shù)據(jù)不可用。在集群?jiǎn)?dòng)期間,這可能會(huì)短暫發(fā)生,因?yàn)橐逊峙淞酥饕制?/p> |
|
timed_out |
如果false響應(yīng)在timeout參數(shù)指定的時(shí)間段內(nèi)返回(30s默認(rèn)情況下) |
|
number_of_nodes |
集群中的節(jié)點(diǎn)數(shù) |
|
number_of_data_nodes |
作為專用數(shù)據(jù)節(jié)點(diǎn)的節(jié)點(diǎn)數(shù) |
|
active_primary_shards |
活動(dòng)主分區(qū)的數(shù)量 |
|
active_shards |
活動(dòng)主分區(qū)和副本分區(qū)的總數(shù) |
|
relocating_shards |
正在重定位的分片的數(shù)量 |
|
initializing_shards |
正在初始化的分片數(shù) |
|
unassigned_shards |
未分配的分片數(shù) |
|
delayed_unassigned_shards |
其分配因超時(shí)設(shè)置而延遲的分片數(shù) |
|
number_of_pending_tasks |
尚未執(zhí)行的集群級(jí)別更改的數(shù)量 |
|
number_of_in_flight_fetch |
未完成的訪存數(shù)量 |
|
task_max_waiting_in_queue_millis |
自最早的初始化任務(wù)等待執(zhí)行以來(lái)的時(shí)間(以毫秒為單位) |
|
active_shards_percent_as_number |
群集中活動(dòng)碎片的比率,以百分比表示 |
問(wèn)題分析
當(dāng)集群狀態(tài)異常時(shí),需要重點(diǎn)關(guān)注unassigned_shards沒(méi)有正常分配的分片,這里舉例說(shuō)明其中一種場(chǎng)景。
找到異常索引
查看索引情況,并根據(jù)返回找到狀態(tài)異常的索引
GET /_cat/indices

查看詳細(xì)的異常信息
GET /_cluster/allocation/explain

這里通過(guò)異常信息可以看出:
- 主分片當(dāng)前處于未分配狀態(tài)(
current_state),發(fā)生這個(gè)問(wèn)題的原因是因?yàn)榉峙淞嗽摲制墓?jié)點(diǎn)已從集群中離開(kāi)(unassigned_info.reason); - 發(fā)生了上訴問(wèn)題之后,分片無(wú)法自動(dòng)分配分片的原因是集群中沒(méi)有該分片的可用副本(
can_allocate); - 同時(shí)也給出了更詳細(xì)的信息(
allocate_explanation)
這種情況發(fā)生的原因是因?yàn)榧河泄?jié)點(diǎn)下線,導(dǎo)致主分片已沒(méi)有任何可用的分片數(shù)據(jù),當(dāng)前唯一能做的事就是等待節(jié)點(diǎn)恢復(fù)并重新加入集群。
注:某些極端場(chǎng)景,比如單副本集群的分片發(fā)生了損壞,或是文件系統(tǒng)故障導(dǎo)致該節(jié)點(diǎn)被永久移除,而此時(shí)只能接受數(shù)據(jù)丟失的事實(shí),并通過(guò)reroute commends來(lái)重新分配空的主分片。
分片未分配(unassigned_info.reason)的所有可能
|
reason |
原因 |
|---|---|
|
INDEX_CREATED |
索引創(chuàng)建,由于API創(chuàng)建索引而未分配的 |
|
CLUSTER_RECOVERED |
集群恢復(fù),由于整個(gè)集群恢復(fù)而未分配 |
|
INDEX_REOPENED |
索引重新打開(kāi) |
|
DANGLING_INDEX_IMPORTED |
導(dǎo)入危險(xiǎn)的索引 |
|
NEW_INDEX_RESTORED |
重新恢復(fù)一個(gè)新索引 |
|
EXISTING_INDEX_RESTORED |
重新恢復(fù)一個(gè)已關(guān)閉的索引 |
|
REPLICA_ADDED |
添加副本 |
|
ALLOCATION_FAILED |
分配分片失敗 |
|
NODE_LEFT |
集群中節(jié)點(diǎn)丟失 |
|
REROUTE_CANCELLED |
reroute命令取消 |
|
REINITIALIZED |
重新初始化 |
|
REALLOCATED_REPLICA |
重新分配副本 |
可以通過(guò)上訴分析方式初步判斷集群產(chǎn)生未分配分片的原因,一般都可以在allocation explain api中得到想要的答案。
異常狀態(tài)分析
我們已經(jīng)了解了 ES 集群異常狀態(tài)分為 YELLOW 和 RED。
YELLOW:主分片可用,但是副本分片不可用。這種情況 Elasticsearch 集群所有的主分片已經(jīng)分配了,但至少還有一個(gè)副本是未分配的。不會(huì)有數(shù)據(jù)丟失,所以搜索結(jié)果依然是完整的。不過(guò),集群高可用性在某種程度上會(huì)被弱化。可以把 yellow 想象成一個(gè)需要關(guān)注的 warnning,該情況不影響索引讀寫(xiě),一般會(huì)自動(dòng)恢復(fù)。
RED:存在不可用的主分片。此時(shí)執(zhí)行查詢雖然部分?jǐn)?shù)據(jù)仍然可以查到,但實(shí)際上已經(jīng)影響到索引讀寫(xiě),需要重點(diǎn)關(guān)注。這種情況 Elasticsearch 集群至少一個(gè)主分片(以及它的全部副本)都在缺失中。這意味著索引已缺少數(shù)據(jù),搜索只能返回部分?jǐn)?shù)據(jù),而分配到這個(gè)分片上的請(qǐng)求都返回異常。
本文我們將講解集群在 YELLOW 異常狀態(tài)下的處理思路,以及哪些情況下無(wú)需人工干預(yù),哪些情況下需要人工干預(yù)。
YELLOW 異常
yellow 異常是 ES 最常見(jiàn)的集群異常,當(dāng)負(fù)載較高時(shí),集群往往會(huì)長(zhǎng)時(shí)間陷入 yellow 狀態(tài)無(wú)法脫離,其表現(xiàn)則是:
- 無(wú)需人工干預(yù),副本分片恢復(fù)緩慢,大部分副本分片處于排隊(duì)等待初始化
- 需要人工干預(yù),副本分片無(wú)法分配
無(wú)需人工干預(yù)
場(chǎng)景1:寫(xiě)入觸發(fā)索引創(chuàng)建(INDEX_CREATED)
ES 支持在索引不存在的情況下發(fā)起對(duì)該索引的寫(xiě)入,當(dāng)對(duì)不存在的索引發(fā)起寫(xiě)入時(shí),ES 會(huì)自動(dòng)創(chuàng)建該索引,并開(kāi)始自動(dòng)映射(put-mapping)不存在的索引字段,這是個(gè)很重的操作,會(huì)對(duì)元數(shù)據(jù)造成較大壓力。
尤其當(dāng)有大量寫(xiě)入或者集群本身元數(shù)據(jù)較大時(shí),ES 會(huì)延遲分配副本分片,進(jìn)入 pending_task 隊(duì)列,這則會(huì)導(dǎo)致集群陷入 yellow 狀態(tài)。這時(shí)即便副本分片開(kāi)始初始化,也會(huì)因?yàn)樗饕写罅繉?xiě)入而需要同步主分片數(shù)據(jù),進(jìn)而導(dǎo)致副本初始化緩慢。
整體表現(xiàn)就是集群長(zhǎng)時(shí)間處于 yellow 狀態(tài),短時(shí)間無(wú)法脫離,但這種情況都會(huì)自動(dòng)恢復(fù),當(dāng)副本分片初始化完成后,yellow 狀態(tài)也就變?yōu)?green 了。

如圖:當(dāng) URGENT Task過(guò)多時(shí),則會(huì)導(dǎo)致 HIGH Task 排隊(duì),進(jìn)入 pending 狀態(tài)
優(yōu)化建議:
業(yè)務(wù)提前預(yù)創(chuàng)建索引,而不是讓 bulk request 自動(dòng)觸發(fā)索引創(chuàng)建(create-index)。
場(chǎng)景2:節(jié)點(diǎn)臨時(shí)離線(NODE_LEFT)
我們假設(shè)集群當(dāng)中所有索引都有冗余副本分片,且只有一個(gè)節(jié)點(diǎn)宕機(jī)下線,那么集群這時(shí)會(huì)進(jìn)入 yellow 狀態(tài)。由于索引目前還有主分片在線,對(duì)業(yè)務(wù)的使用不會(huì)造成影響。如果節(jié)點(diǎn)是因?yàn)槎虝r(shí)間壓力過(guò)大而導(dǎo)致節(jié)點(diǎn)脫離,則一般會(huì)自動(dòng)恢復(fù),這種情況無(wú)需人工干預(yù):
[o.e.c.r.a.AllocationService] [1699879628011021732] failing shard [failed shard, shard [.ds-cdwch-2023.11.13-000404][23], node[vAnpreEnTaSWY-QYV3GGWg], [R], recovery_source[peer recovery], s[INITIALIZING], a[id=r48vj2pQRmauAuXKm-qX9g], unassigned_info[[reason=NODE_LEFT], at[2023-11-14T06:58:10.583Z], delayed=true, details[node_left [vAnpreEnTaSWY-QYV3GGWg]], allocation_status[no_attempt]], message [failed recovery], failure [RecoveryFailedException[[.ds-cdwch-2023.11.13-000404][23]: Recovery failed from {1675171390003468332}{QUotMJ0DRsiM442JPtqlmA}{2aWADQvMRjSKRRsFg-Abrw}{10.1.0.47}{10.1.0.47:9300}{hilrst}{ml.machine_memory=67168968704, rack=cvm_8_800007, xpack.installed=true, set=800007, transform.node=true, ip=9.15.118.138, ml.max_open_jobs=512, ml.max_jvm_size=34326183936, region=8} into {1670988404000091932}{vAnpreEnTaSWY-QYV3GGWg}{-vaCwjbhSpG1iGEY18Wz4A}{10.0.128.45}{10.0.128.45:9300}{hilrst}{ml.machine_memory=67168968704, rack=cvm_8_800006, xpack.installed=true, set=800006, transform.node=true, ip=9.15.104.46, ml.max_open_jobs=512, ml.max_jvm_size=34326183936, region=8}]; nested: RemoteTransportException[[1675171390003468332][10.1.0.47:9300][internal:index/shard/recovery/start_recovery]]; nested: ScpRecoveryIsRunningException[Another recovery task is running for same replica and node. Existing recovery: RecoveryKey{shard: [.ds-cdwch-2023.11
