Elasticsearch cardinality度量误差实测

cardinality度量是一个近似算法。它是基于HyperLogLog++(HLL)算法的。HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。
我们不需要理解技术细节(如果确实感兴趣,可以阅读这篇论文),但我们最好应该关注一下这个算法的特性
可配置的精度,用来控制内存的使用(更精确 = 更多内存)。
小的数据集精度是非常高的。
我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。
要配置精度,我们必须指定precision_threshold参数的值。这个阈值定义了在何种基数水平下我们希望得到一个近乎精确的结果。参考以下示例:
precision_threshold接受 0–40,000 之间的数字,更大的值还是会被当作 40,000 来处理。
示例会确保当字段唯一值在 100 以内时会得到非常准确的结果。尽管算法是无法保证这点的,但如果基数在阈值以下,几乎总是 100% 正确的。高于阈值的基数会开始节省内存而牺牲准确度,同时也会对度量结果带入误差。
对于指定的阈值,HLL 的数据结构会大概使用precision_threshold * 8字节的内存,所以就必须在牺牲内存和获得额外的准确度间做平衡。
在实际应用中,100的阈值可以在唯一值为百万的情况下仍然将误差维持 5% 以内。

上面是官方文档的描述

实际上,我的请求测试,当文档很多的时候,这个误差还是很可观的:
Req

POST /xxx/_search
{
    "size" : 0,
    "aggs" : {
        "distinc_count" : {
            "cardinality" : {
                "field" : "xx.keyword",
                "precision_threshold": 100
            }
        }
    }
}

Resp

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 570470,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "distinc_count": {
      "value": 11158
    }
  }
}

Req

POST /xxx/_search
{
    "size" : 0,
    "aggs" : {
        "distinc_count" : {
            "cardinality" : {
                "field" : "xx.keyword",
                "precision_threshold": 10000
            }
        }
    }
}

Resp

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 570470,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "distinc_count": {
      "value": 10736
    }
  }
}

提高了precision_threshold,得到高的精度估算精度,耗时当然也提高了点(因为之前请求过,所以有缓存,这么低的时延,正常应该几十毫秒)。精度到10000,就基本没误差了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,355评论 19 139
  • 机器学习 经验 数据 数据中产生模型model 的算法 学习算法 learning algorithm 数据集 d...
    时待吾阅读 9,470评论 0 3
  • 缓存的基础知识 1、程序本身具有局部性 时间局部性过去访问到的数据,也有可能被两次访问 空间局部性一个数据被访问到...
    魏镇坪阅读 6,333评论 1 3
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 13,852评论 6 13
  • 谁还记得,当年那轮明月,圆了又缺; 谁能忘记,往日那句永别,呕心沥血。
    丨不是本人阅读 676评论 0 1