ElasticSearch之聚合原理以及精准度分析

写在前面

本文看下es聚合的原理,以及精准度相关的问题。

1:分布式系统近似统计算法

万物都有其内在的规律和限制,如CAP,我们无法设计一个系统同时满足所有的因素,在分布式的计算中也是如此,它也有3个因素:

1:大数据量
2:实时性
3:准确性

以上3个因素,只能满足其中的两个,即如果你需要大数据量下的实时性就会牺牲掉准确性(es),需要大数据量下的准确性就会牺牲掉实时性(Hadoop)
,需要实时性和准确性的话只能牺牲掉大数据量(只能小数据量)。
在这里插入图片描述

本文我们要分析es精准度问题,就属于牺牲掉准确性的场景。

1:metric min是准确的吗?

想要弄清楚metric min是否是存在精准度的问题,需要先来看下min的执行过程,这里我们假定number_of_shard=3 :

1:请求到达coordinate node,coordinate node随机选择三个分片获取min数据
2:每个分片根据本分片的数据计算得到min结果,并将结果发送给coordinate node
3:coordinate node执行min(分片1结果,分片2结果,分片3结果),获取最终的结果

如下图:
在这里插入图片描述
其实可以很容看出来,每个分片返回的min中最小的那个min,肯定是整个数据集的min,所以metric min是准确的。

2:term agg是准确的吗?

想要弄清楚term agg是否是存在精准度的问题,需要先来看下term的执行过程,这里我们假定number_of_shard=3 ,然后获取top 3:

1:请求到达coordinate node,coordinate node随机选择三个分片获取term count数据
2:每个分片,分别对自己的数据,按照term进行分组,并对term count的结果,按照降序排序,并将自己的top 3返回给coordinate node
3:coordinate node收集每个分片的top 3,再对相同的term加在一起,得到总的最终的term count的top 3,作为最终的结果

以上的这个过程是可能有问题的,参考下图:
在这里插入图片描述
错误例子如下:
在这里插入图片描述
最终正确的结果应该是:A(12),B(6),D(6)。这里出错的根本原因是只返回了top 3。es为了表述这里返回的结果是否正确,在返回的结果中增加了doc_count_error_upper_boundsum_other_doc_count,含义如下:

doc_count_error_upper_bound:被遗漏的文档中可能包含的最大的文档数
sum_other_doc_count:没有返回的term的文档的总数

以上的错误例子中,左侧的分片返回的结果是A(6)/B(4)/C(4),因为返回的最小的,所以其可能的最大的未返回文档数是4(最大等于4),同理右侧返回的是A(6)/B(2)/D(3),所以其可能未返回的最大文档数是3,所以例子中的doc_count_error_upper_bound=4+3,sum_other_doc_count就比较简单了,总文档数是(A(6)+B(4)+C(4)+D(3)+A(6)+B(2)+C(1)+D(3)=29),而返回的文档总数是(A(12)+B(6)+C(4)=22),所以
,sum_other_doc_count=29-22=7,如下图:
在这里插入图片描述
es为了解决这个问题,提供了参数shard_size,来设置执行term时从每个分片获取top 几,默认是size*1.5 + 10,通过调大该参数到一定的小可解决问题,另外如果是num_of_shards设置为1也可以解决问题。具体如下图:
在这里插入图片描述
为了加深理解,我们来看一个具体的例子。

2.1:具体实例

数据准备参考这篇文章 。

  • 创建索引
DELETE my_flights
PUT my_flights
{"settings": {"number_of_shards": 20},"mappings" : {"properties" : {"AvgTicketPrice" : {"type" : "float"},"Cancelled" : {"type" : "boolean"},"Carrier" : {"type" : "keyword"},"Dest" : {"type" : "keyword"},"DestAirportID" : {"type" : "keyword"},"DestCityName" : {"type" : "keyword"},"DestCountry" : {"type" : "keyword"},"DestLocation" : {"type" : "geo_point"},"DestRegion" : {"type" : "keyword"},"DestWeather" : {"type" : "keyword"},"DistanceKilometers" : {"type" : "float"},"DistanceMiles" : {"type" : "float"},"FlightDelay" : {"type" : "boolean"},"FlightDelayMin" : {"type" : "integer"},"FlightDelayType" : {"type" : "keyword"},"FlightNum" : {"type" : "keyword"},"FlightTimeHour" : {"type" : "keyword"},"FlightTimeMin" : {"type" : "float"},"Origin" : {"type" : "keyword"},"OriginAirportID" : {"type" : "keyword"},"OriginCityName" : {"type" : "keyword"},"OriginCountry" : {"type" : "keyword"},"OriginLocation" : {"type" : "geo_point"},"OriginRegion" : {"type" : "keyword"},"OriginWeather" : {"type" : "keyword"},"dayOfWeek" : {"type" : "integer"},"timestamp" : {"type" : "date"}}}
}
  • reindex kibana_sample_data_flights数据到创建的索引
POST _reindex
{"source": {"index": "kibana_sample_data_flights"},"dest": {"index": "my_flights"}
}

