距离上一次更新该文章已经过了 719 天,文章所描述的內容可能已经发生变化,请留意。
参考:
https://alexmarquardt.com/2020/10/21/elasticsearch-too-many-script-compilations/
https://github.com/elastic/beats/issues/9600
定位问题
a.字面意思是,ElasticSearch5分钟内执行脚本编译超过75个,编译太多而拒绝编译。编译是非常耗时的,这是ES的自我保护功能。
b.我的操作是希望实现先以索引位置正序排序,再以长度排序, 最后再进行普通排序. 排序使用的脚本 如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| "sort": [ { "_script": { "type": "number", "script": { "source": """def val = doc['字段名'].value; int slashIndex = val.indexOf('值'); return slashIndex; """ }, "order": "asc" } }, { "_script": { "type": "number", "script": { "source": "doc['字段名'].value.length()" }, "order": "asc" } }, { "字段名": { "order": "asc" } } ]
|
临时解决办法(配置每5分钟500)
从 7.9 开始默认启用上下文。但是,如果当前未启用上下文(出于某种原因),则可以使用以下命令启用它们
1 2 3 4 5 6
| PUT _cluster/settings { "transient": { "script.max_compilations_rate": "use-context" } }
|
如果使用了上下文,可以使用以下命令查看
1
| GET /_nodes/stats?filter_path=nodes.*.script_cache.contexts
|
transient参数只会持续到es重新启动
1 2 3 4 5 6
| PUT _cluster/settings { "transient": { "script.context.number_sort.max_compilations_rate": "500/5m" } }
|
persistent(持久)大多数用例可能此参数是首选
1 2 3 4 5 6 7
| PUT _cluster/settings { "persistent": { "script.context.number_sort.max_compilations_rate": "500/5m" } }
|
检查
解决办法
max_compilations_rate参数不宜设置过大, 脚本编译是极其吃资源的一个操作
7.10.4源码

所以我们可以将脚本参数写进params里, 以避免重复编译, 如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| "sort": [ { "_script": { "type": "number", "script": { "params": { "field": "字段名", "val": "值" }, "source": """def val = doc[params.field].value; int slashIndex = val.indexOf(params.val); return slashIndex; """ }, "order": "asc" } }, { "_script": { "type": "number", "script": { "params": { "field": "字段名" }, "source": "doc[params.field].value.length()" }, "order": "asc" } }, { "字段名": { "order": "asc" } } ]
|