百分位和分布值指标

本文档介绍如何理解 Distribution 值类型的指标数据的百分位和直方图模型。分布指标定义值的范围(称为“桶”),并记录每个桶中的测量值数量。分布指标不报告各个测量值,而是报告桶中数量的直方图。如果单个测量值太多而无法收集,但有关这些测量值的统计信息(如平均值或百分位)很有价值,服务便会使用此值类型。

在热图上绘制分布值指标图表时,您可以使用图表工具栏中的选项叠加第 50、第 95 和第 99 百分位。如果要在折线图上显示分布值指标,则必须配置图表以将分布值转换为数值。您可以使用选择一个百分位的校准器来执行这一转换。

本页面的下一节使用一个合成示例来展示如何确定百分位。该示例显示,百分位值取决于存储分区的数量、存储分区的宽度、测量值的分布和样本总数。百分位值与实际的测量值无关,因为直方图中没有这些值。

含合成数据的示例

假设有一个 Exponential 存储桶模型,扩缩因子为 1,增长因子为 2,并且有 10 个有限存储桶。此直方图包含 12 个分桶,其中 10 个是有限分桶,1 个仅指定上限,1 个仅指定下限。在本示例中,索引为 n+1 的有限桶的宽度是索引为 n 的有限桶的两倍。

以下示例显示,存储桶宽度决定了计算百分位与测量值之间的最大误差。这些示例还表明,直方图中的样本数量很重要。例如,如果样本数量少于 20,则第 95 和第 99 百分位将始终在同一个桶中。

案例 1:样本总数为 1。

当只有一个测量值时,三个百分位值不同,但它们仅显示同一桶的第 50、第 95 和第 99 百分位。无法确定估计值与实际测量值之间的误差,因为测量值未知。

例如,假设测量值的直方图如下表所示:

存储分区编号 下限 上限 计数 百分位范围
0 1 0 0
1 1 2 0 0
2 2 4 0 0
3 4 8 0 0
4 8 16 0 0
5 16 32 0 0
6 32 64 0 0
7 64 128 0 0
8 128 256 1 0 - 100
9 256 512 0 0
10 512 1024 0 0
11 1024 0 0

如需计算第 50 百分位,请执行以下操作:

  1. 使用存储桶计数确定包含第 50 百分位的存储桶。在此示例中,第 8 个存储桶包含第 50 百分位。
  2. 使用以下规则计算估算值:

    pth percentage = bucket_low +
                    (bucket_up - bucket_low)*(p - p_low)/(p_up - p_low)
    

    在前面的表达式中,p_lowp_up 是存储桶百分位数范围的下限和上限。同样,bucket_lowbucket_up 是分桶的下限和上限。p_lowp_up 的值取决于计数在不同存储分区之间的分配方式。

例如,第 50 百分位的计算方式如下:

   50th percentile = 128 + (256-128)*(50-0)/(100-0)
                   = 128 + 128 * 50 / 100
                   = 128 + 64
                   = 192

如需计算第 95 个百分位数,请将上一个表达式中的 50 替换为 95。在此示例中,只有一个样本,因此百分位数如下所示:

百分位 存储分区编号
第 50 百分位 8 192
第 95 百分位 8 249.6
第 99 百分位 8 254.7

估计值与实际测量值之间的误差是有界限的,但无法确定,因为测量值未知。

案例 2:样本总数为 10。

有 10 个样本时,第 50 百分位可能与第 95 和第 99 百分位位于不同的桶。但是,没有足够的测量值使得第 95 百分位和第 99 百分位位于不同的桶。

例如,假设测量值的直方图如下表所示:

存储分区编号 下限 上限 计数 百分位范围
0 1 4 0 - 40
1 1 2 2 40 - 60
2 2 4 1 60 - 70
3 4 8 1 70 - 80
4 8 16 1 80 - 90
5 16 32 0 0
6 32 64 0 0
7 64 128 0 0
8 128 256 1 90 - 100
9 256 512 0 0
10 512 1024 0 0
11 1024 0 0

您可以使用前面介绍的步骤计算第 50、第 95 和第 99 百分位。例如,第 50 百分位(位于第 1 个桶中)的计算方式如下:

50th percentile = 1 + (2-1)*(50-40)/(60-40)
                = 1 + (1 * 10 / 20)
                = 1 + 0.5
                = 1.5

同样,第 95 百分位的计算方式如下:

95th percentile = 128 + (256-128)*(95-90)/(100-90)
                = 128 + 128 * 5 / 10
                = 128 + 64
                = 192

通过之前描述的过程,可以计算出百分位数。下表中的每一行都列出了百分位、相应的桶和计算值:

百分位 存储分区编号 最大误差
第 50 百分位 1 1.5 0.5
第 95 百分位 8 192 74
第 99 百分位 8 243.2 115.2

在此示例和前面的示例中,第 95 百分位位于第 8 个存储桶中;但是,百分位计算方式不同。之所以出现差异,是因为样本的分布方式不同。在第一个示例中,所有样本都在同一个存储桶中,而在最新示例中,样本位于不同的存储桶中。

含实际数据的示例

本部分包含一个示例,说明如何确定特定指标使用的桶模型。本部分还说明了如何计算所计算的百分位值中的潜在误差。

