zoukankan      html  css  js  c++  java
  • Elasticsearch学习之深入聚合分析四---案例实战

    1. 需求:比如有一个网站,记录下了每次请求的访问的耗时,需要统计tp50,tp90,tp99

    tp50:50%的请求的耗时最长在多长时间
    tp90:90%的请求的耗时最长在多长时间
    tp99:99%的请求的耗时最长在多长时间

    PUT /website
    {
        "mappings": {
            "logs": {
                "properties": {
                    "latency": {
                        "type": "long"
                    },
                    "province": {
                        "type": "keyword"
                    },
                    "timestamp": {
                        "type": "date"
                    }
                }
            }
        }
    }
    
    POST /website/logs/_bulk
    { "index": {}}
    { "latency" : 105, "province" : "江苏", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 83, "province" : "江苏", "timestamp" : "2016-10-29" }
    { "index": {}}
    { "latency" : 92, "province" : "江苏", "timestamp" : "2016-10-29" }
    { "index": {}}
    { "latency" : 112, "province" : "江苏", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 68, "province" : "江苏", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 76, "province" : "江苏", "timestamp" : "2016-10-29" }
    { "index": {}}
    { "latency" : 101, "province" : "新疆", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 275, "province" : "新疆", "timestamp" : "2016-10-29" }
    { "index": {}}
    { "latency" : 166, "province" : "新疆", "timestamp" : "2016-10-29" }
    { "index": {}}
    { "latency" : 654, "province" : "新疆", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 389, "province" : "新疆", "timestamp" : "2016-10-28" }
    { "index": {}}
    { "latency" : 302, "province" : "新疆", "timestamp" : "2016-10-29" }
    创建索引并添加数据

    可以采用pencentiles语法,示例:

    GET /website/logs/_search 
    {
      "size": 0,
      "aggs": {
        "latency_percentiles": {
          "percentiles": {
            "field": "latency",
            "percents": [
              50,
              95,
              99
            ]
          }
        },
        "latency_avg": {
          "avg": {
            "field": "latency"
          }
        }
      }
    }

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

    我们的网站的提供的访问延时的SLA,确保所有的请求100%,都必须在200ms以内,大公司内,一般都是要求100%在200ms以内

    如果超过1s,则需要升级到A级故障,代表网站的访问性能和用户体验急剧下降

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

    这个percentile ranks,其实比pencentile还要常用,例如,可以按照品牌分组,计算,电视机,售价在1000占比,2000占比,3000占比

    GET /website/logs/_search 
    {
      "size": 0,
      "aggs": {
        "group_by_province": {
          "terms": {
            "field": "province"
          },
          "aggs": {
            "latency_percentile_ranks": {
              "percentile_ranks": {
                "field": "latency",
                "values": [
                  200,
                  1000
                ]
              }
            }
          }
        }
      }
    }

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

    compression,可以限制节点数量,最多 compression * 20 = 2000个node去计算

    默认 100 ,数量越大占用内存越多,但是结果越精准,性能越差,一个节点占用32字节,100 * 20 * 32 = 64KB,如果想要percentile算法越精准,compression可以设置的越大

    3. 聚合分析的内部原理

      采用倒排索引+正排索引(doc value)实现,在PUT/POST的时候,就会生成doc value数据,也就是正排索引,正排索引也会写入磁盘文件中,然后os cache先进行缓存,以提升访问doc value正排索引的性能,如果os cache内存大小不足够放得下整个正排索引,就会将doc value的数据写入磁盘文件中,es官方是建议,es大量是基于os cache来进行缓存和提升性能的,不建议用jvm内存来进行缓存,那样会导致一定的gc开销和oom问题给jvm更少的内存,给os cache更大的内存64g服务器,给jvm最多16g,几十个g的内存给os cache,os cache可以提升doc value和倒排索引的缓存和查询效率

    4.对分析的字段进行聚合

      对分词的field,直接执行聚合操作,会报错,大概意思是说,你必须要打开fielddata,然后将正排索引数据加载到内存中,才可以对分词的field执行聚合操作,而且会消耗很大的内存

    POST /test_index/_mapping/test_type 
    {
      "properties": {
        "test_field": {
          "type": "text",
          "fielddata": true
        }
      }
    }

    如果要对分词的field执行聚合操作,必须将fielddata设置为true

    5. 分词field+fielddata的工作原理

      对不分词的所有field,可以执行聚合操作,如果你的某个field不分词,那么在index-time,就会自动生成doc value,所以针对这些不分词的field执行聚合操作的时候,自动就会用doc value来执行,但是分词的field是没有doc value的,在index-time,如果某个field是分词的,那么是不会给它建立doc value正排索引的,因为分词后,占用的空间过于大,所以默认是不支持分词field进行聚合的,正因为分词field默认没有doc value,所以直接对分词field执行聚合操作,是会报错的

      对于分词field,必须打开和使用fielddata,完全存在于纯内存中,结构和doc value类似,如果是ngram或者是大量term,那么必将占用大量的内存,如果一定要对分词的field执行聚合,那么必须将fielddata=true,然后es就会在执行聚合操作的时候,现场将field对应的数据,建立一份fielddata正排索引,fielddata正排索引的结构跟doc value是类似的,但是只会讲fielddata正排索引加载到内存中来,然后基于内存中的fielddata正排索引执行分词field的聚合操作

      为什么fielddata必须在内存?因为分词的字符串按照term进行聚合,需要执行更加复杂的算法和操作,如果基于磁盘和os cache,那么性能会很差

  • 相关阅读:
    OLAP ODS项目的总结 平台选型,架构确定
    ORACLE ORA12520
    ORACLE管道函数
    ORACLE RAC JDBC 配置
    ORACLE RAC OCFS连接产生的错误
    ORACLE 启动和关闭详解
    OLAP ODS项目的总结 起步阶段
    ORACLE RAC 配置更改IP
    ORACLE RAC OCR cann't Access
    ORACLE RAC Debug 之路 CRS0184错误与CRS初始化
  • 原文地址:https://www.cnblogs.com/sunfie/p/7101749.html
Copyright © 2011-2022 走看看