ES通过抽样agg聚合性能提升3-5倍

2023-12-03 02:20
文章标签 es 性能 提升 agg 聚合 抽样

本文主要是介绍ES通过抽样agg聚合性能提升3-5倍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一直以来,es的agg聚合分析性能都比较差(对应sql的 group by)。特别是在超多数据中做聚合,在搜索的条件命中特别多结果的情况下,聚合分析会非常非常的慢。
一个聚合条件:聚合分析请求的时间 = search time + agg time
N个聚合条件:聚合分析请求的时间 = search time + agg time * N
搜索的数据范围越大,聚合请求时间越长。
搜索条件命中的数据越多,聚合请求的时间越长。
搜索的字段,不一样的值越多,聚合请求时间越长。例如性别字段,通常仅有3个取值(男、女、未知),这种属于取值少的。像邮箱字段,值非常多,上亿个。这种就属于高基数字段。同样的搜索条件,高基数字段的聚合耗时会多非常多!
聚合请求时候非常吃cpu 和io资源的。通常在大数据检索场景下,很难支持高并发的聚合。并发上去以后,先是CPU飙升,再是IO飙升,随之load很高很高。其根本原因,从agg聚合的源码来看。因为聚合请求分为两个阶段,先根据条件查询数据。然后将命中的全部数据,放在内存中做计算。在第二个过程中,因为将所有命中的数据全部取回来,然后做计算,就涉及到了非常多的小文件的IO。IO会蹭蹭蹭的飙升。
就目前而言,在不改源码的情况下,聚合性能很难有很大的突破。本篇文章,通过抽样的思路,通过抽取分片,相当于数据剪枝的方式,来节省资源消耗。提升聚合分析性能,提升大概在3-5倍。随着数据越多,分片越多,资源越少,性能提升效果越明显。
我个人是做万亿级内容数据检索的。负责搜索集群,负责搜索优化。聚合分析性能优化,我应该说已经看了全网关于优化的文章。在实际数据体量非常大的前提下,实际效果不是太明显。
其中比较好的有这几篇文章。
es官方博文
Improving the performance of high-cardinality terms aggregations in Elasticsearch | Elastic Blog
Elasticsearch 聚合性能优化六大猛招-腾讯云开发者社区-腾讯云
Elasticsearch聚合优化 | 聚合速度提升5倍_es聚合速度-CSDN博客

抽样聚合方案

1.es原生抽样聚合

官方提供的采样聚合

参考文档:Sampler aggregation | Elasticsearch Guide [7.11] | Elastic

        ES中的抽样聚合,意思是只对高质量的数据做聚合。比如,指定搜索条件,该搜索条件命中的数据为100W,对这100W数据,根据相关性分数排序。然后对这topK的数据做聚,比如每个shard上取200条评分最高的数据,去聚合。这就是ES sampler aggregation的含义。

2.es pre-filter机制

参考文档:Elasticsearch的search之_shards skipped之谜_布道的博客-CSDN博客__shards skipped

3.es在检索过程中指定分片

GET index_name/_search?preference=_shards:0

        抽样抽分片的思路,只每次固定只检测其中一个分片。例如我们的索引一共300G,每个分片30G,一共有10个分片。在检索的过程中,只对其中一个分片做检索和聚合。其最终的聚合结果,根据我们的测试来看,效果还是非常不错的。聚合结果的分布情况和本来的terms聚合相差不大。性能也能提升个几倍。注意这种方式,聚合结果是近似的,并不是完全准确的(ES本身的聚合解结果就不是100%精准的)。

        在大数据随机分布的情况下。在搜索命中大量数据情况下,其结果分布也是满足正态分布的。注意在搜索结果命中的结果集越多,其结果越符合正态分布,其聚合结果越接近标准值(原生terms聚合)。这里有一个值,一个经验值,在搜索提交条件命中大于10000的时候,可以用抽样,结果偏差不大。

        注意,这里具体抽哪一个分片是有说法的。我们要考虑一个问题,同一个搜索条件,聚合结果应该是一致的。这里可以将搜索条件进行md5,然后取hash值,然后将hash值模上分片总数。这里只是一个思路。

ES官方的抽样聚合说明

抽样方案对比测试

对比测试了三种聚合分析的方式,其中包含了termssampler terms、和shard抽样(假如有10个shard,只对其中一个shard做搜索)

先说测试结论

官方的抽样,召回的结果和标准结果偏差较大。

官方的抽样,时间花费上,并没有太大的提升。

