问题复现
在跟前端进行联调的过程中发现了一个问题,向elasticsearch中增加一条文档数据后,立即请求查询文档列表,发现刚刚新增的文档查不出来,刷新页面或等1s后重新再次请求查询才能查询出来,随后测试了删除文档列表和更新文档列表中的文档这两个接口,出现了同样的问题,即elasticsearch数据更新有延迟。
问题原因
默认情况下ElasticSearch索引的refresh_interval为1秒,这意味着数据写1秒才就可以被搜索到。
因为上述表现,所以称ElasticSearch是近实时搜索引擎。
如果需要调整数据刷新方案,则有三种途径:
设置数据刷新间隔:refresh_interval。
调用数据刷新接口:_refresh。
设置数据刷新策略:RefreshPolicy。
问题修复
1. 设置数据刷新间隔
# 调整所有index的刷新间隔位5分钟
PUT
{
"settings": {
"refresh_interval": "5m"
}
}
# 调整指定index的刷新间隔为180秒
PUT /log
{
"settings": {
"refresh_interval": "180s"
}
}
# 关闭全部index的数据刷新
PUT
{
"settings": {
"refresh_interval": -1
}
}
# 调整指定index的刷新间隔为1秒
PUT /indexname
{
"settings": {
"refresh_interval": "1s"
}
}
注意事项
- 刷新间隔为
-1
代表关闭数据刷新。- 刷新间隔设置时应改携带单位,如:1h、2m、3s。
- 应用在于大量写日志,而非近实时搜索,此时可以增大刷新间隔
2. 调用刷新接口
手动调用ElasticSearch提供的API进行数据刷新,如下:
# 刷新全部index的数据
POST /_refresh
# 刷新指定index的数据
POST /indexname/_refresh
3. 设置刷新策略
可知有以下三种刷新策略:
RefreshPolicy#IMMEDIATE:
请求向ElasticSearch提交了数据,立即进行数据刷新,然后再结束请求。
优点:实时性高、操作延时短。
缺点:资源消耗高。
RefreshPolicy#WAIT_UNTIL:
请求向ElasticSearch提交了数据,等待数据完成刷新,然后再结束请求。
优点:实时性高、操作延时长。
缺点:资源消耗低。
RefreshPolicy#NONE:
默认策略。
请求向ElasticSearch提交了数据,不关系数据是否已经完成刷新,直接结束请求。
优点:操作延时短、资源消耗低。
缺点:实时性低。
结论
综合考虑下来,本人采取了调用刷新接口的方法进行处理,再文档增删改之后主动去调用了_refresh 接口已达到实时搜索可见的效果。
使用NEST调用_refresh接口方法如下:
private async Task RefreshIndex(string indexName)
{
var _client = _clientProvider.GetClient(indexName);
await _client.Indices.RefreshAsync(Indices.Parse(indexName));
}