Elasticsearch在操作数据后不能立即查询到数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch在操作数据后不能立即查询到数据相关的知识,希望对你有一定的参考价值。

参考技术A

一次在使用Elasticsearch来存储数据的时候,前端在把数据保存成功后,调用查询列表的接口来刷新列表时,发现有时能刷新出新保存的数据,有时候又不能,修改和删除数据也发现有类似现象。但是再次刷新页面的时候又可以查询到新操作的数据。

后面发现这个问题是Elasticsearch本身在操作数据后有一定的延迟性导致。Elasticsearch默认情况下在写入数据后,是要等 1s 后才能被查询到。

因为Elasticsearch中每次索引 refresh 会产生一个新的 lucene 段,这会导致频繁的 segment merge 行为,对系统 CPU 和 IO 占用都比较高。

需要修改ElasticSearch的刷新策略

org.elasticsearch.action.support.WriteRequest.RefreshPolicy 中定义了三种刷新策略:

IMMEDIATE

WAIT_UNTIL

NONE (默认策略)

org.elasticsearch.action.support.WriteRequestBuilder 中的 setRefreshPolicy 方法,默认为设置为RefreshPolicy#NONE

setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) 设置为立即刷新,即可解决不能立即查询到数据的问题。

支持的接口:

在查询结果前使用sleep来暂停一段时间再执行查询操作,这样可以不改变ElasticSearch的刷新策略。

当业务需要频繁的操作修改数据的情况下,设置刷新策略为立即刷新的话可能会造成性能问题。

我们可以使用sleep的方式不去修改默认的刷新策略。

当我们在执行新增、修改、删除、批量操作的时候,在这些操作中设置一把锁,过期时间为1s(这个时间刚好是刷新策略的默认时间),在查询数据时我们需要先去检查是否有锁,如果有锁存在我们就等待500ms后再执行查询操作。这样基本上又可以保证不改刷新策略,也可以保存查询的实时性。

ElasticSearch中实现文档操作后立即被搜索到

ElasticSearch一般称为近实时的大数据处理引擎,为什么是近实时呢?原因是当我们提交索引数据时,实际上只是写到了Buffer里面,并不是立即可搜索的,最多需要等1秒才可搜索(index.refresh_interval由这个参数控制,可以通过动态API自定义设置,或在建索引时在settings里面设置),还有一点,当存在副本时,只保证主分片写入成功写入请求就会返回,此时搜索请求如果分配到了副本上,有可能是搜索不到的。

那怎么做到实时搜索呢,在Java的UpdateRequest、IndexRequest、DeleteRequest对象中设置一下就可以了:setRefreshPolicy(RefreshPolicy.IMMEDIATE)

以上是关于Elasticsearch在操作数据后不能立即查询到数据的主要内容,如果未能解决你的问题,请参考以下文章

Elastic Search 基本操作

Elasticsearch和RestHighLevelClient的使用

Elasticsearch学习4-数据修改

Elasticsearch基本查询总结

Elasticsearch基本查询总结

在 Elasticsearch NEST 中的索引间歇性失败后立即调用 Search