行业知识
elasticsearch7.17 terms聚合性能提升90%+
背景
ES7 ���比于 ES6 有多个层面的优化,对于开源的ES而言,升级是必经之路。
ES的使用场景非常多,在升级过程中可能会遇到非预期的结果;
比如之前文章提到的典型案例:ES7.17版本terms查询性能问题
ES7.17版本terms查询性能问题_es terms查询慢 profile-CSDN博客
接下来再分析一个升级之后聚合性能下降的case;
场景
1. 按照标准最佳实践进行改造(分片控制在20G左右,term/terms查询使用keyword类型...)
2. 集群从ES6.8.5 升级到 ES7.17.5
3. 异常:升级后性能骤降
avg 100ms -> 400ms
特定聚合查询 400ms -> 1500ms
4. 通过 profile ,以及实际测试,耗时主要是在聚合
分析
1. 性能下降,随之而来的还有CPU升高
2. 通过 arthas 工具采集火焰图
可以看到和global_ordinals全局序数相关;(查询/聚合时临时构建全局序数)
3. 针对全局序数,一般是2种优化手段
方案一:不使用序数 "execution_hint": "map"
注:只有在聚合时基数较小的情况下适用,否则容易OOM;(即字段整体数据基数较小;或者聚合时需要带有查询条件,查询条件筛选后用于聚合的字段数据基数比较小)
"aggregations": { "agg_count": { "terms": { "field": "xxxxID", "execution_hint": "map", "size": 2, "min_doc_count": 1, "shard_min_doc_count": 0, "show_term_doc_count_error": false, "order": [ { "_key": "asc" } ] } } } 方案二:在查询之前提前创建好全局序数 "eager_global_ordinals": true,将全局序数的构建转移到索引(写数据)阶段,保证查询的效率
PUT xxxx/_mapping{ "properties": { "xxxxxID":{ "type": "keyword", "eager_global_ordinals": true } }} 结论
1. 使用方案一,"execution_hint": "map",性能大幅提升
1600ms -> 10ms (没有pageCache时候是40ms左右)
注:POST xxxx/_cache/clear 只能清理ES本身的缓存,无法清理pageCache
然后check一下terms聚合使用的字段的基数
POST xxxxx/_search{ "query": { "match_all": {} }, "size": 0, "aggs": { "count_aggs": { "cardinality": { "field": "xxxxID" } } }} 整个索引,该字段的基数为 8kw,如果聚合不带任何条件就会消耗大量内存;
如果聚合都带查询条件,那么该方案适用,并且性能提升 90%+;
2. 方案二需要重建索引,理论查询性能也会大幅提升,此处暂无测试数据
PUT xxxx/_mapping{ "properties": { "xxxxxID":{ "type": "keyword", "eager_global_ordinals": true } }}
上一篇:服务器消失了怎么恢复正常?
下一篇:怎么创造飞行服务器?