refresh flush

Elasticsearch 存储的基本单元是shard, ES中一个Index 可能分为多个shard, 事实上每个shard 都是一个Lucence 的Index,并且每个Lucence Index 由多个Segment组成, 每个Segment事实上是一些倒排索引的集合, 每次创建一个新的Document, 都会归属于一个新的Segment, 而不会去修改原来的Segment; 且每次的文档删除操作,会仅仅标记Segment中该文档为删除
状态, 而不会真正的立马物理删除, 所以说ES的index 可以理解为一个抽象的概念。



Commits in Lucene
为了数据安全, 每次的索引变更都最好要立刻刷盘, 所以Commit操作意味着将Segment合并,并写入磁盘。保证内存数据尽量不丢。刷盘是很重的IO操作, 所以为了机器性能和近实时搜索, 并不会刷盘那么及时。



Translog
新文档被索引意味着文档会被首先写入内存buffer和translog文件。每个shard都对应一个translog文件



Refresh in Elasticsearch
在elasticsearch中, _refresh 操作默认每秒执行一次, 意味着将内存buffer的数据写入到一个新的Segment中,这个时候索引变成了可被检索的。

Flush in Elasticsearch
Flush 操作意味着将内存buffer的数据全都写入新的Segments中, 并将内存中所有的Segments全部刷盘, 并且清空translog日志的过程。



refresh APA
在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是 近 实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。



这些行为可能会对新用户造成困惑: 他们索引了一个文档然后尝试搜索它,但却没有搜到。这个问题的解决办法是用 refresh API 执行一次手动刷新:




  1. POST /_refresh

  2. POST /blogs/_refresh



刷新(Refresh)所有的索引。
只刷新(Refresh) blogs 索引
并不是所有的情况都需要每秒刷新。可能你正在使用 Elasticsearch 索引大量的日志文件, 你可能想优化索引速度而不是近实时搜索, 可以通过设置 refresh_interval , 降低每个索引的刷新频率



PUT /my_logs { “settings”: { “refresh_interval”: “30s” }
refresh_interval 可以在既存索引上进行动态更新。 在生产环境中,当你正在建立一个大的新索引时,可以先关闭自动刷新,待开始使用该索引时,再把它们调回来:



PUT /my_logs/_settings { “refresh_interval”: -1 }
PUT /my_logs/_settings { “refresh_interval”: “1s” }
持久化变更
如果没有用 fsync 把数据从文件系统缓存刷(flush)到硬盘,我们不能保证数据在断电甚至是程序正常退出之后依然存在。为了保证 Elasticsearch 的可靠性,需要确保数据变化被持久化到磁盘。



在 动态更新索引,我们说一次完整的提交会将段刷到磁盘,并写入一个包含所有段列表的提交点。Elasticsearch 在启动或重新打开一个索引的过程中使用这个提交点来判断哪些段隶属于当前分片。



即使通过每秒刷新(refresh)实现了近实时搜索,我们仍然需要经常进行完整提交来确保能从失败中恢复。但在两次提交之间发生变化的文档怎么办?我们也不希望丢失掉这些数据。



Elasticsearch 增加了一个 translog ,或者叫事务日志,在每一次对 Elasticsearch 进行操作时均进行了日志记录。通过 translog ,整个流程看起来是下面这样:



一个文档被索引之后,就会被添加到内存缓冲区,并且 追加到了 translog



刷新(refresh)使分片处于 “刷新(refresh)完成后, 缓存被清空但是事务日志不会” 描述的状态,分片每秒被刷新(refresh)一次:
这些在内存缓冲区的文档被写入到一个新的段中,且没有进行 fsync 操作。
这个段被打开,使其可被搜索。
内存缓冲区被清空



这个进程继续工作,更多的文档被添加到内存缓冲区和追加到事务日志



每隔一段时间–例如 translog 变得越来越大–索引被刷新(flush);一个新的 translog 被创建,并且一个全量提交被执行



所有在内存缓冲区的文档都被写入一个新的段。
缓冲区被清空。
一个提交点被写入硬盘。
文件系统缓存通过 fsync 被刷新(flush)。
老的 translog 被删除。



translog 提供所有还没有被刷到磁盘的操作的一个持久化纪录。当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点去恢复已知的段,并且会重放 translog 中所有在最后一次提交后发生的变更操作。



translog 也被用来提供实时 CRUD 。当你试着通过ID查询、更新、删除一个文档,它会在尝试从相应的段中检索之前, 首先检查 translog 任何最近的变更。这意味着它总是能够实时地获取到文档的最新版本。



https://www.6aiq.com/article/1539308290695



当索引一个文档时,如果存在空闲的segment(未被其他线程锁定),则取出空闲segment list中的最后一个segment(LIFO),并锁定,将文档索引至该segment,
找达到flush条件的segment,然后解锁,归还至空闲segment list,如果有达到flush条件的segment,flush该segment。
如果不存在,则创建新的segment,重复上述步骤。
总结1:如果并行的执行向一个索引,索引文档,则需要不同的segment。



https://www.jianshu.com/p/b2b93caabe1d



https://zhuanlan.zhihu.com/p/34674517
https://zhuanlan.zhihu.com/p/34140178
https://zhuanlan.zhihu.com/p/35643348
https://zhuanlan.zhihu.com/Elasticsearch


Category elasticsearch