主要知识点
- precision_threshold参数的理解
- HLL算法优化(hash)
cardinality,count(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 value取hash值,通过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
}
}
}
}