在这里插入图片描述

  • 查询kibana_sample_data_flights
GET kibana_sample_data_flights/_search
{"size": 0,"aggs": {"weather": {"terms": {"field":"OriginWeather","size":5}}}
}

在这里插入图片描述
可以看到"doc_count_error_upper_bound" : 0说明结果是准确的,这是因为es7默认的主分片数就是1,如下图:
在这里插入图片描述
但是我们创建的索引my_flights设置的主分片数是20,所以如果是基于我们创建的索引来查询doc_count_error_upper_bound的值就大于0了,此时解决就可能是不准确的了(注意是可能准确,也可能是对的,当然如果是该值等于0,则肯定是正确的)

POST my_flights/_search
{"size": 0,"aggs": {"weather": {"terms": {"field":"OriginWeather","size":1,"shard_size": 1}}}
}

在这里插入图片描述
我们来尝试调大shard_size的值,此时doc_count_error_upper_bound的值会越来越小,直到为0:
在这里插入图片描述
另外还可以通过增加参数show_term_doc_count_error:true来查看每个桶的最大可能误差数,但是不提清楚这个数是怎么计算的,如下:
在这里插入图片描述

写在后面

参考文章列表

用Elasticsearch做Terms聚合计算数据不准的问题 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/535510.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot配置达梦数据库依赖(达梦8)

maven配置 <!-- 达梦数据库 --><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.1.193</version></dependency><dependency><groupId>com.alibaba&l…

搞懂HR脑回路,春招Offer送上门!

春天已经来了工作还会远吗&#xff1f; 对准程序员们而言&#xff0c;意味着金主打开大门的春招季要来啦&#xff01; Offer飞来飞去&#xff0c;你会收到心仪的offer吗&#xff1f; 要Get这些大厂Offer不难&#xff0c;但前提是——你得先“懂”HR。所谓“懂”&#xff0c;并不…

性能测试场景分析并设计?超细案例讲解

前言 性能测试场景&#xff0c;其实和功能测试没什么区别&#xff0c;只是侧重点不同。 我们在功能测试中经常用到的等价类边界值等分析和设计测试case的方法&#xff0c;目的是为了尽可能的覆盖业务场景&#xff0c;避免遗漏导致的功能逻辑缺失或者未达到预期。 而在性能测试…

数据分析-Pandas雷达图的多维数据可视化

数据分析-Pandas雷达图的多维数据可视化 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表…

机试:偶数分解

题目描述: 代码示例: #include <bits/stdc.h> using namespace std; int main(){ // 算法思想1:遍历小于该偶数的所有素数,存入数组中,遍历数组找出两个数之和等于偶数的数int n;cout << "输入样例" << endl;cin >> n;int nums[n];int k …

echarts绘制雷达图

<template><div><div>【云端报警风险】</div><div ref"target" class"w-full h-full" stylewidth&#xff1a;200px;height:300px></div></div> </template><script setup> import { ref, onMounte…

MySQL教程-SQL

SQL(Structured Query Language)结构化查询语言&#xff0c;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准。 语法 SQL语句可以单行或多行书写&#xff0c;以;为结束标记SQL可以使用空格或缩进来增强语句的可读性SQL分单行注释(-- 注释内容 或 …

代码随想录 Day41 动态规划(背包问题)

动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是解决背包问题&#xff08;Knapsack Problem&#xff09;的一种常用方法。背包问题可以描述为&#xff1a;给定一组物品&#xff0c;每种物品都有自己的重量和价值&#xff0c;背包的总容量是固定的。我们需…

【强化学习笔记一】初识强化学习(定义、应用、分类、性能指标、小车上山案例及代码)

文章目录 第1章 初识强化学习1.1 强化学习及其关键元素1.2 强化学习的应用1.3 强化学习的分类1.3.1 按任务分类1.3.2 按算法分类 1.4 强化学习算法的性能指标1.5 案例&#xff1a;基于Gym库的智能体/环境接口1.5.1 安装Gym库1.5.2 使用Gym库1.5.3 小车上山1.5.3.1 有限动作空间…

12双体系Java学习之局部变量和作用域

局部变量 局部变量的作用域 参数变量

武汉凯迪正大—方波冲击电流试验设备

KDYZ-FB方波冲击电流试验设备是依据交流无间隙氧化锌避雷器有关试验标准设计的一种用于系统额定电压在10KV以下各等级避雷器以及氧化锌电阻片小电流残压/泄漏电流测试的仪表,它对于避雷器及氧化锌电阻片生产厂、电力系统的避雷器及氧化锌电阻片性能检测。 氧化锌避雷器生产常用…

【网络安全|信息安全】OA综合利用工具

-Wanna-Get-All简介 基于Apt-T00ls二次开发工具&#xff0c;I Wanna Get All 安全工具, 严禁一切未授权漏洞扫描攻击 GitHub 地址&#xff1a;https://github.com/R4gd0ll/I-Wanna-Get-All 界面显示效果 注意&#xff1a;&#xff08;工具仅供以安全为目的的学习交流使用&am…