天天看點

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

作者:騰雲憶想

導 讀

騰訊雲Elasticsearch Service(ES)是基于開源搜尋引擎 Elasticsearch 打造的高可用、可伸縮的雲端全托管的 Elasticsearch 服務,包含 Kibana 及常用插件,并內建了安全、SQL、機器學習、告警、監控等進階特性(X-Pack)。使用騰訊雲 ES,您可以快速部署、輕松管理、按需擴充您的叢集,簡化複雜運維操作,快速建構日志分析、異常監控、網站搜尋、企業搜尋、BI 分析等各類業務。

作者簡介

嶽濤

騰雲憶想大資料産品架構師,多年分布式、高并發大資料系統的研發、系統架構設計經驗,擅長主流大資料架構技術平台的落地和實施。目前專注于大資料架構相關元件的研究推廣和最佳實踐的沉澱,緻力于幫助企業完成數字化轉型。

背 景

前面我們學習了《Elasticsearch叢集異常狀态(RED、YELLOW)原因分析》,了解到了當叢集發生主分片無法上線的情況下,叢集狀态會變為RED,此時相應的RED索引讀寫請求都會受到嚴重的影響。這裡我們将介紹在實際使用中,極端場景下ES叢集異常崩潰且無法恢複的一種情況。

問 題

業務突然不可用,持續收到報錯:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件
通過觀察叢集日志,發現ES叢集始終處于無主狀态,無法自我恢複:

Caused by: ClusterBlockException[blocked by: [SERVICE_UNAVAILABLE/2/no master];]
        at org.elasticsearch.cluster.block.ClusterBlocks.globalBlockedException(ClusterBlocks.java:158)
        at org.elasticsearch.cluster.block.ClusterBlocks.globalBlockedRaiseException(ClusterBlocks.java:144)
        at org.elasticsearch.action.bulk.TransportBulkAction.executeBulk(TransportBulkAction.java:204)
        at org.elasticsearch.action.bulk.TransportBulkAction.doExecute(TransportBulkAction.java:151)
        at org.elasticsearch.action.bulk.TransportBulkAction.doExecute(TransportBulkAction.java:71)
        at org.elasticsearch.action.support.TransportAction.doExecute(TransportAction.java:149)
        at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:137)           

<左右滑動檢視全文>

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件
騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

觀察監控發現叢集崩潰前,CPU使用率始終處于瓶頸狀态。

解決過程

一:重新開機叢集并切斷流量

(無效)

當我們發現叢集已經徹底崩潰,為了讓叢集可以盡快恢複,第一時間對叢集做了一次全量重新開機,然後切斷了叢集的請求流量:

[root@sh ~]# curl -s -H 'Content-Type: application/json' -XPUT localhost:9200/_all/_settings -d '
{
  "index.blocks.read": true,
  "index.blocks.write": true
}'           

重新開機後觀察到叢集在正常恢複:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

但是好景不長,沒一會節點又掉線了:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

于是我們緊急采集下一步行動。

二:開啟異步落盤(無效)

進一步觀察,發現叢集的master節點使用的是HDD機械盤。這個會導緻節點啟動後中繼資料同步刷盤效率非常低,會使中繼資料變更卡住較長時間。雖然偶爾能選出主,但因中繼資料變更逾時很快就失主了。于是我們進行如下變更:

[root@sh ~]# curl -s -H 'Content-Type: application/json' -XPUT localhost:9200/_cluster/settings -d '
{
    "persistent":{
        "cluster.metadata.async_write.enable":true,
        "cluster.metadata.master_async_write.enable":true
    },
    "transient":{
        "cluster.metadata.async_write.enable":true,
        "cluster.metadata.master_async_write.enable":true
    }
}'           

這個操作做過之後,可以明顯發現恢複的過程相對穩定一些,但還是會發生節點離線:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

隻好繼續下一個方案。

三、延長發現主節點的間隔時間

通過以上的現象來看,很像是社群讨論的節點被踢出後,反複join/left的問題:[#67873]1。這裡描述的問題是,在節點偶發中繼資料更新過程中,部分節點因 lagging 被踢出,而被踢出後,又因反複left/join無法加入叢集,則需要手動重新開機。lag的原因是資料節點中繼資料應用過程中,因recovery占有分片Engine讀鎖導緻長時間卡住。

于是我們再進行一下如下變更:

discovery.find_peers_interval: 5s 将這個參數在叢集各節點 config/elasticsearch.yml 進行配置,然後重新開機節點。

通過觀察,發現叢集比之前更穩定了一些,但依舊會發生離線:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

不再拖延時間,我們決定深入分析一下。

四:水落石出

抓取火焰圖進行分析,發現性能消耗在findAlias上:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

master一旦被選舉出來,就會被這個alias查找把cpu打滿,我們懷疑叢集應該是建了異常多的alias。經過确認,果然建立大量的别名:

[root@sh ~]# curl -s -XGET localhost:9200/_cat/aliases | wc -l
109661
[root@sh ~]# curl -s -XGET localhost:9200/_cat/templates | wc -l
40597           

歎為觀止,10萬多個别名,4萬多個模式,這簡直就是一個災難。由于内部索引寫入也會觸發别名查找,我們緊急設定一下叢集級别隻讀:

[root@sh ~]# curl -s -XPUT localhost:9200/_cluster/settings
{
    "persistent":{
        "cluster.blocks.read_only_allow_delete":true
    },
    "transient":{
        "cluster.blocks.read_only_allow_delete":true
    }
}           

緊接着我們緊急聯系了業務同學,了解到業務是将ID設定為索引的别名,造成了有大量别名的産生,而又不定期進行清理,最終導緻有龐大的alias量級。經過推動,業務通過腳本進行别名的删除,降低了大批别名後,叢集恢複正常:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

1.findAlias原理及問題根因

比對的過程是通過将别名字元串切分成多個區間子串進行比對,業務的别名也是比較長,一個别名切分成幾十上百個區間,上萬的别名就很多了。且master處理任務是單線程的,也可以看到是部分cpu100%。

2.後續觀察

持續觀察了一段時間,從那天業務清理過别名之後,叢集的CPU使用率就沒再居高不下:

騰雲憶想技術幹貨|記一次Elasticsearch叢集異常崩潰的離奇事件

參考資料:

[#67873]1

https://github.com/elastic/elasticsearch/issues/67873

-END-

繼續閱讀