• 持久化变更
    • flush API

    持久化变更

    没用fsync同步文件系统缓存到磁盘,我们不能确保电源失效,甚至正常退出应用后,数据的安全。为了ES的可靠性,需要确保变更持久化到磁盘。

    我们说过一次全提交同步段到磁盘,写提交点,这会列出所有的已知的段。在重启,或重新打开索引时,ES使用这次提交点决定哪些段属于当前的分片。

    当我们通过每秒的刷新获得近实时的搜索,我们依然需要定时地执行全提交确保能从失败中恢复。但是提交之间的文档怎么办?我们也不想丢失它们。

    ES增加了事务日志(translog),来记录每次操作。有了事务日志,过程现在如下:

    1. 当一个文档被索引,它被加入到内存缓存,同时加到事务日志。

      图1:新的文档加入到内存缓存,同时写入事务日志
      新的文档加入到内存缓存,同时写入事务日志

    2. refresh使得分片的进入如下图描述的状态。每秒分片都进行refeash:

      • 内存缓冲区的文档写入到段中,但没有fsync。
      • 段被打开,使得新的文档可以搜索。
      • 缓存被清除

        图2:经过一次refresh,缓存被清除,但事务日志没有
        经过一次refresh,缓存被清除,但事务日志没有

    3. 随着更多的文档加入到缓存区,写入日志,这个过程会继续

      图3:事务日志会记录增长的文档
      事务日志会记录增长的文档

    4. 不时地,比如日志很大了,新的日志会创建,会进行一次全提交:

      • 内存缓存区的所有文档会写入到新段中。
      • 清除缓存
      • 一个提交点写入硬盘
      • 文件系统缓存通过fsync操作flush到硬盘
      • 事务日志被清除

    事务日志记录了没有flush到硬盘的所有操作。当故障重启后,ES会用最近一次提交点从硬盘恢复所有已知的段,并且从日志里恢复所有的操作。

    事务日志还用来提供实时的CRUD操作。当你尝试用ID进行CRUD时,它在检索相关段内的文档前会首先检查日志最新的改动。这意味着ES可以实时地获取文档的最新版本。

    图4:flush过后,段被全提交,事务日志清除
    flush过后,段被全提交,事务日志清除

    flush API

    在ES中,进行一次提交并删除事务日志的操作叫做 flush。分片每30分钟,或事务日志过大会进行一次flush操作。

    flush API可用来进行一次手动flush:

    1. POST /blogs/_flush <1>
    2. POST /_flush?wait_for_ongoing <2>
    • <1> flush索引blogs
    • <2> flush所有索引,等待操作结束再返回

    你很少需要手动flush,通常自动的就够了。

    当你要重启或关闭一个索引,flush该索引是很有用的。当ES尝试恢复或者重新打开一个索引时,它必须重放所有事务日志中的操作,所以日志越小,恢复速度越快。