## 百分位计算edit

Elasticsearch 提供的另外一个近似度量就是 `percentiles` 百分位数度量。 百分位数展现某以具体百分比下观察到的数值。例如，第95个百分位上的数值，是高于 95% 的数据总和。

Figure 40. Average request latency over time

Figure 41. Average request latency with 99th percentile over time

### 百分位度量edit

```POST /website/logs/_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" }```

```GET /website/logs/_search
{
"size" : 0,
"aggs" : {
"percentiles" : {
"field" : "latency"
}
},
"avg" : {
"field" : "latency"
}
}
}
}```
 `percentiles` 度量被应用到 `latency` 延时字段。 为了比较，我们对相同字段使用 `avg` 度量。

```...
"aggregations": {
"values": {
"1.0": 75.55,
"5.0": 77.75,
"25.0": 94.75,
"50.0": 101,
"75.0": 289.75,
"95.0": 489.34999999999985,
"99.0": 596.2700000000002
}
},
"value": 199.58333333333334
}
}```

```GET /website/logs/_search
{
"size" : 0,
"aggs" : {
"zones" : {
"terms" : {
"field" : "zone"
},
"aggs" : {
"percentiles" : {
"field" : "latency",
"percents" : [50, 95.0, 99.0]
}
},
"avg" : {
"field" : "latency"
}
}
}
}
}
}```
 首先根据区域我们将延时分到不同的桶中。 再计算每个区域的百分位数值。 `percents` 参数接受了我们想返回的一组百分位数，因为我们只对长的延时感兴趣。

```...
"aggregations": {
"zones": {
"buckets": [
{
"key": "eu",
"doc_count": 6,
"values": {
"50.0": 299.5,
"95.0": 562.25,
"99.0": 610.85
}
},
"value": 309.5
}
},
{
"key": "us",
"doc_count": 6,
"values": {
"50.0": 90.5,
"95.0": 101.5,
"99.0": 101.9
}
},
"value": 89.66666666666667
}
}
]
}
}
...```

### 百分位等级edit

• 50 百分位是 119ms。
• 119ms 百分位等级是 50 百分位。

```GET /website/logs/_search
{
"size" : 0,
"aggs" : {
"zones" : {
"terms" : {
"field" : "zone"
},
"aggs" : {
"percentile_ranks" : {
"field" : "latency",
"values" : [210, 800]
}
}
}
}
}
}```
 `percentile_ranks` 度量接受一组我们希望分级的数值。

```"aggregations": {
"zones": {
"buckets": [
{
"key": "eu",
"doc_count": 6,
"values": {
"210.0": 31.944444444444443,
"800.0": 100
}
}
},
{
"key": "us",
"doc_count": 6,
"values": {
"210.0": 100,
"800.0": 100
}
}
}
]
}
}```

• 在欧洲（EU），210ms 的百分位等级是 31.94% 。
• 在美国（US），210ms 的百分位等级是 100% 。
• 在欧洲（EU）和美国（US），800ms 的百分位等级是 100% 。

`percentile_ranks` 度量提供了与 `percentiles` 相同的信息，但它以不同方式呈现，如果我们对某个具体数值更关心，使用它会更方便。

### 学会权衡edit

• 百分位的准确度与百分位的 极端程度 相关，也就是说 1 或 99 的百分位要比 50 百分位要准确。这只是数据结构内部机制的一种特性，但这是一个好的特性，因为多数人只关心极端的百分位。
• 对于数值集合较小的情况，百分位非常准确。如果数据集足够小，百分位可能 100% 精确。
• 随着桶里数值的增长，算法会开始对百分位进行估算。它能有效在准确度和内存节省之间做出权衡。 不准确的程度比较难以总结，因为它依赖于 聚合时数据的分布以及数据量的大小。

`cardinality` 类似，我们可以通过修改参数 `compression` 来控制内存与准确度之间的比值。

TDigest 算法用节点近似计算百分比：节点越多，准确度越高（同时内存消耗也越大），这都与数据量成正比。 `compression` 参数限制节点的最大数目为 `20 * compression`