ElasticSearch的Update By Query的坑(使用注意事项及其方案)

ES的Update By Query对应的就是关系型数据库的update set ... where...语句;

ES的Update By Query可能存在的坑:比如批量更新时非事务模式执行(允许部分成功部分失败)、大批量操作会超时、频繁更新会报错(版本冲突)、脚本执行太频繁时又会触发断路器等。

 

1. 非事务模式执行

所有更新和查询失败都会导致update_by_query中止,并在响应失败时返回。已执行的更新仍然存在。(该过程不会回滚,只会中止)

使用时候不建议太大数据的修改;

建议增加补偿机制,将失败的请求记录下来,定时补偿;

 

2. java.io.IOException: listener timeout

默认是30000ms,(修改超时时间并非真正的解决方案)

 

3. VersionConflictEngineException

es是准实时的,默认refresh_interval: "1s"(默认值,可修改)

update_by_query在索引启动时获取索引的快照,这意味着如果文档在生成快照的时间和处理索引请求之间发生更改,则会出现版本冲突。===》1s内多次修改同一个document就会发生,你通过设置version_conflicts=false(会忽略错误),但并未解决问题,还有2种方式解决该问题:

  • retries,一直重试,UpdateByQueryRequestBuilder中默认为11次,可见对es是有一定的压力的
  • refresh=true,一直去刷盘,当然可以解决准实时的问题,但磁盘消耗是很多的

 

4. IllegalArgumentException: failed to execute script

Too many dynamic script compilations within, max: [75/5m],script修改语句只能接受5分钟内75次,具体可参与官方script-compilation-circuit-breaker,这个值太小了

 

 

总结:使用Update By Query要重点关注上面的4个问题,特别是涉及到大批量的修改,特别要关注监控信息(GET _tasks?detailed=true&actions=*byquery

建议要限流,比如:可通过前置mongodb(定时定量去更新)或者更新失败后记录到新的index中后续定时定量去补偿。

 

 

 

 

你可能感兴趣的:(elasticsearch,Elasticsearch)