确定桶模型

如需确定在特定时间间隔用于某个指标的桶,请调用 Cloud Monitoring API 的 projects.timeSeries/list 方法。

例如,要确定某个指标的桶模型,请执行以下操作:

  1. 转到 projects.timeSeries/list 网页。
  2. API Explorer 中,输入指定指标的过滤条件、开始时间和结束时间。

    例如,如需获取存储 API 请求延迟时间的指标的相关信息,请输入以下命令:

    metric.type="serviceruntime.googleapis.com/api/request_latencies"
    resource.type="consumed_api"
    

    在此示例中,过滤条件字段指定了指标类型和资源类型。如需详细了解这些过滤条件,请参阅监控过滤条件

  3. 点击 Enter

以下是某个 Google Cloud 项目上提供的一个分布值指标的 list API 响应:

{
  "timeSeries": [
    {
      "metric": {...},
      "resource": {...},
      },
      "metricKind": "DELTA",
      "valueType": "DISTRIBUTION",
      "points": [
        {
          "interval": {
            "startTime": "2020-11-03T15:05:00Z",
            "endTime": "2020-11-03T15:06:00Z"
          },
          "value": {
            "distributionValue": {
              "count": "3",
              "mean": 25.889,
              "bucketOptions": {
                "exponentialBuckets": {
                  "numFiniteBuckets": 66,
                  "growthFactor": 1.4,
                  "scale": 1
                }
              },
              "bucketCounts": [
                "0",
                "0",
                "0",
                "0",
                "0",
                "0",
                "0",
                "0",
                "0",
                "0",
                "3"
              ]
            }
          }
        },

在 API 响应中,value 字段描述 points 数组中存储的数据。countmean 字段报告在指定时间间隔内有 3 个测量值,它们的平均值为 25.889。bucketOptions 字段显示,指数模型配置为具有 66 个桶,标度为 1,增长因数为 1.4。

要计算索引为 n 的桶的下限和上限,请使用以下规则:

  • 下限(1 ≤ n < N)= 标度 * (增长因数)(n-1)
  • 上限(0 ≤ n < N-1)= 标度 * (增长因数)n

在前面的表达式中,N 是分桶的总数。

下表中显示了此指标的存储桶,以及每个存储桶的中点:

个存储桶 下限 上限 中点
0 1 不适用
1 1 1.40 1.20
2 1.40 1.96 1.68
9 14.76 20.66 17.71
10 20.66 28.93 24.79
11 28.93 40.50 34.71

验证百分位计算

现在已知桶配置,对于任何一组测量值,您都可以预测第 50、第 95 和第 99 百分位值。例如,如果只有一个样本,并且位于 10 号桶中,则第 50 百分位值为 24.79。

如果要检索指标的第 50、第 95 和第 99 百分位值,您可以使用 API 方法 projects.timeSeries/list,并添加校准时间段和校准器。在此示例中,选择了以下设置:

  • 校准器ALIGN_PERCENTILE_50ALIGN_PERCENTILE_95ALIGN_PERCENTILE_99
  • 校准时间段:60 秒

如果选择 ALIGN_PERCENTILE_50,时序中的每个值都是桶的第 50 百分位:

{
  "timeSeries": [
    {
      "metric": {...},
      "resource": {...},
      "metricKind": "GAUGE",
      "valueType": "DOUBLE",
      "points": [
        {
          "interval": {
            "startTime": "2020-11-03T15:06:36Z",
            "endTime": "2020-11-03T15:06:36Z"
          },
          "value": {
            "doubleValue": 24.793256140799986
          }
        },
        {
          "interval": {
            "startTime": "2020-11-03T15:05:36Z",
            "endTime": "2020-11-03T15:05:36Z"
          },
          "value": {
            "doubleValue": 34.710558597119977
          }
        },
        {
          "interval": {
            "startTime": "2020-11-03T15:04:36Z",
            "endTime": "2020-11-03T15:04:36Z"
          },
          "value": {
            "doubleValue": 24.793256140799986
          }
        }
      ]
    },

两个示例的第 50 百分位位于桶 10 中,另一个示例则位于桶 11 中。

下表展示了使用不同校准器执行 projects.timeSeries/list 方法的结果。第一行对应于未指定校准器的情况。如果未指定校准器,则返回桶模型和平均值。接下来的三行列出了校准器设置为 ALIGN_PERCENTILE_50ALIGN_PERCENTILE_95ALIGN_PERCENTILE_99 时返回的数据:

统计信息 样本 @ 15:06 样本 @ 15:05 样本 @ 15:04
平均值 25.889 33.7435 不可用。
第 50 百分位 24.79 34.71 24.79
第 95 百分位 28.51 39.91 28.51
第 99 百分位 28.84 40.37 28.84

如两个合成数据示例所示,百分位的值取决于样本的分布方式。如果所有样本都位于样本桶中,则第 50 百分位是该桶的中点。但是,如果样本位于不同的分桶中,则该分布会影响估算结果。

如需确定第 50 百分位是否是对平均值的合理估计,您可以将平均值与第 50 百分位进行比较。将返回平均值和桶详细信息。

后续步骤

如需了解如何直观呈现分布值指标,请参阅分布值指标简介