整體流程:
- 數(shù)據(jù)寫入buffer緩沖和translog日志文件中。
當(dāng)你寫一條數(shù)據(jù)document的時候魂挂,一方面寫入到mem buffer緩沖中,一方面同時寫入到translog日志文件中。 - buffer滿了或者每隔1秒(可配)旷赖,refresh將mem buffer中的數(shù)據(jù)生成index segment文件并寫入os cache辅髓,此時index segment可被打開以供search查詢讀取泣崩,這樣文檔就可以被搜索到了(注意,此時文檔還沒有寫到磁盤上)洛口;然后清空mem buffer供后續(xù)使用矫付。可見第焰,refresh實現(xiàn)的是文檔從內(nèi)存移到文件系統(tǒng)緩存的過程买优。
- 重復(fù)上兩個步驟,新的segment不斷添加到os cache挺举,mem buffer不斷被清空杀赢,而translog的數(shù)據(jù)不斷增加,隨著時間的推移湘纵,translog文件會越來越大脂崔。
- 當(dāng)translog長度達到一定程度的時候,會觸發(fā)flush操作梧喷,否則默認每隔30分鐘也會定時flush砌左,其主要過程:
4.1. 執(zhí)行refresh操作將mem buffer中的數(shù)據(jù)寫入到新的segment并寫入os cache,然后打開本segment以供search使用铺敌,最后再次清空mem buffer汇歹。
4.2. 一個commit point被寫入磁盤,這個commit point中標(biāo)明所有的index segment适刀。
4.3. filesystem cache(os cache)中緩存的所有的index segment文件被fsync強制刷到磁盤os disk秤朗,當(dāng)index segment被fsync強制刷到磁盤上以后,就會被打開笔喉,供查詢使用取视。
4.4. translog被清空和刪除硝皂,創(chuàng)建一個新的translog。
refresh
最原始的ES版本里作谭,必須等待fsync將segment刷入磁盤稽物,才能將segment打開供search使用,這樣的話折欠,從一個document寫入到它可以被搜索贝或,可能會超過一分鐘,主要瓶頸是在fsync實際發(fā)生磁盤IO寫數(shù)據(jù)進磁盤锐秦,是很耗時的咪奖,這就不是近實時的搜索了。為此酱床,引入refresh操作的目的是提高ES的實時性羊赵,使添加文檔盡可能快的被搜索到,同時又避免頻繁fsync帶來性能開銷扇谣,依靠的原理就是文件系統(tǒng)緩存OS cache里緩存的文件可以被打開(open/reopen)和讀取昧捷,而這個os cache實際是一塊內(nèi)存區(qū)域,而非磁盤罐寨,所以操作是很快的靡挥。
寫入流程改進:
1)數(shù)據(jù)寫入到內(nèi)存buffer隊列中
2)每隔一定時間,buffer中的數(shù)據(jù)被寫入segment文件鸯绿,然后先寫入os cache
3)只要segment數(shù)據(jù)寫入os cache跋破,那就直接打開segment供search使用,而不必調(diào)用fsync將segment刷新到磁盤
將緩存數(shù)據(jù)生成segment后刷入os cache楞慈,并被打開供搜索的過程就叫做refresh幔烛,默認每隔1秒。也就是說囊蓝,每隔1秒就會將buffer中的數(shù)據(jù)寫入一個新的index segment file饿悬,先寫入os cache中。所以聚霜,es是近實時的狡恬,輸入寫入到os cache中可以被搜索,默認是1秒蝎宇,所以從數(shù)據(jù)插入到被搜索到弟劲,最長是1秒(可配)。
flush操作與translog
但是姥芥,需要注意兔乞, index segment刷入到os cache后就可以打開供查詢,這個操作是有潛在風(fēng)險的,因為os cache中的數(shù)據(jù)有可能在意外的故障中丟失庸追,而此時數(shù)據(jù)必備并未刷入到os disk霍骄,此時數(shù)據(jù)丟失將是不可逆的,這個時候就需要一種機制淡溯,可以將對es的操作記錄下來读整,來確保當(dāng)出現(xiàn)故障的時候,已經(jīng)落地到磁盤的數(shù)據(jù)不會丟失咱娶,并在重啟的時候可以從操作記錄中將數(shù)據(jù)恢復(fù)過來米间。elasticsearch提供了translog來記錄這些操作,結(jié)合os cached segments數(shù)據(jù)定時落盤來實現(xiàn)數(shù)據(jù)可靠性保證(flush)膘侮。
當(dāng)向elasticsearch發(fā)送創(chuàng)建document文檔添加請求的時候屈糊,document數(shù)據(jù)會先進入到buffer,與此同時會將操作記錄在translog之中喻喳,當(dāng)發(fā)生refresh時(數(shù)據(jù)從index buffer中進入filesystem cache的過程)translog中的操作記錄并不會被清除另玖,而當(dāng)數(shù)據(jù)從os cache中被寫入磁盤之后才會將translog中清空。這個將os cache的索引文件(segment file)持久化到磁盤的過程就是flush表伦,flush之后,這段translog的使命就完成了慷丽,因為segment已經(jīng)寫入磁盤蹦哼,就算故障也可以從磁盤的segment文件中恢復(fù)。flush的時機可能是1.定時flush要糊;2.translog大小達到閾值纲熏;3.一些重要操作;4.指令觸發(fā)。
translog記錄的是已經(jīng)在內(nèi)存生成(segments)并存儲到os cache但是還沒寫到磁盤的那些索引操作(注意锄俄,有一種解釋說局劲,添加到buffer中但是沒有被存入segment中的數(shù)據(jù)沒有被記錄到translog中,這依賴于寫translog的時機奶赠,不同版本可能有變化鱼填,不影響理解),此時這些新寫入的數(shù)據(jù)可以被搜索到毅戈,但是當(dāng)節(jié)點掛掉后這些未來得及落入磁盤的數(shù)據(jù)就會丟失苹丸,可以通過trangslog恢復(fù)。
當(dāng)然translog本身也是磁盤文件苇经,頻繁的寫入磁盤會帶來巨大的IO開銷赘理,因此對translog的追加寫入操作的同樣操作的是os cache,因此也需要定時落盤(fsync)扇单。translog落盤的時間間隔直接決定了ES的可靠性商模,因為宕機可能導(dǎo)致這個時間間隔內(nèi)所有的ES操作既沒有生成segment磁盤文件,又沒有記錄到Translog磁盤文件中,導(dǎo)致這期間的所有操作都丟失且無法恢復(fù)施流。
translog的fsync是ES在后臺自動執(zhí)行的凉倚,默認是每5秒鐘主動進行一次translog fsync,或者當(dāng)translog文件大小大于512MB主動進行一次fsync嫂沉,對應(yīng)的配置是index.translog.flush_threshold_period 和 index.translog.flush_threshold_size稽寒。還需指出的是, 從ES2.0開始趟章,每次index杏糙、bulk、delete蚓土、update完成的時候也會觸發(fā)translog flush宏侍,當(dāng)flush到磁盤成功后才給請求端返回 200 OK。這個改變提高了數(shù)據(jù)安全性蜀漆,但是會對寫入的性能造成不小的影響谅河,因此在可靠性要求不十分嚴(yán)格且寫入效率優(yōu)先的情況下,可以在 index template 里設(shè)置如下參數(shù):"index.translog.durability":"async"确丢,這相當(dāng)于關(guān)閉了index绷耍、bulk等操作的同步flush translog操作,僅使用默認的定時刷新鲜侥、文件大小閾值刷新的機制褂始,同時可以調(diào)高 "index.translog.sync_interval":30s (默認是5s)和index.translog.flush_threshold_size配置選項。
總結(jié)一下translog的功能:
- 保證在filesystem cache中的數(shù)據(jù)不會因為elasticsearch重啟或是發(fā)生意外故障的時候丟失描函。
- 當(dāng)系統(tǒng)重啟時會從translog中恢復(fù)之前記錄的操作崎苗。
- 當(dāng)對elasticsearch進行CRUD操作的時候,會先到translog之中進行查找舀寓,因為tranlog之中保存的是最新的數(shù)據(jù)胆数。
- translog的清除時間時進行flush操作之后(將數(shù)據(jù)從filesystem cache刷入disk之中)。
總結(jié)一下flush操作的時間點:
- es的各個shard會每個30分鐘進行一次flush操作互墓。
- 當(dāng)translog的數(shù)據(jù)達到某個上限的時候會進行一次flush操作必尼。
有關(guān)于translog和flush的一些配置項:
- index.translog.flush_threshold_ops:當(dāng)發(fā)生多少次操作時進行一次flush。默認是 unlimited轰豆。
- index.translog.flush_threshold_size:當(dāng)translog的大小達到此值時會進行一次flush操作胰伍。默認是512mb。
- index.translog.flush_threshold_period:在指定的時間間隔內(nèi)如果沒有進行flush操作酸休,會進行一次強制flush操作骂租。默認是30m。
- index.translog.interval:多少時間間隔內(nèi)會檢查一次translog斑司,來進行一次flush操作渗饮。es會隨機的在這個值到這個值的2倍大小之間進行一次操作但汞,默認是5s。