Elasticsearch更新后延迟问题处理

参考网站:

[Elasticsearch] ES更新问题踩坑记录 - chaplinthink - 博客园 (cnblogs.com)

解决elasticsearch更新数据后不能立即刷新的问题_es更新后立马刷新_我一直在流浪的博客-CSDN博客

问题

前端请求,对 ES 中的数据进行 update。然后进行查询刚刚操作完毕的数据,或者数据列表。

不过查询到的却是 update 前的数据。

原因分析

Elesticsearch 更新数据后会有延迟。

ES 实现的是一种【近实时搜索(Real-time Search)】的策略:

  1. ES 产生一个新分段(Segment),把数据缓存到 Index Buffer;
  2. refresh:1s 后(默认配置),ES 清空写缓存,新段 write 到文件系统缓存(FileSystem Cache);
  3. flush:通过手工调用 flush 接口(POST /my-index-000001/_flush),或者操作系统通过一定策略(默认每隔 30 分钟或者 translog 达到一定大小的时候:由 index.translog.flush_threshold_size 控制,默认 512MB),将 Index Buffer 中的数据全部刷新到磁盘里的一个新的 Segment 中,清空 Index Buffer。然后调用 Lucene 的 commit 方法将所有内存中的 Segment 持久化(fsync)到磁盘,一个 commit point 写入磁盘中,同时清空 translog 日志文件。

提交点(commit point):记录当前所有可用的 Segment ,一个索引一般只有一个 commit point,而每个 commit point 都会维护一个 .del 文件( ES 删除数据本质是不属于物理删除),当 ES 做删改操作时首先会在 .del 文件中声明某个 Document 已经被删除,文件内记录了在某个 Segment 内某个 Document 已经被删除,当查询请求过来时在 Segment 中被删除的文件是能够查出来的,但是当返回结果时会根据 commit point 维护的那个 .del 文件把已经删除的文档过滤掉。

这种策略可以大幅提升写入的效率。因为从 write 接口返回 success 开始,无论数据有没有被刷到磁盘,该数据已经对读取可见。

处理方案

方案一:修改 ES refresh 的间隔时间

1
curl -XPUT  http://ip:9200/meta_es_data/_settings?pretty -d '{"refresh_interval" : "500ms"}'

方案二:在每次更新操作后,休眠 1s

1
2
3
baseSearchService.update(docBean);

Thread.sleep(1000);

方案三:在 ES 请求接口有请求后强制 refresh(当写测试的时候, 手动刷新很有用,但是不要在生产环境下每次索引一个文档都去手动刷新。 “相反,你的应用需要意识到 Elasticsearch 的近实时的性质,并接受它的不足” ~~~)

1
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);

拓展

拓展一

ES 的 refresh 虽然可以配置刷新的时间,但是没必要,频繁的刷新会造成压力过大。

因为 ES 每次 refresh 都产生一个新段(Segment),频繁的 refresh 会导致段数量的暴增。段数量过多会导致过多的消耗文件句柄、内存和 CPU 时间;而且段的数量越多,查询的速度也会越慢。

虽然 ES 可以进行【段合并】,但是段的合并会消耗掉大量系统资源,尤其是磁盘 I/O。

拓展二

ES 数据在更新的时候并不是在原来的数据上做修改的,而是找到该数据的索引 ID,把原来的数据删掉,再重新插入一条,但索引 ID 是相同的。

拓展三

当删除、更新两个操作间隔很短时间执行,上一个数据还没有 refresh 到 FileSystem Cache 区域,就无法查询。

final TableDocBean docBean = baseSearchService.getById(id);(获取不到数据,会导致数据更新失败)

拓展四

由于系统是先缓存了一段数据才写,且新段不会立即刷入磁盘中,这两个过程如果出现某些意外情况(例如主机断电等),则会存在丢失数据的风险。通用的处理方法是【记录事务日志】,每次对 ES 进行操作时均记录事务日志,当 ES 启动的时候,重放 translog 中所有在最后一次提交后发生的变更操作。比如 HBase 等都有自己的事务日志。





  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 Liangxj
  • 访问人数: | 浏览次数: