②延迟写策略介绍完了存储的形式,那么索引写入到磁盘的过程是怎样的?是否是直接调 Fsync 物理性地写入磁盘?
答案是显而易见的,如果是直接写入到磁盘上,磁盘的 I/O 消耗上会严重影响性能 。
那么当写数据量大的时候会造成 ES 停顿卡死,查询也无法做到快速响应 。如果真是这样 ES 也就不会称之为近实时全文搜索引擎了 。
为了提升写的性能,ES 并没有每新增一条数据就增加一个段到磁盘上,而是采用延迟写的策略 。
每当有新增的数据时,就将其先写入到内存中,在内存和磁盘之间是文件系统缓存 。
当达到默认的时间(1 秒钟)或者内存的数据达到一定量时,会触发一次刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件缓存系统 上,稍后再被刷新到磁盘中并生成提交点 。
这里的内存使用的是 ES 的 JVM 内存,而文件缓存系统使用的是操作系统的内存 。
新的数据会继续的被写入内存,但内存中的数据并不是以段的形式存储的,因此不能提供检索功能 。
由内存刷新到文件缓存系统的时候会生成新的段,并将段打开以供搜索使用,而不需要等到被刷新到磁盘 。
在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 Refresh (即内存刷新到文件缓存系统) 。
默认情况下每个分片会每秒自动刷新一次 。这就是为什么我们说 Elasticsearch 是近实时搜索,因为文档的变化并不是立即对搜索可见,但会在一秒之内变为可见 。
我们也可以手动触发 Refresh,
POST /_refresh刷新所有索引,POST /nba/_refresh刷新指定的索引 。Tips:尽管刷新是比提交轻量很多的操作,它还是会有性能开销 。当写测试的时候,手动刷新很有用,但是不要在生产>环境下每次索引一个文档都去手动刷新 。而且并不是所有的情况都需要每秒刷新 。
可能你正在使用 Elasticsearch 索引大量的日志文件,你可能想优化索引速度而不是>近实时搜索 。
这时可以在创建索引时在 Settings 中通过调大
refresh_interval = "30s" 的值 ,降低每个索引的刷新频率,设值时需要注意后面带上时间单位,否则默认是毫秒 。当refresh_interval=-1时表示关闭索引的自动刷新 。虽然通过延时写的策略可以减少数据往磁盘上写的次数提升了整体的写入能力,但是我们知道文件缓存系统也是内存空间,属于操作系统的内存,只要是内存都存在断电或异常情况下丢失数据的危险 。
为了避免丢失数据,Elasticsearch 添加了事务日志(Translog),事务日志记录了所有还没有持久化到磁盘的数据 。

文章插图
添加了事务日志后整个写索引的流程如上图所示:
- 一个新文档被索引之后,先被写入到内存中,但是为了防止数据的丢失,会追加一份数据到事务日志中 。
不断有新的文档被写入到内存,同时也都会记录到事务日志中 。这时新数据还不能被检索和查询 。
- 当达到默认的刷新时间或内存中的数据达到一定量后,会触发一次 Refresh,将内存中的数据以一个新段形式刷新到文件缓存系统中并清空内存 。这时虽然新段未被提交到磁盘,但是可以提供文档的检索功能且不能被修改 。
- 随着新文档索引不断被写入,当日志数据大小超过 512M 或者时间超过 30 分钟时,会触发一次 Flush 。
内存中的数据被写入到一个新段同时被写入到文件缓存系统,文件系统缓存中数据通过 Fsync 刷新到磁盘中,生成提交点,日志文件被删除,创建一个空的新日志 。
③段合并
由于自动刷新流程每秒会创建一个新的段 ,这样会导致短时间内的段数量暴增 。而段数目太多会带来较大的麻烦 。
每一个段都会消耗文件句柄、内存和 CPU 运行周期 。更重要的是,每个搜索请求都必须轮流检查每个段然后合并查询结果,所以段越多,搜索也就越慢 。
推荐阅读
- 远安黄茶功效禁忌,黄茶的功效与作用及禁忌详解
- 黄茶都有哪几种,详解黄茶和绿茶的区别
- 黄茶的保健功效与作用,黄茶的功效与作用及禁忌详解
- 岳阳黄茶品质特点,详解黄茶特点
- 黄茶的保健功能,黄茶的功效与作用及禁忌详解
- 黄茶具备的品质特点,详解黄茶特点
- 青茶红茶黑茶白茶绿茶黄茶等都有什么区别,详解黄茶和绿茶的区别
- 虎山黄茶的功效与作用及禁忌,黄茶的功效与作用及禁忌详解
- 黄小茶品质特点,详解黄茶特点
- 黄茶的特点与功效及禁忌,黄茶的功效与作用及禁忌详解