抽取分片,召回的结果和标准结果偏差不大。

抽取分片,时间花费上,性能提升3-5倍。资源花费为分片总数分之一。

响应时间对比如下

检索范围

检索条件

查询语法

响应时间

备注

major_index_202303

北京 AND 暴雨

terms

4561

7694

shard抽样

1423

2785

效果最好

terms sampler

5650

3663

效果没有太明显

召回结果对比如下

关键词

terms(结果)

抽取一个分片

sampler terms(抽样200)

备注

地区

4224

446

2094

中国

3772

375

-

发展

3605

342

-

天气

3503

378

1942

部分

2781

294

1525

大雨

2395

236

-

暴雨

2394

264

2454

气温

2079

212

915

局地

1851

199

1055

工作

1741

187

-

降雨

-

-

1111

北京

-

-

827

巴西

-

-

801

灾害

-

-

801

检索语句

 这里使用的是query_string 检索语法。对比标准的terms聚合,官方的simple抽样,和抽分片。

  "query": {"query_string": {"query": """北京 AND 暴雨""","fields": ["content^1.0","title^1.0"],"type": "phrase","tie_breaker": 1,"default_operator": "and","max_determinized_states": 10000,"enable_position_increments": true,"fuzziness": "AUTO","fuzzy_prefix_length": 0,"fuzzy_max_expansions": 50,"phrase_slop": 0,"escape": false,"auto_generate_synonyms_phrase_query": true,"fuzzy_transpositions": true,"boost": 1}}

全部测试结果原始数据

搜索范围

搜索条件

聚合方式

耗时情况ms

返回结果 

major_info_202303

北京 AND 暴雨

terms

4561

7694

[

        {

          "key" : "地区",

          "doc_count" : 4224

        },

        {

          "key" : "中国",

          "doc_count" : 3772

        },

        {

          "key" : "发展",

          "doc_count" : 3605

        },

        {

          "key" : "天气",

          "doc_count" : 3503

        },

        {

          "key" : "部分",

          "doc_count" : 2781

        },

        {

          "key" : "大雨",

          "doc_count" : 2395

        },

        {

          "key" : "暴雨",

          "doc_count" : 2394

        },

        {

          "key" : "气温",

          "doc_count" : 2079

        },

        {

          "key" : "局地",

          "doc_count" : 1851

        },

        {

          "key" : "工作",

          "doc_count" : 1741

        }

      ]

terms

sampler

5650

3663

[

          {

            "key" : "暴雨",

            "doc_count" : 2454

          },

          {

            "key" : "地区",

            "doc_count" : 2094

          },

          {

            "key" : "天气",

            "doc_count" : 1942

          },

          {

            "key" : "部分",

            "doc_count" : 1525

          },

          {

            "key" : "降雨",

            "doc_count" : 1111

          },

          {

            "key" : "局地",

            "doc_count" : 1055

          },

          {

            "key" : "气温",

            "doc_count" : 915

          },

          {

            "key" : "北京",

            "doc_count" : 827

          },

          {

            "key" : "巴西",

            "doc_count" : 801

          },

          {

            "key" : "灾害",

            "doc_count" : 801

          }

        ]

terms

+

指定shard

1423

2785

[

        {

          "key" : "地区",

          "doc_count" : 446

        },

        {

          "key" : "天气",

          "doc_count" : 378

        },

        {

          "key" : "中国",

          "doc_count" : 375

        },

        {

          "key" : "发展",

          "doc_count" : 342

        },

        {

          "key" : "部分",

          "doc_count" : 294

        },

        {

          "key" : "暴雨",

          "doc_count" : 264

        },

        {

          "key" : "大雨",

          "doc_count" : 236

        },

        {

          "key" : "气温",

          "doc_count" : 212

        },

        {

          "key" : "局地",

          "doc_count" : 199

        },

        {

          "key" : "工作",

          "doc_count" : 187

        }

      ]

这篇关于ES通过抽样agg聚合性能提升3-5倍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/447726

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

java学习,进阶,提升

http://how2j.cn/k/hutool/hutool-brief/1930.html?p=73689

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr

SQL2005 性能监视器计数器错误解决方法

【系统环境】 windows 2003 +sql2005 【问题状况】 用户在不正当删除SQL2005后会造成SQL2005 性能监视器计数器错误,如下图 【解决办法】 1、在 “开始” --> “运行”中输入 regedit,开启注册表编辑器,定位到 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVer