搞懂 Prometheus 这四种指标类型,谁都可能成为监控老司机?
一个指标名称
收集该数据点的时间戳
一个由数字表示的测量值
1、Prometheus指标
Counters Gauges Histograms Summaries
# HELP用来为指标提供描述,# TYPE为指标提供类型。
现在,让我们来更详细地介绍一下每个Prometheus指标类型。
计数器(Counter)
# HELP http_requests_total Total number of http api requests
# TYPE http_requests_total counter
http_requests_total{api="add_product"} 4633433
指标名称是http_requests_total
,它有一个名为api的标签,值为add_product
,Counter 的值为 4633433。
这意味着自从上次服务启动或Counter重置以来,add_product
的 API 已经被调用了 4633433 次。按照惯例,Counter 类型的指标通常以_total
为后缀。
rate(http_requests_total{api="add_product"}[5m])
increase(http_requests_total{api="add_product"}[5m])
这将返回过去5分钟内的总请求数,这相当于用每秒的速率乘以间隔时间的秒数(在我们的例子中是5分钟):
rate(http_requests_total{api="add_product"}[5m]) * 5 * 60
其他你可能会使用 Counter 类型指标的例子:测量电子商务网站的订单数量,在网络接口上发送和接收的字节数,或者应用程序中的错误数量。如果它是一个会一直上升的指标,那么就使用一个Counter
。
下面是一个例子,说明如何使用 Prometheus 客户端库在 Python 中创建和增加一个计数器指标:
from prometheus_client import Counter
api_requests_counter = Counter(
'http_requests_total',
'Total number of http api requests',
['api']
)
api_requests_counter.labels(api='add_product').inc()
需要注意的是,由于Counter可以被重置为零,你要确保你用来存储和查询指标的后端能够支持这种情况,并且在Counter重启的情况下仍然提供准确的结果。
Prometheus 和兼容 PromQL 的 Prometheus 远程存储系统,如 Promscale,可以正确处理 Counter 重启。
仪表(Gauge)
Gauge 指标用于可以任意增加或减少的测量。这是你可能更熟悉的指标类型,因为即使没有经过额外处理的实际值也是有意义的,它们经常被使用到。例如,测量温度、CPU和内存使用的指标,或者队列的大小都是Gauge。
例如,为了测量一台主机的内存使用情况,我们可以使用一个Gauge指标,比如:
# HELP node_memory_used_bytes Total memory used in the node in bytes
# TYPE node_memory_used_bytes gauge
node_memory_used_bytes{hostname="host1.domain.com"} 943348382
Counter
指标时不同,rate和delta函数对Gauge没有意义。然而,计算特定时间序列的平均数、最大值、最小值或百分比的函数经常与 Gauge一起使用。avg_over_time
、max_over_time
、min_over_time
和quantile_over_time
。要计算过去10分钟内在host1.domain.com 上使用的平均内存,你可以这样做:avg_over_time(node_memory_used_bytes{hostname="host1.domain.com"}[10m])
from prometheus_client import Gauge
memory_used = Gauge(
'node_memory_used_bytes',
'Total memory used in the node in bytes',
['hostname']
)
memory_used.labels(hostname='host1.domain.com').set(943348382)
直方图(Histogram)
一个包含测量次数的Counter。指标名称使用_count后缀。 一个包含所有测量值之和的Counter。指标名称使用_sum后缀。 直方图桶被暴露为一系列的Counter,使用指标名称的后缀_bucket和表示桶的上限的le label。Prometheus中的桶是包含桶的边界的,即一个上限为N的桶(即le label)包括所有数值小于或等于N的数据点。
# HELP http_request_duration_seconds Api requests response time in seconds
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_sum{api="add_product" instance="host1.domain.com"} 8953.332
http_request_duration_seconds_count{api="add_product" instance="host1.domain.com"} 27892
http_request_duration_seconds_bucket{api="add_product" instance="host1.domain.com" le="0"}
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.01"} 0
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.025"} 8
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.05"} 1672
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.1"} 8954
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.25"} 14251
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="0.5"} 24101
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="1"} 26351
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="2.5"} 27534
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="5"} 27814
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="10"} 27881
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="25"} 27890
http_request_duration_seconds_bucket{api="add_product", instance="host1.domain.com", le="+Inf"} 27892
rate(http_request_duration_seconds_sum{api=”add_product”, instance=”host1.domain.com”}[5m]) / rate(http_request_duration_seconds_count{api=”add_product”, instance=”host1.domain.com”}[5m])
sum(rate(http_request_duration_seconds_sum[5m])) / sum(rate(http_request_duration_seconds_count[5m]))
利用 Histogram,你可以在查询时计算单个时间序列以及多个时间序列的百分位。在PromQL中,我们将使用histogram_quantile函数。Prometheus使用分位数而不是百分位数。
它们本质上是一样的,但是以0到1的比例表示的,而百分位数是以0到100的比例表示的。要计算在host1.domain.com上运行的add_product API响应时间的第99百分位数(0.99四分位数),你可以使用以下查询。
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{api=”add_product”, instance=”host1.domain.com”}[5m]))
Histograms 的一大优势是可以进行汇总。下面的查询返回所有API和实例的响应时间的第99个百分点:
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
首先,桶必须是预定义的,这需要一些前期的设计。如果你的桶没有被很好地定义,你可能无法计算出你需要的百分比,或者会消耗不必要的资源。例如,如果你有一个总是需要超过一秒钟的API,那么拥有上限(le label)小于一秒钟的桶将是无用的,只会消耗监控后端服务器的计算和存储资源。另一方面,如果99.9%的API请求耗时少于50毫秒,那么拥有一个上限为100毫秒的初始桶将无法让你准确测量API的性能。
第二,他们提供的是近似的百分位数,而不是精确的百分位数。这通常没什么问题,只要你的桶被设计为提供具有合理准确性的结果。 第三,由于百分位数需要在服务器端计算,当有大量数据需要处理时,它们的计算成本会非常高。在Prometheus中减轻这种情况的一个方法是使用录制规则来预先计算所需的百分位数。
from prometheus_client import Histogram
api_request_duration = Histogram(
name='http_request_duration_seconds',
documentation='Api requests response time in seconds',
labelnames=['api', 'instance'],
buckets=(0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 25 )
)
api_request_duration.labels(
api='add_product',
instance='host1.domain.com'
).observe(0.3672)
像直方图一样,Summary指标对于测量请求持续时间和响应体大小很有用。
像直方图一样,汇总度量对于测量请求持续时间和响应大小很有用。
一个Summary指标包括这些指标:
一个包含总测量次数的Counter。指标名称使用
_count
后缀。一个包含所有测量值之和的Counter。指标名称使用_sum后缀。可以选择使用带有分位数标签的指标名称,来暴露一些测量值的分位数指标。由于你不希望这些量值是从应用程序运行的整个时间内测得的,Prometheus客户端库通常会使用流式的分位值,这些分位值是在一个滑动的(通常是可配置的)时间窗口上计算得到的。
# HELP http_request_duration_seconds Api requests response time in seconds
# TYPE http_request_duration_seconds summary
http_request_duration_seconds_sum{api="add_product" instance="host1.domain.com"} 8953.332
http_request_duration_seconds_count{api="add_product" instance="host1.domain.com"} 27892
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="0"}
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="0.5"} 0.232227334
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="0.90"} 0.821139321
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="0.95"} 1.528948804
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="0.99"} 2.829188272
http_request_duration_seconds{api="add_product" instance="host1.domain.com" quantile="1"} 34.283829292
首先,客户端计算百分位是很昂贵的。这是因为客户端库必须保持一个有序的数据点列表,以进行这种计算。在Prometheus SDK中的实现限制了内存中保留和排序的数据点的数量,这降低了准确性以换取效率的提高。注意,并非所有的Prometheus客户端库都支持汇总指标中的量值。例如,Python SDK就不支持。 第二,你要查询的量值必须由客户端预先定义。只有那些已经提供了指标的量值才能通过查询返回。没有办法在查询时计算其他百分位。增加一个新的百分位指标需要修改代码,该指标才可以被使用。 第三,也是最重要的一点,不可能把多个Summary指标进行聚合计算。这使得它们对动态现代系统中的大多数用例毫无用处,在这些用例中,通常我们对一个特定的组件感兴趣,这个视角是全局的,它不与特定的实例关联。
下面的代码使用 Prometheus 的 Python 客户端库创建了一个 Summary 指标。
from prometheus_client import Summary
api_request_duration = Summary(
'http_request_duration_seconds',
'Api requests response time in seconds',
['api', 'instance']
)
api_request_duration.labels(api='add_product', instance='host1.domain.com').observe(0.3672)
上面的代码没有定义任何量化指标,只会产生总和和计数指标。Prometheus 的Python SDK 不支持 Summary 指标中的分位数计算。
链接:https://blog.csdn.net/LinkSLA/article/details/132846738
(版权归原作者所有,侵删)
微信扫码关注该文公众号作者