1. 程式人生 > 其它 >ES elasticsearch refresh和flush的區別

ES elasticsearch refresh和flush的區別

整體流程:
  1. 資料寫入buffer緩衝和translog日誌檔案中。
    當你寫一條資料document的時候,一方面寫入到mem buffer緩衝中,一方面同時寫入到translog日誌檔案中。
  2. buffer滿了或者每隔1秒(可配),refresh將mem buffer中的資料生成index segment檔案並寫入os cache,此時index segment可被開啟以供search查詢讀取,這樣文件就可以被搜尋到了(注意,此時文件還沒有寫到磁碟上);然後清空mem buffer供後續使用。可見,refresh實現的是文件從記憶體移到檔案系統快取的過程。
  3. 重複上兩個步驟,新的segment不斷新增到os cache,mem buffer不斷被清空,而translog的資料不斷增加,隨著時間的推移,translog檔案會越來越大。
  4. 當translog長度達到一定程度的時候,會觸發flush操作,否則預設每隔30分鐘也會定時flush,其主要過程:
    4.1. 執行refresh操作將mem buffer中的資料寫入到新的segment並寫入os cache,然後開啟本segment以供search使用,最後再次清空mem buffer。
    4.2. 一個commit point被寫入磁碟,這個commit point中標明所有的index segment。
    4.3. filesystem cache(os cache)中快取的所有的index segment檔案被fsync強制刷到磁碟os disk,當index segment被fsync強制刷到磁碟上以後,就會被開啟,供查詢使用。
    4.4. translog被清空和刪除,建立一個新的translog。
refresh

最原始的ES版本里,必須等待fsync將segment刷入磁碟,才能將segment開啟供search使用,這樣的話,從一個document寫入到它可以被搜尋,可能會超過一分鐘,主要瓶頸是在fsync實際發生磁碟IO寫資料進磁碟,是很耗時的,這就不是近實時的搜尋了。為此,引入refresh操作的目的是提高ES的實時性,使新增文件儘可能快的被搜尋到,同時又避免頻繁fsync帶來效能開銷,依靠的原理就是檔案系統快取OS cache裡快取的檔案可以被開啟(open/reopen)和讀取,而這個os cache實際是一塊記憶體區域,而非磁碟,所以操作是很快的。

寫入流程改進:
1)資料寫入到記憶體buffer佇列中
2)每隔一定時間,buffer中的資料被寫入segment檔案,然後先寫入os cache
3)只要segment資料寫入os cache,那就直接開啟segment供search使用,而不必呼叫fsync將segment重新整理到磁碟

將快取資料生成segment後刷入os cache,並被開啟供搜尋的過程就叫做refresh,預設每隔1秒。也就是說,每隔1秒就會將buffer中的資料寫入一個新的index segment file,先寫入os cache中。所以,es是近實時的,輸入寫入到os cache中可以被搜尋,預設是1秒,所以從資料插入到被搜尋到,最長是1秒(可配)。

flush操作與translog

但是,需要注意, index segment刷入到os cache後就可以開啟供查詢,這個操作是有潛在風險的,因為os cache中的資料有可能在意外的故障中丟失,而此時資料必備並未刷入到os disk,此時資料丟失將是不可逆的,這個時候就需要一種機制,可以將對es的操作記錄下來,來確保當出現故障的時候,已經落地到磁碟的資料不會丟失,並在重啟的時候可以從操作記錄中將資料恢復過來。elasticsearch提供了translog來記錄這些操作,結合os cached segments資料定時落盤來實現資料可靠性保證(flush)。

當向elasticsearch傳送建立document文件新增請求的時候,document資料會先進入到buffer,與此同時會將操作記錄在translog之中,當發生refresh時(資料從index buffer中進入filesystem cache的過程)translog中的操作記錄並不會被清除,而當資料從os cache中被寫入磁碟之後才會將translog中清空。這個將os cache的索引檔案(segment file)持久化到磁碟的過程就是flush,flush之後,這段translog的使命就完成了,因為segment已經寫入磁碟,就算故障也可以從磁碟的segment檔案中恢復。flush的時機可能是1.定時flush;2.translog大小達到閾值;3.一些重要操作;4.指令觸發。

translog記錄的是已經在記憶體生成(segments)並存儲到os cache但是還沒寫到磁碟的那些索引操作(注意,有一種解釋說,新增到buffer中但是沒有被存入segment中的資料沒有被記錄到translog中,這依賴於寫translog的時機,不同版本可能有變化,不影響理解),此時這些新寫入的資料可以被搜尋到,但是當節點掛掉後這些未來得及落入磁碟的資料就會丟失,可以通過trangslog恢復。

當然translog本身也是磁碟檔案,頻繁的寫入磁碟會帶來巨大的IO開銷,因此對translog的追加寫入操作的同樣操作的是os cache,因此也需要定時落盤(fsync)。translog落盤的時間間隔直接決定了ES的可靠性,因為宕機可能導致這個時間間隔內所有的ES操作既沒有生成segment磁碟檔案,又沒有記錄到Translog磁碟檔案中,導致這期間的所有操作都丟失且無法恢復。

translog的fsync是ES在後臺自動執行的,預設是每5秒鐘主動進行一次translog fsync,或者當translog檔案大小大於512MB主動進行一次fsync,對應的配置是index.translog.flush_threshold_period 和 index.translog.flush_threshold_size。還需指出的是, 從ES2.0開始,每次index、bulk、delete、update完成的時候也會觸發translog flush,當flush到磁碟成功後才給請求端返回 200 OK。這個改變提高了資料安全性,但是會對寫入的效能造成不小的影響,因此在可靠性要求不十分嚴格且寫入效率優先的情況下,可以在 index template 裡設定如下引數:"index.translog.durability":"async",這相當於關閉了index、bulk等操作的同步flush translog操作,僅使用預設的定時重新整理、檔案大小閾值重新整理的機制,同時可以調高 "index.translog.sync_interval":30s (預設是5s)和index.translog.flush_threshold_size配置選項。

總結一下translog的功能:
  • 保證在filesystem cache中的資料不會因為elasticsearch重啟或是發生意外故障的時候丟失。
  • 當系統重啟時會從translog中恢復之前記錄的操作。
  • 當對elasticsearch進行CRUD操作的時候,會先到translog之中進行查詢,因為tranlog之中儲存的是最新的資料。
  • translog的清除時間時進行flush操作之後(將資料從filesystem cache刷入disk之中)。
總結一下flush操作的時間點:
  • es的各個shard會每個30分鐘進行一次flush操作。
  • 當translog的資料達到某個上限的時候會進行一次flush操作。
有關於translog和flush的一些配置項:
  • index.translog.flush_threshold_ops:當發生多少次操作時進行一次flush。預設是 unlimited。
  • index.translog.flush_threshold_size:當translog的大小達到此值時會進行一次flush操作。預設是512mb。
  • index.translog.flush_threshold_period:在指定的時間間隔內如果沒有進行flush操作,會進行一次強制flush操作。預設是30m。
  • index.translog.interval:多少時間間隔內會檢查一次translog,來進行一次flush操作。es會隨機的在這個值到這個值的2倍大小之間進行一次操作,預設是5s。

連結:https://www.jianshu.com/p/15837be98ffd

螃蟹在剝我的殼,筆記本在寫我,漫天的我落在楓葉上雪花上,而你在想我。 --章懷柔