- 问题描述:
SpringBoot 项目使用 RestHighLevelClien 操作ES修改数据成功,之后前端调用查询接口发现数据并未更新,待1S左右再次刷新发现ES数据成功更新。
从现象来看是ES操作后存在延迟。 - 问题原因
这个问题是Elasticsearch本身在操作数据后有一定的延迟性导致。Elasticsearch默认情况下在写入数据后,是要等1s后才能被查询到。
因为Elasticsearch中每次索引refresh
会产生一个新的 lucene 段,这会导致频繁的segment merge
行为,对系统 CPU 和 IO 占用都比较高。 - 解决方案
- 方案1:代码中指定setRefreshPolicy的刷新策略,使用立即刷新策略IMMEDIATE方式提交请求。
1 public static enum RefreshPolicy implements Writeable {
2 NONE("false"), 3 IMMEDIATE("true"), 4 WAIT_UNTIL("wait_for"); 5 }- IMMEDIATE:
请求想ES提交了数据,立即刷新数据再结束请求
优点:实时性最高,实时性最高
缺点:资源消耗高 - WAIT_UNTIL
请求向ES提交数据,等待1S(默认)后结束请求,数据刷新。
优点:实时性相对较高
缺点:资源消耗低 - NONE(默认策略)
请求向ES提交数据,不等待数据完成刷新,直接结束请求。
优点:操作延时短,资源消耗低
缺点:实时性低 - 支持的接口:
删除:DeleteRequestBuilder
新增:IndexRequestBuilder
更新:UpdateRequestBuilder
批量:BulkRequestBuilder
- IMMEDIATE:
- 方案2:前端后后端,使用sleep的方式延迟调用API,等待ES数据更新后再进行请求
- 方案1:代码中指定setRefreshPolicy的刷新策略,使用立即刷新策略IMMEDIATE方式提交请求。