cardinality 可用于聚合函数,可计算某个字段的基数,即该字段的distinct值,它基于HLL算法来实现的。HHL会先对我们的输入做Hash运算,然后对我们得到的hash结果的bits位做 概率估算,从而得到基数,其特点是:可配置的精度, 用来控制内存的使用。(更精确=更多内存) , 小的数据集精度是非常高的,我们可以通过配置参数,排设置固定的去重内存使用量。无论是数千或数十亿的数据量,内存使用量只与你配置的精度有关。
例如
{
"aggs":{
"cateIds":{
"cardinality":{
"field":"cateId",
"precision_threshold" : 100
}
}
},
"size":0
}
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"hits": {
"total": 515,
"max_score": 0,
"hits": []
},
"aggregations": {
"cateIds": {
"value": 53
}
}
}
cardinality 基数 , 计算的是count(distinct) , 通常会有5%的错误率。
precision_threshold 用来优化准确率和内存开销。
如果precision_threshold 设置为100 100则是预设值, 如果真实值小于100 计算出来的值就是正确的,如果真实值大于100 则计算出的值就是模糊的,100可自定义。
cardinality 算法内存占用量:precision_threshould * 8 byte 内存消耗 , 100*8 = 800 个字节
占用内存很小,而且如果unique value如果在值以内, name可以确保100%准确率
100,数百万的unique value , 错误率在5%以内。
precision_threshould ,值设置越大,占用内存越大, 更能确保更多unique value场景下 100%准确率。
如果precision_threshould 设置了10000 , 分配内存为 10000 * 8 / 1024 -> 80K
2. HyperLogLog++ (HLL) 算法性能优化:
cardinality底层算法优化:HLL算法 , HLL算法的性能。
会对所有的unique value取 hash值, 通过hash值近似去求 distinct count 。
默认情况下发送一个cardinality请求的时候 , 会动态地对所有的field value , 取 hash值 , 我们可以将取hash值的操作,迁移到简历索引的时候,创建索引时,cateId field type 增加创建其hash值索引。
PUT /supplier/
{
"mappings":{
"cat":{
"properties":{
"cateId":{
"type":"text",
"fields":{
"hash":{
"type":"murmur3"
}
}
}
}
}
}
}
{
"aggs":{
"cateIds":{
"cardinality":{
"field":"cateId.hash",
"precision_threshold" : 100
}
}
},
"size":0
}
根据hash值作引进行cartinality metric
参考:https://www.cnblogs.com/richaaaard/p/5319299.html