Elasticsearch 是一個基於 Lucene 庫的搜索引擎。它提供了一個準實時的、分佈式、支持多租戶的全文搜索引擎。 ————維基百科緩存
那麼問題來了,爲啥 Elasticsearch 不是實時的,是什麼阻礙了它的實時性?elasticsearch
文章引用自:https://juejin.im/post/5d1b35a1e51d45775746b990分佈式
elasticsearch 被稱爲準實時搜索,緣由是對 Elasticsearch 的寫入操做成功後,寫入的數據須要1秒鐘後才能被搜索到,所以 Elasticsearch 搜索是準實時或者又稱爲近實時(near real time
)。post
elasticsearch底層使用的 Lucene,而 Lucene 的寫入是實時的。但 Lucene 的實時寫入意味着每一次寫入請求都直接將數據寫入硬盤,所以頻繁的I/O操做會致使很大的性能問題。性能
圖1 表示是 es 寫操做流程,當一個寫請求發送到 es 後,es 將數據寫入 memory buffer
中,並添加事務日誌(translog
)。若是每次一條數據寫入內存後當即寫到硬盤文件上,因爲寫入的數據確定是離散的,所以寫入硬盤的操做也就是隨機寫入了。硬盤隨機寫入的效率至關低,會嚴重下降es的性能。搜索引擎
所以 es 在設計時在 memory buffer
和硬盤間加入了 Linux 的頁面高速緩存(File system cache
)來提升 es 的寫效率。spa
當寫請求發送到 es 後,es 將數據暫時寫入 memory buffer
中,此時寫入的數據還不能被查詢到。默認設置下,es 每1秒鐘將 memory buffer
中的數據 refresh
到 Linux 的 File system cache
,並清空 memory buffer
,此時寫入的數據就能夠被查詢到了。設計
圖1 ElasticSearch 日誌寫入日誌
但 File system cache
依然是內存數據,一旦斷電,則 File system cache
中的數據所有丟失。默認設置下,es 每30分鐘調用 fsync
將 File system cache
中的數據 flush
到硬盤。所以須要經過 translog
來保證即便由於斷電 File system cache
數據丟失,es 重啓後也能經過日誌回放找回丟失的數據。code
translog
默認設置下,每個 index
、delete
、update
或 bulk
請求都會直接 fsync
寫入硬盤。爲了保證 translog
不丟失數據,在每一次請求以後執行 fsync
確實會帶來一些性能問題。對於一些容許丟失幾秒鐘數據的場景下,能夠經過設置 index.translog.durability
和 index.translog.sync_interval
參數讓 translog
每隔一段時間才調用 fsync
將事務日誌數據寫入硬盤。
對於須要寫入後實時查詢的數據,能夠經過手動 refresh
操做將 memory buffer
的數據當即寫入到 File system cache
。固然,該解決方案的代價就是下降了 ES 的寫性能。
一、單個文檔更新後當即refresh
PUT /test/_doc/1?refresh {"test": "test"} PUT /test/_doc/2?refresh=true {"test": "test"}
二、refresh
整個索引的memory buffer
POST /test/_refresh