Elasticsearch?Recovery索引分片分配詳解
基礎(chǔ)知識點(diǎn)
在Eleasticsearch中recovery指的就是一個索引的分片分配到另外一個節(jié)點(diǎn)的過程;一般在快照恢復(fù)、索引副本數(shù)變更、節(jié)點(diǎn)故障、節(jié)點(diǎn)重啟時發(fā)生。由于master保存整個集群的狀態(tài)信息,因此可以判斷出哪些shard需要做再分配,以及分配到哪個結(jié)點(diǎn),例如:
如果某個shard主分片在,副分片所在結(jié)點(diǎn)掛了,那么選擇另外一個可用結(jié)點(diǎn),將副分片分配(allocate)上去,然后進(jìn)行主從分片的復(fù)制。
如果某個shard的主分片所在結(jié)點(diǎn)掛了,副分片還在,那么將副分片升級為主分片,然后做主從分片復(fù)制。
如果某個shard的主副分片所在結(jié)點(diǎn)都掛了,則暫時無法恢復(fù),等待持有相關(guān)數(shù)據(jù)的結(jié)點(diǎn)重新加入集群后,從該結(jié)點(diǎn)上恢復(fù)主分片,再選擇另外的結(jié)點(diǎn)復(fù)制副分片。
正常情況下,我們可以通過ES的health的API接口,查看整個集群的健康狀態(tài)和整個集群數(shù)據(jù)的完整性:
狀態(tài)及含義如下:
green
: 所有的shard主副分片都是正常的;
yellow
: 所有shard的主分片都完好,部分副分片沒有或者不完整,數(shù)據(jù)完整性依然完好;
red
: 某些shard的主副分片都沒有了,對應(yīng)的索引數(shù)據(jù)不完整。
recovery過程要消耗額外的資源,CPU、內(nèi)存、結(jié)點(diǎn)之間的網(wǎng)絡(luò)帶寬等等。 這些額外的資源消耗,有可能會導(dǎo)致集群的服務(wù)性能下降,或者一部分功能暫時不可用。了解一些recovery的過程和相關(guān)的配置參數(shù),對于減小recovery帶來的資源消耗,加快集群恢復(fù)過程都是很有幫助的。
減少集群Full Restart造成的數(shù)據(jù)來回拷貝
ES集群可能會有整體重啟的情況,比如需要升級硬件、升級操作系統(tǒng)或者升級ES大版本。重啟所有結(jié)點(diǎn)可能帶來的一個問題: 某些結(jié)點(diǎn)可能先于其他結(jié)點(diǎn)加入集群, 先加入集群的結(jié)點(diǎn)可能已經(jīng)可以選舉好master,并立即啟動了recovery的過程,由于這個時候整個集群數(shù)據(jù)還不完整,master會指示一些結(jié)點(diǎn)之間相互開始復(fù)制數(shù)據(jù)。 那些晚到的結(jié)點(diǎn),一旦發(fā)現(xiàn)本地的數(shù)據(jù)已經(jīng)被復(fù)制到其他結(jié)點(diǎn),則直接刪除掉本地“失效”的數(shù)據(jù)。 當(dāng)整個集群恢復(fù)完畢后,數(shù)據(jù)分布不均衡,顯然是不均衡的,master會觸發(fā)rebalance過程,將數(shù)據(jù)在節(jié)點(diǎn)之間挪動。整個過程無謂消耗了大量的網(wǎng)絡(luò)流量;合理設(shè)置recovery相關(guān)參數(shù)則可以防范這種問題的發(fā)生。
gateway.expected_nodes gateway.expected_master_nodes gateway.expected_data_nodes
以上三個參數(shù)是說集群里一旦有多少個節(jié)點(diǎn)就立即開始recovery過程。 不同之處在于,第一個參數(shù)指的是master或者data都算在內(nèi),而后面兩個參數(shù)則分指master和data node。
在期待的節(jié)點(diǎn)數(shù)條件滿足之前, recovery過程會等待gateway.recover_after_time (默認(rèn)5分鐘) 這么長時間,一旦等待超時,則會根據(jù)以下條件判斷是否啟動:
gateway.expected_nodes gateway.expected_master_nodes gateway.expected_data_nodes
舉例來說,對于一個有10個data node的集群,如果有以下的設(shè)置:
gateway.expected_data_nodes: 10 gateway.recover_after_time: 5m gateway.recover_after_data_nodes: 8
那么集群5分鐘以內(nèi)10個data node都加入了,或者5分鐘以后8個以上的data node加入了,都會立即啟動recovery過程。
減少主副本之間的數(shù)據(jù)復(fù)制
如果不是full restart,而是重啟單個data node,仍然會造成數(shù)據(jù)在不同結(jié)點(diǎn)之間來回復(fù)制。為避免這個問題,可以在重啟之前,先關(guān)閉集群的shard allocation:
然后在節(jié)點(diǎn)重啟完成加入集群后,再重新打開:
這樣在節(jié)點(diǎn)重啟完成后,盡量多的從本地直接恢復(fù)數(shù)據(jù)。
但是在ES1.6版本之前,即使做了以上措施,仍然會發(fā)現(xiàn)有大量主副本之間的數(shù)據(jù)拷貝。從表面去看,這點(diǎn)很讓人不能理解。
主副本數(shù)據(jù)完全一致,ES應(yīng)該直接從副本本地恢復(fù)數(shù)據(jù)就好了,為什么要重新從主片再復(fù)制一遍呢? 原因在于recovery是簡單對比主副本的segment file來判斷哪些數(shù)據(jù)一致可以本地恢復(fù),哪些不一致需要遠(yuǎn)端拷貝的。
而不同節(jié)點(diǎn)的segment merge是完全獨(dú)立運(yùn)行的,可能導(dǎo)致主副本merge的深度不完全一樣,從而造成即使文檔集完全一樣,產(chǎn)生的segment file卻不完全一樣。
為了解決這個問題,ES1.6版本以后加入了synced flush的新特性。 對于5分鐘沒有更新過的shard,會自動synced flush一下,實(shí)質(zhì)是為對應(yīng)的shard加了一個synced flush ID。這樣當(dāng)重啟節(jié)點(diǎn)的時候,先對比一下shard的synced flush ID,就可以知道兩個shard是否完全相同,避免了不必要的segment file拷貝,極大加快了冷索引的恢復(fù)速度。
需要注意的是synced flush只對冷索引有效,對于熱索引(5分鐘內(nèi)有更新的索引)沒有作用。 如果重啟的結(jié)點(diǎn)包含有熱索引,那么還是免不了大量的文件拷貝
。因此在重啟一個結(jié)點(diǎn)之前,最好按照以下步驟執(zhí)行,recovery幾乎可以瞬間完成:
- 暫停數(shù)據(jù)寫入程序
- 關(guān)閉集群shard allocation
- 手動執(zhí)行POST /_flush/synced
- 重啟節(jié)點(diǎn)
- 重新開啟集群shard allocation
- 等待recovery完成,集群health status變成green
- 重新開啟數(shù)據(jù)寫入程序
特大熱索引為何恢復(fù)慢
對于冷索引,由于數(shù)據(jù)不再更新,利用synced flush特性,可以快速直接從本地恢復(fù)數(shù)據(jù)。 而對于熱索引,特別是shard很大的熱索引,;除了synced flush派不上用場需要大量跨節(jié)點(diǎn)拷貝segment file以外,translog recovery是導(dǎo)致慢的更重要的原因。
從主片恢復(fù)數(shù)據(jù)到副片需要經(jīng)歷3個階段:
- 對主片上的segment file做一個快照,然后拷貝到復(fù)制片分配到的結(jié)點(diǎn)。數(shù)據(jù)拷貝期間,不會阻塞索引請求,新增索引操作記錄到translog里。
- 對translog做一個快照,此快照包含第一階段新增的索引請求,然后重放快照里的索引操作。此階段仍然不阻塞索引請求,新增索引操作記錄到translog里。
- 為了能達(dá)到主副片完全同步,阻塞掉新索引請求,然后重放階段二新增的translog操作。
可見,在recovery完成之前,translog是不能夠被清除掉的(禁用掉正常運(yùn)作期間后臺的flush操作)。
如果shard比較大,第一階段耗時很長,會導(dǎo)致此階段產(chǎn)生的translog很大。重放translog比起簡單的文件拷貝耗時要長得多,因此第二階段的translog耗時也會顯著增加。
等到第三階段,需要重放的translog可能會比第二階段還要多。 而第三階段是會阻塞新索引寫入的,在對寫入實(shí)時性要求很高的場合,就會非常影響用戶體驗(yàn)。
因此,要加快大的熱索引恢復(fù)速度,最好的方式是遵從上一節(jié)提到的方法: 暫停新數(shù)據(jù)寫入,手動sync flush,等待數(shù)據(jù)恢復(fù)完成后,重新開啟數(shù)據(jù)寫入,這樣可以將數(shù)據(jù)延遲影響可以降到最低。
萬一遇到Recovery慢,想知道進(jìn)度怎么辦呢? CAT Recovery API可以顯示詳細(xì)的recovery各個階段的狀態(tài)。 這個API怎么用就不在這里贅述了,參考: CAT Recovery。
其他Recovery相關(guān)的專家級設(shè)置
還有其他一些專家級的設(shè)置(參見: recovery)可以影響recovery的速度,但提升速度的代價是更多的資源消耗,因此在生產(chǎn)集群上調(diào)整這些參數(shù)需要結(jié)合實(shí)際情況謹(jǐn)慎調(diào)整,一旦影響應(yīng)用要立即調(diào)整回來。
對于搜索并發(fā)量要求高,延遲要求低的場合,默認(rèn)設(shè)置一般就不要去動了。
對于日志實(shí)時分析類對于搜索延遲要求不高,但對于數(shù)據(jù)寫入延遲期望比較低的場合,可以適當(dāng)調(diào)大indices.recovery.max_bytes_per_sec,提升recovery速度,減少數(shù)據(jù)寫入被阻塞的時長。
最后要說的一點(diǎn)是ES的版本迭代很快,對于Recovery的機(jī)制也在不斷的優(yōu)化中。 其中有一些版本甚至引入了一些bug,比如在ES1.4.x有嚴(yán)重的translog recovery bug,導(dǎo)致大的索引trans log recovery幾乎無法完成 。
因此實(shí)際使用中如果遇到問題,最好在Github的issue list里搜索一下,看是否使用的版本有其他人反映同樣的問題。
以上就是Elasticsearch Recovery索引分片分配詳解的詳細(xì)內(nèi)容,更多關(guān)于Elasticsearch Recovery索引分片分配的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JDBC利用C3P0數(shù)據(jù)庫連接池連接數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了JDBC利用C3P0數(shù)據(jù)庫連接池連接數(shù)據(jù)庫,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08Spring整合Quartz實(shí)現(xiàn)動態(tài)定時器的示例代碼
本篇文章主要介紹了Spring整合Quartz實(shí)現(xiàn)動態(tài)定時器的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-01-01JavaSE經(jīng)典小練習(xí)項(xiàng)目之拷貝文件夾
文件拷貝是一個常見的任務(wù),無論是備份文件,還是將文件從一個位置復(fù)制到另一個位置,文件拷貝都是必不可少的,這篇文章主要給大家介紹了關(guān)于JavaSE經(jīng)典小練習(xí)項(xiàng)目之拷貝文件夾的相關(guān)資料,需要的朋友可以參考下2023-10-10java中LinkedList使用迭代器優(yōu)化移除批量元素原理
本文主要介紹了java中LinkedList使用迭代器優(yōu)化移除批量元素原理,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10java數(shù)組與以逗號分隔開的字符串的相互轉(zhuǎn)換操作
這篇文章主要介紹了java數(shù)組與以逗號分隔開的字符串的相互轉(zhuǎn)換操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09