Elasticsearch进阶笔记第二十五篇

298 阅读4分钟

Elasticsearch高手进阶篇(51)

深入聚合数据分析_percentiles rank以及网站访问时延SLA统计

  • SLA:就是你提供的服务的标准

    • 我们的网站的提供的访问延时的SLA,确保所有的请求100%,都必须在200ms以内,大公司内,一般都是要求100%在200ms以内
    • 如果超过1s,则需要升级到A级故障,代表网站的访问性能和用户体验急剧下降

需求:在200ms以内的,有百分之多少,在1000毫秒以内的有百分之多少,percentile ranks metric

这个percentile ranks,其实比pencentile还要常用

按照品牌分组,计算,电视机,售价在1000占比,2000占比,3000占比

 GET /waws_website/waws_logs/_search 
 {
   "size": 0,
   "aggs": {
     "group_by_province": {
       "terms": {
         "field": "province"
       },
       "aggs": {
         "latency_percentile_ranks": {
           "percentile_ranks": {
             "field": "latency",
             "values": [
               200,
               1000
             ]
           }
         }
       }
     }
   }
 }
 
 {
   "took": 2,
   "timed_out": false,
   "_shards": {
     "total": 5,
     "successful": 5,
     "failed": 0
   },
   "hits": {
     "total": 12,
     "max_score": 0,
     "hits": []
   },
   "aggregations": {
     "group_by_province": {
       "doc_count_error_upper_bound": 0,
       "sum_other_doc_count": 0,
       "buckets": [
         {
           "key": "新疆",
           "doc_count": 6,
           "latency_percentile_ranks": {
             "values": {
               "200.0": 29.40613026819923,
               "1000.0": 100
             }
           }
         },
         {
           "key": "江苏",
           "doc_count": 6,
           "latency_percentile_ranks": {
             "values": {
               "200.0": 100,
               "1000.0": 100
             }
           }
         }
       ]
     }
   }
 }
  • percentile的优化

    • TDigest算法,用很多节点来执行百分比的计算,近似估计,有误差,节点越多,越精准
  • compression

    • 限制节点数量最多 compression * 20 = 2000个node去计算
    • 默认100
    • 越大,占用内存越多,越精准,性能越差
    • 一个节点占用32字节,100 * 20 * 32 = 64KB
    • 如果你想要percentile算法越精准,compression可以设置的越大

Elasticsearch高手进阶篇(52)

深入聚合数据分析_基于doc value正排索引的聚合内部原理

聚合内部原理

  • 聚合分析的内部原理是什么

    • aggs,term,metric avg max,执行一个聚合操作的时候,内部原理是怎样的呢?用了什么样的数据结构去执行聚合?是不是用的倒排索引?
  • 搜索+聚合,写个示例

 GET /waws_index/waws_type/_search 
 {
     "query": {
         "match": {
             "search_field": "test"
         }
     },
     "aggs": {
         "group_by_agg_field": {
             "terms": {
                 "field": "agg_field"
             }
         }
     }
 }
  • 纯用倒排索引来实现的弊端

    • es肯定不是纯用倒排索引来实现聚合+搜索的

search_field

  • doc1: hello world test1, test2
  • doc2: hello test
  • doc3: world test

倒排索引

  • hello doc1,doc2
  • world doc1,doc3
  • test1 doc1
  • test2 doc1
  • test doc2,doc3
 "query": {
     "match": {
         "search_field": "test"
     }
 }

test --> doc2,doc3 --> search result, doc2,doc3

分析

自我理解:

  • 只有倒排索引不能解决agg聚合的原因

    • 当我们只有倒排索引的时候,我们有一个agg_field字段,我们需要知道agg_field的值一共有两个field1和field2,这个时候我们需要聚合计算,以field1进行分组,就需要遍历所有的倒排索引,看看这个倒排索引是不是field1,最后将所有的agg_field的字段的集合。
    • 我们有多少的agg_field的字段,我们就会遍历多少遍的倒排索引,比较浪费时间
  • 倒排索引+正排索引(doc value)的原理和优势

    • 我们使用正排索引也就是使用doc去索引原始field的过程,我们可以直接通过doc去索引单词,速度会更快一些(但是感觉还是要遍历整个文档才知道,不知道快在哪?在查查看)
讲解部分
  • agg_field

    • doc2: agg1
    • doc3: agg2
    • 100万个值 ... ... ...
  • 倒排

    • agg1 doc2
    • agg2 doc3
  • doc2, doc3, search result --> 实际上,要搜索到doc2的agg_field的值是多少,doc3的agg_field的值是多少
  • doc2和doc3的agg_field的值之后,就可以根据值进行分组,实现terms bucket操作
  • doc2的agg_field的值是多少,这个时候,如果你手上只有一个倒排索引,你该怎么办???你要扫描整个倒排索引,去一个一个的搜,拿到每个值,比如说agg1,看一下,它是不是doc2的值,拿到agg2,看一下,是不是doc2的值,直到找到doc2的agg_field的值,在倒排索引中

  • 搜索和聚合的区别

    • 如果用纯倒排索引去实现聚合,性能是很低下的,搜索,search,搜倒排索引,搜那个term,就结束了;聚合,搜索出了1万个doc,每个doc都要在倒排索引中搜索出它的那个聚合field的值
倒排索引+正排索引(doc value)的原理和优势

doc value:正排索引

  • search_field

    • doc1: hello world test1, test2
    • doc2: hello test
    • doc3: world test
  • 倒排索引

    • hello doc1,doc2
    • world doc1,doc3
    • test1 doc1
    • test2 doc1
    • test doc2,doc3
 "query": {
     "match": {
         "search_field": "test"
     }
 }

test --> doc2,doc3 --> search result, doc2,doc3

doc value数据结构,正排索引

100万个 doc2: agg1 doc3: agg2

倒排索引的话,必须遍历完整个倒排索引才可以

  • 因为可能你要聚合的那个field的值,是分词的,比如说hello world my name --> 一个doc的聚合field的值可能在倒排索引中对应多个value
  • 所以说,当你在倒排索引中找到一个值,发现它是属于某个doc的时候,还不能停,必须遍历完整个倒排索引,才能说确保找到了每个doc对应的所有terms,然后进行分组聚合

... ... ... 100万个

doc2: agg1 hello world

doc3: agg2 test hello

我们有没有必要搜索完整个正排索引啊,1万个doc --> 搜 -> 可能跟搜索到15000次,就搜索完了,就找到了1万个doc的聚合field的所有值了,然后就可以执行分组聚合操作了