49.ardinality算法之优化内存开销以及HLL算法

主要知识点

  • precision_threshold参数的理解
  • HLL算法优化(hash)

   

   

cardinalitycount(distinct)5%的错误率,性能在100ms左右

   

一、precision_threshold

优化准确率和内存开销

   

GET /tvs/sales/_search

{

"size" : 0,

"aggs" : {

"distinct_brand" : {

"cardinality" : {

"field" : "brand",

"precision_threshold" : 100

}

}

}

}

   

"precision_threshold":100 表示如果brand在100个之内,就是几乎保证100%准确。

cardinality算法,会占用precision_threshold * 8 byte 内存消耗,即是:

100 * 8 = 800个字节。precision_threshold的值设置的越大,占用内存越大,但可以确保更多unique value的场景下100%准确。官方统计,对于100万元的数据量,precision_threshold人值设为100的话,错误率不超过5%。所以要在精准度和内存占用中找到一个平衡点。

   

二、HyperLogLog++ (HLL)算法性能优化

   

cardinality底层算法用的是HLL算法。HLL算法会对所有的uniue valuehash值,通过hash值近似去求distcint count,误差较小,默认情况下,发送一个cardinality请求的时候,会动态地对所有的field value,然后再取这些field value 的 hash; HLL算法优化的方法就是将取hash值的操作,前移到建立索引的时候,也就是在建立索引时就建立好hash这个索引,这样在搜索时就不用再建立hash,而是直接以hash值进行搜索。

   

在建立索引时就建立hash:

   

PUT /tvs2/

{

"mappings": {

"sales": {

"properties": {

"brand":{

"type": "text",

"fields": {"hash":{"type": "murmur3"}}}

}

}

}

}

   

进行搜索时:

GET /tvs/sales/_search

{

"size" : 0,

"aggs" : {

"distinct_brand" : {

"cardinality" : {

"field" : "brand.hash",

"precision_threshold" : 100

}

}

}

}

原文地址:https://www.cnblogs.com/liuqianli/p/8535902.html