1. 故障分析與排查
一個 Elasticsearch 集群至少包括一個節點和一個索引。或者它 可能有一百個數據節點、三個單獨的主節點,以及一小打客戶端節點——這些共同操作一千個索引(以及上萬個分片)。
不管集群擴展到多大規模,你都會想要一個快速獲取集群狀態的途徑。Cluster Health API 充當的就是這個角色。你可以把它想象成是在一萬英尺的高度鳥瞰集群。它可以告訴你安心吧一切都好,或者警告你集群某個地方有問題。
讓我們執行一下 cluster-health API 然后看看響應體是什么樣子的:
GET _cluster/health
和 Elasticsearch 里其他 API 一樣,cluster-health 會返回一個 JSON 響應。這對自動化和告警系統來說,非常便於解析。響應中包含了和你集群有關的一些關鍵信息:
{
"cluster_name": "elasticsearch_zach",
"status": "green",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 10,
"active_shards": 10,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
``
響應信息中最重要的一塊就是 status 字段。狀態可能是下列三個值之一:
*green*
所有的主分片和副本分片都已分配。你的集群是 100% 可用的。
*yellow*
所有的主分片已經分片了,但至少還有一個副本是缺失的。不會有數據丟失,所以搜索結果依然是完整的。不過,你的高可用性在某種程度上被弱化。如果 更多的 分片消失,你就會丟數據了。把 yellow 想象成一個需要及時調查的警告。
*red*
至少一個主分片(以及它的全部副本)都在缺失中。這意味着你在缺少數據:搜索只能返回部分數據,而分配到這個分片上的寫入請求會返回一個異常。
green/yellow/red 狀態是一個概覽你的集群並了解眼下正在發生什么的好辦法。剩下來的指標給你列出來集群的狀態概要:
number_of_nodes 和 number_of_data_nodes 這個命名完全是自描述的。
active_primary_shards 指出你集群中的主分片數量。這是涵蓋了所有索引的匯總值。
active_shards 是涵蓋了所有索引的_所有_分片的匯總值,即包括副本分片。
relocating_shards 顯示當前正在從一個節點遷往其他節點的分片的數量。通常來說應該是 0,不過在 Elasticsearch 發現集群不太均衡時,該值會上漲。比如說:添加了一個新節點,或者下線了一個節點。
initializing_shards 是剛剛創建的分片的個數。比如,當你剛創建第一個索引,分片都會短暫的處於 initializing 狀態。這通常會是一個臨時事件,分片不應該長期停留在 initializing 狀態。你還可能在節點剛重啟的時候看到 initializing 分片:當分片從磁盤上加載后,它們會從 initializing 狀態開始。
unassigned_shards 是已經在集群狀態中存在的分片,但是實際在集群里又找不着。通常未分配分片的來源是未分配的副本。比如,一個有 5 分片和 1 副本的索引,在單節點集群上,就會有 5 個未分配副本分片。如果你的集群是 red 狀態,也會長期保有未分配分片(因為缺少主分片)。
鑽更深點:找到問題索引編輯
想象一下某天碰到問題了, 而你發現你的集群健康狀態看起來像是這樣:
{
"cluster_name": "elasticsearch_zach",
"status": "red",
"timed_out": false,
"number_of_nodes": 8,
"number_of_data_nodes": 8,
"active_primary_shards": 90,
"active_shards": 180,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 20
}
好了,從這個健康狀態里我們能推斷出什么來?嗯,我們集群是 red ,意味着我們缺數據(主分片 + 副本分片)了。我們知道我們集群原先有 10 個節點,但是在這個健康狀態里列出來的只有 8 個數據節點。有兩個數據節點不見了。我們看到有 20 個未分配分片。
這就是我們能收集到的全部信息。那些缺失分片的情況依然是個謎。我們是缺了 20 個索引,每個索引里少 1 個主分片?還是缺 1 個索引里的 20 個主分片?還是 10 個索引里的各 1 主 1 副本分片?具體是哪個索引?
要回答這個問題,我們需要使用 level 參數讓 cluster-health 答出更多一點的信息:
GET _cluster/health?level=indices
這個參數會讓 cluster-health API 在我們的集群信息里添加一個索引清單,以及有關每個索引的細節(狀態、分片數、未分配分片數等等):
{
"cluster_name": "elasticsearch_zach",
"status": "red",
"timed_out": false,
"number_of_nodes": 8,
"number_of_data_nodes": 8,
"active_primary_shards": 90,
"active_shards": 180,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 20
"indices": {
"v1": {
"status": "green",
"number_of_shards": 10,
"number_of_replicas": 1,
"active_primary_shards": 10,
"active_shards": 20,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
},
"v2": {
"status": "red",
"number_of_shards": 10,
"number_of_replicas": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 20
},
"v3": {
"status": "green",
"number_of_shards": 10,
"number_of_replicas": 1,
"active_primary_shards": 10,
"active_shards": 20,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
},
....
}
}
我們可以看到 v2 索引就是讓集群變 red 的那個索引。
由此明確了,20 個缺失分片全部來自這個索引。
一旦我們詢問要索引的輸出,哪個索引有問題立馬就很清楚了:v2 索引。我們還可以看到這個索引曾經有 10 個主分片和一個副本,而現在這 20 個分片全不見了。可以推測,這 20 個索引就是位於從我們集群里不見了的那兩個節點上。
level 參數還可以接受其他更多選項:
GET _cluster/health?level=shards
shards 選項會提供一個詳細得多的輸出,列出每個索引里每個分片的狀態和位置。這個輸出有時候很有用,但是由於太過詳細會比較難用。如果你知道哪個索引有問題了,本章討論的其他 API 顯得更加有用一點。
阻塞等待狀態變化編輯
當構建單元和集成測試時,或者實現和 Elasticsearch 相關的自動化腳本時,cluster-health API 還有另一個小技巧非常有用。你可以指定一個 wait_for_status 參數,它只有在狀態達標之后才會返回。比如:
GET _cluster/health?wait_for_status=green
這個調用會 阻塞 (不給你的程序返回控制權)住直到 cluster-health 變成 green ,也就是說所有主分片和副本分片都分配下去了。這對自動化腳本和測試非常重要。
如果你創建一個索引,Elasticsearch 必須在集群狀態中向所有節點廣播這個變更。那些節點必須初始化這些新分片,然后響應給主節點說這些分片已經 Started 。這個過程很快,但是因為網絡延遲,可能要花 10–20ms。
如果你有個自動化腳本是 (a) 創建一個索引然后 (b) 立刻寫入一個文檔,這個操作會失敗。因為索引還沒完全初始化完成。在 (a) 和 (b) 兩步之間的時間可能不到 1ms —— 對網絡延遲來說這可不夠。
比起使用 sleep 命令,直接讓你的腳本或者測試使用 wait_for_status 參數調用 cluster-health 更好。當索引完全創建好,cluster-health 就會變成 green ,然后這個調用就會把控制權交還給你的腳本,然后你就可以開始寫入了。
有效的選項是: green 、 yellow 和 red 。這個調回會在達到你要求(或者『更高』)的狀態時返回。比如,如果你要求的是 yellow ,狀態變成 yellow 或者 green 都會打開調用。
## 2.問題提解決
經分析 應該是磁盤空間不足導致的,自盤空間使用率高於90,備份分片不再繼續寫入。
curl -H "Content-Type: application/json" -XPUT --user elastic:vwnzcs57xwvqwcqqx8cbqn8r https://10.107.168.84:9200/_cluster/settings -k -d '{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%"
}
}'
通過以上命令調整閾值。
