Elasticsearch设置refresh=true后文档更新未立即生效问题咨询
结论先行
你的预期完全合理,关闭案件后立即从待办队列消失是非常符合业务逻辑的正常需求,当前问题的根源和解决方案如下:
问题根因分析
你当前使用的是ES 2.4版本,refresh=true参数仅会触发处理写入请求的主分片执行强制刷新,副本分片并不会同步触发刷新,仍然遵循默认1秒的后台刷新周期。
你返回结果中的_shards字段显示total:2, successful:1,并不是只更新了副本分片,反而代表主分片已经完成写入和刷新,副本分片的刷新动作尚未完成,所以仅统计到1个成功的refresh操作。
由于你的搜索请求会在主、副本分片之间自动负载均衡,当请求命中还未完成刷新的副本分片时,就会返回旧的status数据,导致已经关闭的案件仍然出现在处理中队列里。
适配你场景的最优解决方案
你的业务日更新量仅1000次,就算每次都强制刷新也完全不会触发官方文档提到的性能问题,以下方案按改造成本从低到高排序:
- 方案1:搜索时指定查询偏好为主分片
在待办队列的查询请求中添加参数preference=_primary,强制所有队列查询请求路由到主分片,主分片已经在写入时完成强制刷新,可100%保证每次查询都能拿到最新状态。这个方案改造成本极低,仅需要修改查询请求参数,你的日均几万次查询量完全不会给主分片带来压力。 - 方案2:降低索引全局刷新间隔
直接调整cases索引的配置,将index.refresh_interval从默认1s改为100ms,副本分片的后台刷新间隔降低到0.1秒,用户几乎感知不到延迟。这个方案不需要修改任何业务请求代码,仅需要调整ES索引配置即可。 - 方案3:前端短延迟重试兼容
如果你不想修改ES侧的任何配置和请求参数,可以在前端刷新待办队列的逻辑里增加兼容:如果查询到的列表中包含用户刚关闭的案件,自动做一次300ms的延迟重试,基本可以覆盖副本分片的刷新间隔,用户感知也非常弱。
内容的提问来源于stack exchange,提问作者mojoken
相关产品推荐
相关产品推荐

