Lucene採用了這種方案,緩存
- 它構建的單個倒排索引稱爲segment,合在一塊兒稱爲Index,
- 與ES中的Index概念不一樣。
- ES中的一個Shard對應一個Lucene Index。
segment寫入磁盤的過程依然很耗時,jvm
- 能夠藉助文件系統緩存的特性,
- 先將segment在緩存中 IT建立並開放查詢來進一步提高實時性,
- 該過程在es中被稱爲refresh。
- 在refresh以前文檔會先存儲在一個buffer中,
- refresh時將buffer中的全部文檔清空並生成segmentes
- 默認每1秒執行一次refresh,
- 所以文檔的實時性被提升到1秒,
- 這也是es被稱爲近實時(Near Real Time)的真正緣由
若是在內存中的segment尚未寫入磁盤前發生了宕機,那麼內存中的文檔就沒法恢復了。 索引
- 那麼如何解決這個問題呢?
- es引入translog機制。寫入文檔到buffer時,同時將該操做寫入translog。
- translog 文件會即時寫入磁盤(fsync),6.x默認每一個請求都會落盤,
- 能夠修改成每5秒寫一次,這樣風險即是丟失5秒內的數據,相關配置爲index.translog.*
- es從新啓動時會自動檢查translog文件,並從中恢復數據
flush負責將內存中的segment寫入磁盤,主要作以下的工做:內存
- 將translog寫入磁盤
- 將index buffer清空,其中的文檔生成一個新的segment,至關於一個refrsh操做
- 執行fsync操做,將內存中的segment寫入磁盤
- 刪除舊的translog文件
refresh發生的時機主要有如下幾種狀況:文檔
- 間隔時間達到時,
- 經過index.settings.refresh_interval來設定,默認是1秒
- index.buffer佔滿時,
- 其大小經過indices.memory.index_buffer_size設置,
- 默認爲jvm heap的10%,全部shard共享
- flush發生時也會發生refresh
flush發生的時機主要有如下幾種狀況:io
- 間隔時間達到時,默認是30分鐘
- 5.x以前能夠經過index.translog.flush_threshold_period修改
- 以後發佈的版本沒法設置
- translog佔滿時,
- 其大小能夠經過index.translog.flush_threshold_size控制,
- 默認是512MB每一個index有本身的translog