Elasticsearch索引的分片分配Recovery使用講解
什么是recovery?
在elasticsearch中,recovery指的是一個(gè)索引的分片分配到另外一個(gè)節(jié)點(diǎn)的過(guò)程,一般在快照恢復(fù)、索引復(fù)制分片的變更、節(jié)點(diǎn)故障或重啟時(shí)發(fā)生,由于master節(jié)點(diǎn)保存整個(gè)集群相關(guān)的狀態(tài)信息,因此可以判斷哪些分片需要再分配及分配到哪個(gè)節(jié)點(diǎn),例如:
- 如果某個(gè)主分片在,而復(fù)制分片所在的節(jié)點(diǎn)掛掉了,那么master需要另行選擇一個(gè)可用節(jié)點(diǎn),將這個(gè)主分片的復(fù)制分片分配到可用節(jié)點(diǎn)上,然后進(jìn)行主從分片的數(shù)據(jù)復(fù)制。
如果某個(gè)主分片所在的節(jié)點(diǎn)掛掉了,復(fù)制分片還在,那么master會(huì)主導(dǎo)將復(fù)制分片升級(jí)為主分片,然后再做主從分片數(shù)據(jù)復(fù)制。 - 如果某個(gè)分片的主副分片都掛掉了,則暫時(shí)無(wú)法恢復(fù),而是要等持有相關(guān)數(shù)據(jù)的節(jié)點(diǎn)重新加入集群后,master才能主持?jǐn)?shù)據(jù)恢復(fù)相關(guān)操作。
但是,recovery過(guò)程要消耗額外的資源,CPU、內(nèi)存、節(jié)點(diǎn)間的網(wǎng)絡(luò)帶寬等??赡軐?dǎo)致集群的服務(wù)性能下降,甚至部分功能暫時(shí)無(wú)法使用,所以,有必要了解在recovery的過(guò)程和其相關(guān)的配置,來(lái)減少不必要的消耗和問(wèn)題。
減少集群full restart造成的數(shù)據(jù)來(lái)回拷貝
有時(shí)候,可能會(huì)遇到es集群整體重啟的情況,比如硬件升級(jí)、不可抗力的意外等,那么再次重啟集群會(huì)帶來(lái)一個(gè)問(wèn)題:某些節(jié)點(diǎn)優(yōu)先起來(lái),并優(yōu)先選舉出了主節(jié)點(diǎn),有了主節(jié)點(diǎn),該主節(jié)點(diǎn)會(huì)立刻主持recovery的過(guò)程。
但此時(shí),這個(gè)集群數(shù)據(jù)還不完整(還有其他的節(jié)點(diǎn)沒有起來(lái)),例如A節(jié)點(diǎn)的主分片對(duì)應(yīng)的復(fù)制分片所在的B節(jié)點(diǎn)還沒起來(lái),但主節(jié)點(diǎn)會(huì)將A節(jié)點(diǎn)的幾個(gè)沒有復(fù)制分片的主分片重新拷貝到可用的C節(jié)點(diǎn)上。而當(dāng)B節(jié)點(diǎn)成功起來(lái)了,自檢時(shí)發(fā)現(xiàn)在自己節(jié)點(diǎn)存儲(chǔ)的A節(jié)點(diǎn)主分片對(duì)應(yīng)的復(fù)制分片已經(jīng)在C節(jié)點(diǎn)上出現(xiàn)了,就會(huì)直接刪除自己節(jié)點(diǎn)中“失效”的數(shù)據(jù)(A節(jié)點(diǎn)的那幾個(gè)復(fù)制分片),這種情況很可能頻繁出現(xiàn)在有多個(gè)節(jié)點(diǎn)的集群中。
而當(dāng)整個(gè)集群恢復(fù)后,其各個(gè)節(jié)點(diǎn)的數(shù)據(jù)分布,顯然是不均衡的(先啟動(dòng)的節(jié)點(diǎn)把數(shù)據(jù)恢復(fù)了,后起來(lái)的節(jié)點(diǎn)內(nèi)刪除了無(wú)效的數(shù)據(jù)),這時(shí),master就會(huì)觸發(fā)Rebalance的過(guò)程,將數(shù)據(jù)在各個(gè)節(jié)點(diǎn)之間挪動(dòng),這個(gè)過(guò)程又消耗了大量的網(wǎng)絡(luò)流量。所以,我們需要合理的設(shè)置recovery相關(guān)參數(shù)來(lái)優(yōu)化recovery過(guò)程。
- 在集群?jiǎn)?dòng)過(guò)程中,一旦有了多少個(gè)節(jié)點(diǎn)成功啟動(dòng),就執(zhí)行recovery過(guò)程,這個(gè)命令將master節(jié)點(diǎn)(有master資格的節(jié)點(diǎn))和data節(jié)點(diǎn)都算在內(nèi)。
gateway.expected_nodes: 3
- 有幾個(gè)master節(jié)點(diǎn)啟動(dòng)成功,就執(zhí)行recovery的過(guò)程。
gateway.expected_master_nodes: 3
- 有幾個(gè)data節(jié)點(diǎn)啟動(dòng)成功,就執(zhí)行recovery的過(guò)程。
gateway.expected_data_nodes: 3
當(dāng)集群在期待的節(jié)點(diǎn)數(shù)條件滿足之前,recovery過(guò)程會(huì)等待gateway.recover_after_time指定的時(shí)間,一旦等待超時(shí),則會(huì)根據(jù)以下條件判斷是否執(zhí)行recovery的過(guò)程:
gateway.recover_after_nodes: 3 # 3個(gè)節(jié)點(diǎn)(master和data節(jié)點(diǎn)都算)啟動(dòng)成功 gateway.recover_after_master_nodes: 3 # 3個(gè)有master資格的節(jié)點(diǎn)啟動(dòng)成功 gateway.recover_after_data_nodes: 3 # 3個(gè)有data資格的節(jié)點(diǎn)啟動(dòng)成功
上面三個(gè)配置滿足一個(gè)就會(huì)執(zhí)行recovery的過(guò)程。
如果有以下配置的集群:
gateway.expected_data_nodes: 10 gateway.recover_after_time: 5m gateway.recover_after_data_nodes: 8
此時(shí)的集群在5分鐘內(nèi),有10個(gè)data節(jié)點(diǎn)都加入集群,或者5分鐘后有8個(gè)以上的data節(jié)點(diǎn)加入集群,都會(huì)啟動(dòng)recovery的過(guò)程。
減少主副本之間的數(shù)據(jù)復(fù)制
如果不是full restart,而是重啟單個(gè)節(jié)點(diǎn),也會(huì)造成不同節(jié)點(diǎn)之間來(lái)復(fù)制,為了避免這個(gè)問(wèn)題,可以在重啟之前,關(guān)閉集群的shard allocation。
PUT _cluster/settings { "transient": { "cluster.routing.allocation.enable":"none" } }
當(dāng)節(jié)點(diǎn)重啟后,再重新打開:
PUT _cluster/settings { "transient": { "cluster.routing.allocation.enable":"all" } }
這樣,節(jié)點(diǎn)重啟后,盡可能的從本節(jié)點(diǎn)直接恢復(fù)數(shù)據(jù)。但是在es1.6版本之前,既使做了以上措施,仍然會(huì)出現(xiàn)大量主副分片之間的數(shù)據(jù)拷貝,從面上看,這點(diǎn)讓人很不理解,主副分片數(shù)據(jù)是完全一致的,在節(jié)點(diǎn)重啟后,直接從本節(jié)點(diǎn)的副本重恢復(fù)數(shù)據(jù)就好了呀,為什么還要再?gòu)闹鞣制購(gòu)?fù)制一遍呢?原因是在于recovery是簡(jiǎn)單的對(duì)比主副分片的segment file(分段文件)來(lái)判斷哪些數(shù)據(jù)一致是可以本地恢復(fù),哪些不一致的需要重新拷貝的。而不同節(jié)點(diǎn)的segment file是完全獨(dú)立運(yùn)行的,這可能導(dǎo)致主副本merge的深度不完全一致,從而造成即使文檔集完全一樣,而產(chǎn)生的segment file卻不完全一樣。
為了解決這個(gè)問(wèn)題,在es1.6版本之后,加入了synced flush(同步刷新)新特性,對(duì)于5分鐘沒有更新過(guò)的shard,會(huì)自動(dòng)synced flush一下,其實(shí)就是為對(duì)應(yīng)的shard加入一個(gè)synced flush id,這樣在節(jié)點(diǎn)重啟后,先對(duì)比主副shard的synced flush id,就可以知道兩個(gè)shard是否完全相同,避免了不必要的segment file拷貝。
需要注意的是synced flush只對(duì)冷索引有效,對(duì)于熱索引(5分鐘內(nèi)有更新的索引)無(wú)效,如果重啟的節(jié)點(diǎn)包含有熱索引,那還是免不了大量的拷貝。如果要重啟一個(gè)包含大量熱索引的節(jié)點(diǎn),可以按照以下步驟執(zhí)行重啟過(guò)程,可以讓recovery過(guò)程瞬間完成:
- 暫停數(shù)據(jù)寫入
- 關(guān)閉集群的shard allocation
- 手動(dòng)執(zhí)行 POST /_flush/synced
- 重啟節(jié)點(diǎn)
- 重新開啟集群的shard allocation
- 等待recovery完成,當(dāng)集群的health status是green后
- 重新開啟數(shù)據(jù)寫入
特大熱索引為何恢復(fù)慢
對(duì)于冷索引,由于數(shù)據(jù)不再更新(對(duì)于elasticsearch來(lái)說(shuō),5分鐘,很久了),利用synced flush可以快速的從本地恢復(fù)數(shù)據(jù),而對(duì)于熱索引,特別是shard很大的熱索引,除了synced flush派不上用場(chǎng),從而需要大量跨節(jié)點(diǎn)拷貝segment file以外,translog recovery可能是導(dǎo)致慢的更重要的原因。
我們來(lái)研究下這個(gè)translog recovery是什么鬼!
當(dāng)節(jié)點(diǎn)重啟后,從主分片恢復(fù)數(shù)據(jù)到復(fù)制分片需要經(jīng)歷3個(gè)階段:
- 第一階段,對(duì)于主分片上的segment file做一個(gè)快照,然后拷貝到復(fù)制分片所在的節(jié)點(diǎn),在數(shù)據(jù)拷貝期間,不會(huì)阻塞索引請(qǐng)求,新增的索引操作會(huì)記錄到translog中(理解為于臨時(shí)文件)。
- 第二階段,對(duì)于translog做一個(gè)快照,此快照包含第一階段新增的索引請(qǐng)求,然后重放快照里的索引操作,這個(gè)階段仍然不會(huì)阻塞索引請(qǐng)求,新增索引操作記錄到translog中。
- 第三階段,為了能達(dá)到主副分片完全同步,阻塞新索引請(qǐng)求,然后重放上一階段新增的translog操作。
由此可見,在recovery過(guò)程完成之前,translog是不能被清除掉的。如果shard比較大,第一階段會(huì)耗時(shí)很長(zhǎng),會(huì)導(dǎo)致此階段產(chǎn)生的translog很大,重放translog要比簡(jiǎn)單的文件拷貝耗時(shí)更長(zhǎng),因此第二階段的translog耗時(shí)也顯著的增加了。等到了第三階段,需要重放的translog可能會(huì)比第二階段更多。要命的是,第三階段是會(huì)阻塞新索引(寫入)請(qǐng)求的,在對(duì)寫入實(shí)時(shí)性要求很高的場(chǎng)合,這就會(huì)導(dǎo)致性能下降,非常影響用戶體驗(yàn)。因此,要加快特大熱索引恢復(fù)速度,最好是參照上一節(jié)中的方式:
- 暫停數(shù)據(jù)寫入。
- 手動(dòng)synced flush。
- 等待數(shù)據(jù)恢復(fù)完成后。
- 重新恢復(fù)數(shù)據(jù)寫入。
這樣就會(huì)把數(shù)據(jù)延遲影響降到最低。
歡迎斧正,that's all see also:[本文主要參考:Elasticsearch Recovery詳解]
(https://blog.csdn.net/u012450329/article/details/52881045) | [cat recovery]
(https://www.elastic.co/guide/en/elasticsearch/reference/current/recovery.html)
以上就是Elasticsearch索引的分片分配Recovery使用講解的詳細(xì)內(nèi)容,更多關(guān)于Elasticsearch索引的分片分配Recovery 的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
做一個(gè)優(yōu)秀程序員應(yīng)該知道的15件事
這篇文章主要介紹了做一個(gè)優(yōu)秀程序員應(yīng)該知道的15件事,寫的很好,需要的朋友可以參考下2014-07-07詳解VScode自動(dòng)補(bǔ)全CSS3前綴插件以及配置無(wú)效的解決辦法
這篇文章主要介紹了詳解VScode自動(dòng)補(bǔ)全CSS3前綴插件以及配置無(wú)效的解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06用asp與php實(shí)現(xiàn)百度ping服務(wù)的代碼
分別用asp與php實(shí)現(xiàn)百度ping服務(wù)的代碼,需要的朋友可以參考下2012-02-02Scala項(xiàng)目構(gòu)建工具sbt和IntelliJ IDEA環(huán)境配置詳解
這篇文章主要介紹了Scala項(xiàng)目構(gòu)建工具sbt和IntelliJ IDEA環(huán)境配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10基于Token的身份驗(yàn)證之JWT基礎(chǔ)教程
JWT(json web token)是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)。下面這篇文章主要給大家介紹了關(guān)于基于Token的身份驗(yàn)證之JWT的基礎(chǔ)相關(guān)資料,文中通過(guò)示例代碼的非常詳細(xì),需要的朋友可以參考下2018-09-09百度HI QQ和MSN 阿里旺旺貿(mào)易通MSN在線客服在線聊天代碼
有時(shí)候業(yè)務(wù)需要,需要讓客戶更方便的與我們溝通,就可以參考下面的代碼。2010-04-04vscode調(diào)用HTML文件的實(shí)現(xiàn)步驟
利用Vscode軟件編寫html的時(shí)候,一般都想右鍵選擇html文件,本文主要介紹了vscode調(diào)用HTML文件的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12