elasticsearch 聚合(三)过滤之百分比-近似聚合

妈呀终于计算完了,经过一系列现实的搏击。练就一身的奇淫巧技。接下来去家大公司网站计算一下百分比。数据准备,这里我用的是官方的数据

DELETE  website
PUT /website
{
  "mappings": {
    "properties": {
      "latency": {
        "type": "long"
      },
      "zone": {
        "type": "keyword"
      },
      "timestamp": {
        "type": "date"
      }
    }
  }
}

POST /website/_bulk
{ "index": {}}
{ "latency" : 100, "zone" : "US", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 80, "zone" : "US", "timestamp" : "2014-10-29" }
{ "index": {}}
{ "latency" : 99, "zone" : "US", "timestamp" : "2014-10-29" }
{ "index": {}}
{ "latency" : 102, "zone" : "US", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 75, "zone" : "US", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 82, "zone" : "US", "timestamp" : "2014-10-29" }
{ "index": {}}
{ "latency" : 100, "zone" : "EU", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 280, "zone" : "EU", "timestamp" : "2014-10-29" }
{ "index": {}}
{ "latency" : 155, "zone" : "EU", "timestamp" : "2014-10-29" }
{ "index": {}}
{ "latency" : 623, "zone" : "EU", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 380, "zone" : "EU", "timestamp" : "2014-10-28" }
{ "index": {}}
{ "latency" : 319, "zone" : "EU", "timestamp" : "2014-10-29" }

1 百分位度量 percentiles

#query
{
    "size" : 0,
    "aggs" : {
        "load_times" : {
            "percentiles" : {
                "field" : "latency" 
            }
        },
        "avg_load_time" : {
            "avg" : {
                "field" : "latency" 
            }
        }
    }
}
#result
"aggregations" : {
    "load_times" : {
      "values" : { #默认返回[1, 5, 25, 50, 75, 95, 99]
        "1.0" : 75.0,
        "5.0" : 75.5,
        "25.0" : 90.5,
        "50.0" : 101.0,# 50的请求在100ms左右
        "75.0" : 299.5,
        "95.0" : 598.6999999999997,
        "99.0" : 623.0
      }
    },
    "avg_load_time" : {
      "value" : 199.58333333333334
    }
  }

  #query 看下是否跟数据中心的地理区域有关
  {
  "size": 0,
  "aggs": {
    "zones": {
      "terms": {
        "field": "zone" #首先根据区域我们将延时分到不同的桶中
      },
      "aggs": {
        "load_times": {
          "percentiles": { #再计算每个区域的百分位数值。
            "field": "latency"
          }
        },
        "avg_load_time": {
          "avg": {
            "field": "latency"
          }
        }
      }
    }
  }
}

#result
       "buckets" : [
        {
          "key" : "EU",
          "doc_count" : 6,
          "load_times" : {
            "values" : {
              "50.0" : 299.5,
              "95.0" : 623.0,
              "99.0" : 623.0
            }
          },
          "avg_load_time" : {
            "value" : 309.5
          }
        },
        {
          "key" : "US",
          "doc_count" : 6,
          "load_times" : {
            "values" : {
              "50.0" : 90.5,
              "95.0" : 102.0,
              "99.0" : 102.0
            }
          },
          "avg_load_time" : {
            "value" : 89.66666666666667
          }
        }
      ]

在响应结果中,我们发现欧洲区域(EU)要比美国区域(US)慢很多,在美国区域(US),50 百分位与 99 百分位十分接近,它们都接近均值。
与之形成对比的是,欧洲区域(EU)在 50 和 99 百分位有较大区分。现在,显然可以发现是欧洲区域(EU)拉低了延时的统计信息,我们知道欧洲区域的 50% 延时都在 300ms+。这样我们就知道了欧洲的网络中心太差

2 百分位等级
这里有另外一个紧密相关的度量叫 percentile_ranks 。 percentiles 度量告诉我们落在某个百分比以下的所有文档的最小值。例如,如果 50 百分位是 119ms,那么有 50% 的文档数值都不超过 119ms。 percentile_ranks 告诉我们某个具体值属于哪个百分位。119ms 的 percentile_ranks 是在 50 百分位。 这基本是个双向关系,例如:
50 百分位是 119ms。
119ms 百分位等级是 50 百分位。

所以假设我们网站必须维持的服务等级协议(SLA)是响应时间低于 210ms。然后,我们老板警告我们如果响应时间超过 800ms 会把我开除。可以理解的是,我们希望知道有多少百分比的请求可以满足 SLA 的要求(并期望至少在 800ms 以下!)我们可以应用 percentile_ranks 衡量

#query
{
  "size": 0,
  "aggs": {
    "zones": {
      "terms": {
        "field": "zone"
      },
      "aggs": {
        "load_times": {
          "percentile_ranks": {
            "field": "latency",
            "values": [
              210,
              800
            ]
          }
        }
      }
    }
  }
}
#result
     "buckets" : [
        {
          "key" : "EU",
          "doc_count" : 6,
          "load_times" : {
            "values" : {
              "210.0" : 31.944444444444443,
              "800.0" : 100.0
            }
          }
        },
        {
          "key" : "US",
          "doc_count" : 6,
          "load_times" : {
            "values" : {
              "210.0" : 100.0,
              "800.0" : 100.0
            }
          }
        }
      ]

在欧洲(EU),210ms 的百分位等级是 31.94% 。
在美国(US),210ms 的百分位等级是 100% 。
在欧洲(EU)和美国(US),800ms 的百分位等级是 100% 。
这个算法是TDigest算法,这个鬼东西有点超纲了。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注