一、refresh
對于任何數(shù)據(jù)庫的寫入來講fsync刷盤雖然保證的數(shù)據(jù)的安全但是如果每次操作都必須fsync一次,那fsync操作將是一個(gè)巨大的操作代價(jià),在衡量對數(shù)據(jù)安全與操作代價(jià)下,ES引入了一個(gè)較輕量的操作refresh操作來避免頻繁的fsync操作。
1.1 什么是refresh
在ES中,當(dāng)寫入一個(gè)新文檔時(shí),首先被寫入到內(nèi)存緩存中,默認(rèn)每1秒將in-memory index buffer中的文檔生成一個(gè)新的段并清空原有in-memory index buffer,新寫入的段變?yōu)榭勺x狀態(tài),但是還沒有被完全提交。該新的段首先被寫入文件系統(tǒng)緩存,保證段文件可以正常被正常打開和讀取,后續(xù)再進(jìn)行刷盤操作。由此可以看到,ES并不是寫入文檔后馬上就可以搜索到,而是一個(gè)近實(shí)時(shí)的搜索(默認(rèn)1s后)。
如圖,文檔被寫入一個(gè)新的段后處于searchable狀態(tài),但是仍是未提交狀態(tài)
文檔寫入內(nèi)存緩存區(qū)中,默認(rèn)每1s生成一個(gè)新的段,這個(gè)寫入并打開一個(gè)新段的輕量的過程叫做 refresh。
雖然refresh是一個(gè)較輕量的操作,但也是有一定的資源消耗的,必要時(shí)刻可以手動執(zhí)行refresh api保證文檔可立即被讀到。生產(chǎn)環(huán)境建議正確使用refresh api,接受ES本身1s后可讀的近實(shí)時(shí)特性。
1.2 refresh api的使用
-- refresh全局索引
POST /_refresh?
-- refresh指定索引
POST /blogs/_refresh?
1.3 refresh相關(guān)參數(shù)設(shè)置
refresh_interval 控制索引refresh頻率
默認(rèn)為1s,可根據(jù)實(shí)際業(yè)務(wù)場景設(shè)置為n u m {num}num{時(shí)間單位},表示索引每${num}s進(jìn)行一次refresh;若設(shè)置為-1表示關(guān)閉refresh。
refresh_interval參數(shù)設(shè)置時(shí)是填寫具體的一個(gè)持續(xù)時(shí)間值,若該參數(shù)設(shè)置為1則表示每1毫秒進(jìn)行一次refresh,若設(shè)置不當(dāng)會導(dǎo)致整個(gè)ES集群處于癱瘓狀態(tài)
PUT /my_logs
{
? "settings": {
? ? "refresh_interval": "30s" ? ? ? ? ? //設(shè)置每30s進(jìn)行一次refresh
? }
}
合理設(shè)置refresh_interval參數(shù),在生產(chǎn)環(huán)境中,若我們需要?jiǎng)?chuàng)建一個(gè)大索引,可設(shè)置該參數(shù)為-1,開始使用時(shí)再開啟參數(shù),減少創(chuàng)建索引時(shí)refresh的消耗
1.4 refresh特點(diǎn)
不完整提交(因?yàn)闆]有刷盤)
refresh資源消耗相對較小,避免每次文檔寫入fsync導(dǎo)致資源上的瓶頸
默認(rèn)每1s進(jìn)行一次refresh,refresh后的段可以被打開,實(shí)現(xiàn)近實(shí)時(shí)搜索
二、flush
即使通過每秒refresh實(shí)現(xiàn)了近實(shí)時(shí)搜索,但refresh無法保障數(shù)據(jù)安全,我們?nèi)匀恍枰?jīng)常進(jìn)行完整提交來確保能從失敗中恢復(fù)。flush就是一次完全提交的過程,一次完整的提交會將段刷到磁盤,并寫入一個(gè)包含所有段列表的提交點(diǎn)。Elasticsearch 在啟動或重新打開一個(gè)索引的過程中使用這個(gè)提交點(diǎn)來判斷哪些段隸屬于當(dāng)前分片,保證數(shù)據(jù)的安全。
為此ES增加了一個(gè) translog ,或者叫事務(wù)日志,在每一次對 ES的變更操作除寫入內(nèi)存緩存外還會寫入到translog中,translog周期性刷盤,保證變更的持久性。
2.1 什么是translog
translog就是ES的一個(gè)事務(wù)日志,當(dāng)發(fā)生一個(gè)文檔變更操作時(shí),文檔不僅會寫入到內(nèi)存緩存區(qū)也會同樣記錄到事務(wù)日志中,事務(wù)日志保證還沒有被刷到磁盤的操作的進(jìn)行持久化。translog持久化后保證即使意外斷電或者ES程序重啟,ES首先通過磁盤中最后一次提交點(diǎn)恢復(fù)已經(jīng)落盤的段,然后將該提交點(diǎn)之后的變更操作通過translog進(jìn)行重放,重構(gòu)內(nèi)存中的segment。
translog也可以被用來實(shí)時(shí)CRUD搜索,當(dāng)我們通過_id進(jìn)行查詢/更新/刪除文檔時(shí),ES在檢索該文檔對應(yīng)的segment時(shí)會優(yōu)先檢查translog中最近一次的變更操作,以便獲取到最新版本的文檔記錄。
2.2 translog基本流程
一個(gè)文檔被索引之后,就會被添加到內(nèi)存緩沖區(qū),并且追加到了translog
默認(rèn)每秒refresh一次,refresh會清空內(nèi)存緩存,但是不會清空translog
refresh操作不斷發(fā)生,更多的文檔被添加到內(nèi)存緩沖區(qū)和追加到translog
translog周期性通過fsync進(jìn)行刷盤,默認(rèn)5s,可通過參數(shù)index.translog.sync_interval、index.translog.durability控制,保證應(yīng)用重啟后先確認(rèn)最后記錄的commit point,commit point之后的變更操作通過落盤的translog進(jìn)行重構(gòu)恢復(fù)段
默認(rèn)當(dāng)translog太大(512MB)時(shí),進(jìn)行flush操作
2.3 什么是flush
將translog中所有的段進(jìn)行全量提交并對translog進(jìn)行截?cái)嗟牟僮鹘凶鰂lush,flush操作期間會做的事項(xiàng)主要有:
強(qiáng)制refresh,將內(nèi)存緩沖區(qū)所有文檔寫入一個(gè)新的段,寫入到文件系統(tǒng)緩存并將舊的內(nèi)存緩沖區(qū)被清空(refresh)
將最新的commit point寫入磁盤
將文件系統(tǒng)緩存中的段通過fsync進(jìn)行刷盤
刪除老的translog,啟動新translog
2.4 flush api的使用
一般來講自動刷新就足夠了,很少需要自己手動執(zhí)行 flush 操作。
POST /blogs/_flush?
POST /_flush?wait_for_ongoing?
2.5 flush 相關(guān)參數(shù)設(shè)置
index.translog.sync_interval
? ? translog通過fsync刷盤的的頻率,默認(rèn)5s,不允許設(shè)置100ms以內(nèi)
? ??
index.translog.durability
? ? request(default):默認(rèn)每次請求(index, delete, update, or bulk request)后都進(jìn)行fsync和commit
? ? async:每間隔sync_interval進(jìn)行一次fsync和commit
index.translog.flush_threshold_size
? ? translog最大達(dá)到512MB的時(shí)候強(qiáng)制進(jìn)行flush操作,flush后將commit point進(jìn)行刷盤,保證數(shù)據(jù)安全
2.6 flush的特點(diǎn)
refresh會清空內(nèi)存緩存,但是不會清空translog
flush操作將文件系統(tǒng)緩存中的segment進(jìn)行fsync刷盤,并更新commit point
當(dāng)程序意外重啟后,es首先找到commit point,然后通過translog重構(gòu)commit point之后的segment
三、merge
每次refresh操作都會生成一個(gè)新的segment,隨著時(shí)間的增長segmengt會越來越多,這就出現(xiàn)一個(gè)比較嚴(yán)重的問題是每次search操作必須依次掃描所有的segment,導(dǎo)致查詢效率變慢,為了避免該問題es會定期多這個(gè)segment進(jìn)行合并操作。
3.1 什么是merge
將refresh產(chǎn)生的多個(gè)小segment整合為一個(gè)大的segment的操作就叫做merge。同時(shí)merge操作會將已經(jīng)打.del標(biāo)簽的文檔從文件系統(tǒng)進(jìn)行物理刪除。merge屬于一個(gè)后臺操作。
在es中每個(gè)delete操作其實(shí)都是對將要?jiǎng)h除的文檔打一個(gè).del的標(biāo)簽,同理update操作就是將原文檔進(jìn)行.del打標(biāo)然后插入新文檔,只有merge操作才會將這些已經(jīng)打標(biāo)的.del文件真正進(jìn)行物理刪除。
一個(gè)大segment的merge操作是很消耗CPU、IO資源的,如果使用不當(dāng)會影響到本身的serach查詢性能。es默認(rèn)會控制merge進(jìn)程的資源占用以保證merge期間search具有足夠資源。
3.2 merge操作相關(guān)流程
refresh操作會相應(yīng)的產(chǎn)生很多小的segment文件,并刷入到文件系統(tǒng)緩存(此時(shí)文件系統(tǒng)中既有已經(jīng)完全commit的segment也有不完全提交僅searchable的segment)
es可以對這些零散的小segment文件進(jìn)行合并(包含完全提交以及searchalbe的segment)
es會對merge操作后的segment進(jìn)行一次flush操作,更新磁盤cpmmit point
將merge之后的segment打開保證searchalbe,然后刪除merge之前的零散的小segment
3.3 相關(guān)參數(shù)API
optimize API通過對max_num_segments參數(shù)對merge操作進(jìn)行控制,默認(rèn)該參數(shù)為1,控制每次merge僅對1個(gè)segment進(jìn)行合并,保證原有的search操作資源充足。
POST /logstash-2014-10/_optimize?max_num_segments=1?
max_bytes_per_sec為限制每次merge操作的帶寬限制,默認(rèn)20MB每秒。若生產(chǎn)環(huán)境使用SSD或者es日志中發(fā)現(xiàn)“now
throttling indexing”相關(guān)INFO等級等信息,可適當(dāng)調(diào)大該參數(shù)。
?indices.store.throttle.max_bytes_per_sec文章來源:http://www.zghlxwxcb.cn/news/detail-715344.html
3.4 merge的特點(diǎn)
對文件系統(tǒng)中零散的小segment進(jìn)行合并,合并為一個(gè)大的segment,減少search期間依次掃描多個(gè)segment帶來的資源消耗
merge操作會消耗CPU、IO資源,ES對于merge操作相對比較保守,會控制每次merge操作的帶寬限制
merge操作不適用于頻繁更新的動態(tài)索引,相反他更適合只有index的日志型索引,定期將歷史索引segment進(jìn)行合并,加快search效率
參考文檔:
https://www.elastic.co/guide/en/elasticsearch/guide/current/dynamic-indices.html
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/index-modules-translog.html
————————————————
版權(quán)聲明:本文為CSDN博主「三思吶三思」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_37692493/article/details/108182161文章來源地址http://www.zghlxwxcb.cn/news/detail-715344.html
到了這里,關(guān)于理解ES的refresh、flush、merge的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!