ElasticSearch系列七:深入ES聚合数据分析

一、聚合操作内部原理

1.正排索引(doc value)的聚合内部原理
①index-time生成
PUT/POST的时候,就会生成doc value数据,也就是正排索引
②核心原理与倒排索引类似
正排索引,也会写入磁盘文件中,然后os cache先进行缓存,以提升访问doc value正排索引的性能
如果os cache内存大小不足够放得下整个正排索引,doc value,就会将doc value的数据写入磁盘文件中
③性能问题:给jvm更少的内存,给os cache更大的内存
④如果的确不需要doc value,比如聚合等操作,那么可以禁用,减少磁盘空间占用
PUT my_index
{
  "mappings": {
"my_type": {
 "properties": {
"my_field": {
 "type":       "keyword"
 "doc_values": false 
}
 }
}
  }
}
⑤如果要对分词的field执行聚合操作,必须将fielddata设置为true
POST /test_index/_mapping/test_type 
{
  "properties": {
"test_field": {
 "type": "text",
 "fielddata": true
}
  }
}

二、易并行聚合算法:比如max

1.近似聚合算法 :采用在每个node上进行近估计的方式,得到最终的结论
如果采取近似估计的算法:延时在100ms左右,0.5%错误
如果采取100%精准的算法:延时一般在5s~几十s,甚至几十分钟,几小时,0%错误
2.三角选择原则 :精准+实时+大数据 --> 选择2个
a.精准+实时: 没有大数据,数据量很小,那么一般就是单击跑,随便你则么玩儿就可以
b.精准+大数据:hadoop,批处理,非实时,可以处理海量数据,保证精准,可能会跑几个小时
c. 大数据+实时 :es,不精准,近似估计,可能会有百分之几的错误率

三、cardinality去重算法

cartinality metric,对每个bucket中的指定的field进行去重,取去重后的count,类似于count(distcint)
cardinality,count(distinct),5%的错误率,性能在100ms左右
cardinality算法,会占用precision_threshold * 8 byte 内存消耗,100 * 8 = 800个字节
HyperLogLog++ (HLL)算法性能优化
例:GET /tvs/sales/_search
{
 "size" : 0,
 "aggs" : {
 "months" : {
"date_histogram": {
 "field": "sold_date",
 "interval": "month"
},
"aggs": {
 "distinct_colors" : {
 "cardinality" : {
"field" : "brand"
 }
 }
}
 }
 }
}

四、需求实战:记录下每次请求的访问的耗时,需要统计tp50,tp90,tp99

a.percentiles百分比算法
例:比如有一个网站,记录下了每次请求的访问的耗时,需要统计tp50,tp90,tp99
GET /website/logs/_search 
{
 "size": 0,
 "aggs": {
"group_by_province": {
 "terms": {
"field": "province"
 },
 "aggs": {
"latency_percentiles": {
 "percentiles": {
"field": "latency",
"percents": [
 50,
 95,
 99
]
 }
},
"latency_avg": {
 "avg": {
"field": "latency"
 }
}
 }
}
 }
}
b.percentile ranks和网站访问时延SLA统计
例:在200ms以内的,有百分之多少,在1000毫秒以内的有百分之多少
GET /website/logs/_search 
{
 "size": 0,
 "aggs": {
"group_by_province": {
 "terms": {
"field": "province"
 },
 "aggs": {
"latency_percentile_ranks": {
 "percentile_ranks": {
"field": "latency",
"values": [
 200,
 1000
]
 }
}
 }
}
 }
}
c.percentile的优化:
TDigest算法:用很多节点来执行百分比的计算,近似估计,有误差,节点越多,越精准
compression:默认100,限制节点数量最多 compression * 20 = 2000个node去计算,越大,占用内存越多,越精准,性能越差,一个节点占用32字节,100 * 20 * 32 = 64KB,如果你想要percentile算法越精准,compression可以设置的越大

五、海量bucket优化机制:从深度优先到广度优先

例:对于评论数量排名前10的演员,每个演员的电影取到评论数量排名前5的电影
{
 "aggs" : {
"actors" : {
 "terms" : {
"field" :        "actors",
"size" :         10,
"collect_mode" : "breadth_first" 
 },
 "aggs" : {
"costars" : {
 "terms" : {
"field" : "films",
"size" :  5
 }
}
 }
}
}
}

深度优先的方式,构建了一整颗完整的树出来了,10万个actor,每个actor平均有10部电影,10万 + 100万 --> 110万的数据量的一颗树。构建了大量的数据,然后裁剪掉了99.99%的数据。
广度优先的方式,构建出film,裁剪出其中的5个film即可,10万 -> 50个

你可能感兴趣的:(Elasticsearch)