[Elasticsearch] refresh/flush/merge概念及Api

一、Refresh操作

默认情况下,Elasticsearch写入的数据会存在于内存缓冲区中,此时并没有落入segment,而是等待index.refresh_interval的时间间隔后,数据会落入到segment中,此时才可以被检索;

而refresh操作简而言之就是将内存缓冲区的数据刷入segement中,使其可以被索引;而默认情况下es配置index.refresh_interval为1s,即每1s将缓冲区的数据刷到segment中使其可以被索引,也就是es所称的实时搜索;

ES会进行默认配置的refresh,但执行index ,Update , Delete , Bulk 操作时提供了可以手动指定refresh 的值,比如

PUT /test/_doc/1?refresh=true
{"field": "test"}
PUT /test/_doc/1?refresh=false
{"field": "test"}
PUT /test/_doc/1?refresh=wait_for
{"field": "test"}

在这时写入数据会同时执行refrsh的操作,总共有三种策略
    1.true
    2.false(默认)
    3.wait_for:等待index.refresh_interval时间,使其自动refresh后响应返回

当我们的某个索引,不需要实时搜索的时候,我们可以调整index.refresh_interval的时间间隔,让其节省资源,在插入数据的时候进行显式的指定refresh=true;

二、Flush操作

flush操作就是将segment中的数据刷入磁盘当中; 

需要注意的是,在flush操作前会进行refresh的操作,确保当前的内存缓冲区数据也可以成功落盘;

而说到这里就需要提到trans log的问题,translog是elasticsearh在数据写入内存缓冲区时,同步写入的日志;可以称其为防丢日志; 他的作用是保证在内存缓冲区而未刷入segment中的数据不会因为意外而丢失,如果出现意外也可以通过translog来进行数据的恢复,从而保证形成segment;

而flush操作可以内存缓冲区的数据刷新到segment中,并将segment刷入到磁盘中,而同时会删除当前的translog;

总的来说,当我们执行flush的时候同时执行以下操作

  1. 把所有在内存缓冲区中的文档写入到一个新的segment中
  2. 清空内存缓冲区
  3. 往磁盘里写入commit point信息
  4. 将segment数据落盘
  5. 删除旧的translog文件,因此此时内存中的segments已经写入到磁盘中,就不需要translog来保障数据安全了

一般情况下,对于批量导入大量数据到ElasticSearch的某个索引后,推荐进行手动的flush操作,可以释放掉多余的trans log的空间;(但注意,当索引正在执行flush操作时,可能会对性能产生一定的影响,因为系统需要同时处理磁盘IO和搜索请求。所以如果非大量数据导入后清理空间,不推荐频繁的进行手动的flush操作)

ES会进行默认的flush操作,但同样提供了手动flush的操作;(批量导入大量数据到ElasticSearch的某个索引后,推荐进行手动的flush操作,)

POST /test_index/_flush 

在执行flush操作的时候,提供了以下参数:

allow_no_indices

当索引使用通配符等方式时,是否允许未命中有效索引,该参数设置为true时,未命中索引不会返回错误,反之返回错误

默认为true

force

未提交到索引的修改也会被强制刷新(内部参数)

默认为true

wait_if_ongoing

如果为true,那么在已有flush请求处理过程中,会阻塞当前flush请求;

如果为flase,发现已有flush请求,直接返回错误

默认为true

ignore_unavailable

使用丢失或关闭的索引,则请求返回错误。

默认为false

三、Merge操作

上面提到过在每个分片中,存储数据的最小单位为segment,也就是说我们搜索数据的时候会去每个shard中的每个segment寻找数据,所以segment过多是灾难的。

当segment过多的时候,会自动寻找非hot时间段进行merge操作;将多个小的segment合并整理为一个segment。
当然你也可以使用force merge进行强制的手动merge操作,但该操作会使索引只读。这是因为在force merge操作期间,Elasticsearch将所有的分段合并成一个更大的分段,并且在此过程中会暂停写入操作,以确保分段的一致性和完整性。

可以在强制合并的时候指定max_num_segments参数,来指定将多个segment合并成最后的一个索引大小;若指定max_num_segments为1,那么segment将会合并为1个segment。


当然从另外一个角度来说,其实merge就是因为多个segment中的数据量过于碎片,换种思想我们可以在setting中增大index-refresh-interval的值,使得内存缓冲区的数据refresh成segement时,拥有更大的单位;但是注意调大index.refresh_interval意味着数据从写入到被索引也就是进入segement的间隔变长,所以不建议对实时搜索需求的索引调整该参数。

    ElasticSearch会进行自动的Merge操作,但同样提供了强制Merge的API。

POST /test_index/_forcemerge?max_num_segments = 1 
flush

是否在合并后执行flush操作;

默认为true.

max_num_segments 合并到的段数。要完全合并索引,请将其设置为1.
wait_for_completion

如果true,请求将阻塞直到操作完成。

默认为true.

四、总结

写入数据时,会首先写入到内存缓冲区,并记录相关translog。

内存缓冲区的数据会在index.refresh_interval时间后,自动写入segment中。

过多的segment会触发merge操作,目的旨在整理segment,防止segment过多影响搜索效率。

而flush操作会将segment们落入到磁盘当中,并同时记录提交点,删除旧的translog释放空间;

当然,es提供了手动的refresh操作,手动的flush操作,手动的强制merge操作;

推荐不需要实时搜索的索引,调大index.refresh_interval,节省IO;

推荐在大量数据写入索引后,手动进行调用flush操作,释放translog的空间;

推荐在集群环境良好,节点不易掉线情况时,调大index.translog.sync_interval,即调大tranlog刷盘时间(默认5s,推荐增大至30s);

不推荐频繁的进行手动强制merge操作,该操作使得索引只读;

[Elasticsearch] refresh/flush/merge概念及Api_第1张图片

图片地址:ES的数据写入原理,refresh和flush_es写入原理_攻城狮Kevin的博客-CSDN博客

你可能感兴趣的:(elasticsearch,大数据,搜索引擎)