如果一个新文档被索引到 Elasticsearch 索引,那么它可以在索引操作后 1 秒内进行搜索。但是,可以通过对索引调用_flush
或操作来强制使该文档立即可搜索。_refresh
这两个操作有什么区别 - 结果似乎对他们来说是一样的,文档是立即可搜索的。
这些操作中的每一项到底是什么?
ES 文档似乎没有深入解决这个问题。
如果一个新文档被索引到 Elasticsearch 索引,那么它可以在索引操作后 1 秒内进行搜索。但是,可以通过对索引调用_flush
或操作来强制使该文档立即可搜索。_refresh
这两个操作有什么区别 - 结果似乎对他们来说是一样的,文档是立即可搜索的。
这些操作中的每一项到底是什么?
ES 文档似乎没有深入解决这个问题。
您得到的答案是正确的,但我认为值得进一步阐述。
刷新有效地调用 lucene 索引读取器上的重新打开,以便您可以搜索的数据的时间点快照得到更新。这个 lucene 特性是 lucene 近实时 api 的一部分。
弹性搜索刷新使您的文档可用于搜索,但它不能确保将它们写入磁盘到持久存储,因为它不调用 fsync,因此不能保证持久性。使您的数据持久的原因是 lucene 提交,它的成本要高得多。
虽然您可以每秒调用 lucene 重新打开,但您不能对 lucene commit 执行相同的操作。
通过 lucene,您可以通过经常调用重新打开来近乎实时地搜索新文档,但您仍然需要调用 commit 以确保将数据写入磁盘并进行 fsync,从而安全。
Elasticsearch 通过为每个分片(实际上是一个 lucene 索引)添加一个事务日志来解决这个“问题”,其中存储了尚未提交的写入操作。事务日志是 fsync 且安全的,因此您可以在任何时间点获得持久性,即使对于尚未提交的文档也是如此。您可以近乎实时地搜索文档,因为每秒都会自动进行刷新,并且您还可以确保如果发生错误,可以重放事务日志以恢复最终丢失的文档。事务日志的好处是它可以在内部用于其他事情,例如通过 id 提供实时获取。
弹性搜索刷新有效地触发了lucene 提交,并且还清空了事务日志,因为一旦在 lucene 级别提交数据,lucene 本身就可以保证持久性。Flush 也作为 api 公开并且可以进行调整,尽管通常这不是必需的。根据添加到事务日志中的操作数量、它们的大小以及最后一次刷新发生的时间,刷新会自动发生。
刷新会导致写入一个新段,因此它可用于搜索。
刷新会导致发生 Lucene 提交。这要贵得多。
有关更多详细信息,我写了一篇文章,其中涵盖了其中一些内容:Elasticsearch from the bottom up :)
刷新:
冲洗:
Segment是lucene的一部分。不可变段使 OS 页面缓存总是干净的。
Translog 是 Elasticsearch 的一部分。Translog 的目标是耐用性。
参考: