一、聚合操作内部原理
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个