1 概述
es是如何處理索引數據的變動的?
或者說索引數據變動時,es會執行哪些操作?
refresh、fsync、merge 和 flush 操作有何作用?
es是如何確保即使es發生宕機數據也不丟失的?
在回答上述問題前,可以先了解一下es處理索引數據變動的主要流程,其示意圖如下所示。
2 處理索引數據變動的過程
由示意圖可知,es處理索引數據變動的主要過程如下所述:
(1)將數據寫入內存緩沖區;
(2)生成新的segment,使數據可見-即可被搜索到;
(3)將數據存儲到磁盤。
2.1 將數據寫入內存緩沖區
當索引數據變動(插入、更新或刪除索引數據)時,首先會將變動的索引數據寫入到內存中的“索引緩沖區”,然后將索引數據變動命令寫入到內存中的“translog緩沖區”。
- translog的作用是當es服務宕機后需要進行數據恢復時,通過translog可以恢復尚未存儲到磁盤中的es索引數據。
- 通過每次索引變動請求完成時(默認)執行fsync操作,或者定時執行(設為異步執行時,默認為5s)fsync操作,將“translog緩沖區”中的數據添加到磁盤中的translog文件中。
New documents are added to the in-memory buffer and appended to the transaction log
2.2 使數據可見
通過定時執行refresh操作,將“索引緩沖區”的文檔生成一個新的segment(段),此時新增和修改的數據能被搜索到。
- 默認每秒執行一次refresh操作。
- 每次refresh操作都會生成一個新的segment,隨著時間的增長segmengt會越來越多。因為每次search操作都會掃描所有的segment,因此segmengt過多將導致查詢效率變慢。為了避免該問題的發生,es會定期將segment進行merge合并操作。
- 執行refresh操作時,磁盤中的translog文件不會被清除。
?After a refresh, the buffer is cleared but the transaction log is not
2.3 將數據存儲到磁盤
(3)通過執行flush操作(刷盤),將內存中的segment存儲到磁盤,同時刪除磁盤中的translog文件。
- 默認每隔30min執行一次,或者在磁盤中的translog文件過大時(index.translog.flush_threshold_size,默認512mb)執行一次。
After a flush, the segments are fully commited and the transaction log is cleared
3 refresh、merge 和 flush
3.1 refresh
3.1.1 定義
將“索引緩沖區”的文檔生成一個新segment(段)并清空該“索引緩沖區”,使新增或修改后的數據能被ES的api接口查詢到。
refresh_interval 控制索引refresh頻率 ,默認為1s。
3.1.2 修改執行頻率
可以通過修改 refresh_interval 來修改執行頻率
PUT /test_index/_settings
{"settings": {"refresh_interval": "2s" }
}
3.1.3 api
refresh全部索引
POST /_refresh
refresh指定索引
POST /test_index/_refresh
3.2 merge
將多個小segment合并成一個大segment,并刪除舊的segment。
3.3 flush
3.3.1 定義
通過執行flush操作(刷盤),將內存中的segment存儲到磁盤,同時刪除磁盤中的translog文件。
3.3.2 api
刷盤指定索引
POST /test_index/_flush
刷盤所有索引,且等刷盤結束才返回結果
POST /_flush?wait_for_ongoing
4 參考文獻
(1)理解ES的refresh、flush、merge
(2)Making Changes Persistent | Elasticsearch: The Definitive Guide [2.x] | Elastic
(3)Translog | Elasticsearch Guide [7.10] | Elastic