prometheus 包含四种核心的指标类型:
Counter
counter 是一个累积计数的指标,仅支持增加或者重置为0(只增不减 )。例如:可以用来统计服务请求的数量,任务完成数量,或者出错的数量。
Java的使用如下:
import io.prometheus.client.Counter;
class YourClass {
static final Counter requests = Counter.build()
.name("requests_total").help("Total requests.").register();
void processRequest() {
requests.inc();
// Your code here.
}
}
//通过rate()函数获取HTTP请求量的增长率
rate(http_requests_total[5m])
//查询当前系统中,访问量前10的HTTP地址
topk(10, http_requests_total)
Gauge
gauge是一个纯数值型的能够经常进行增加或者减少的指标。例如用来做温度的计数,内存的使用,同样也可以用来使用计算服务请求数量。
java使用如下:
class YourClass {
static final Gauge inprogressRequests = Gauge.build()
.name("inprogress_requests").help("Inprogress requests.").register();
void processRequest() {
inprogressRequests.inc();
// Your code here.
inprogressRequests.dec();
}
}
dalta(cpu_temp_celsius{host="zeus"}[2h]) //计算CPU温度在两小时内的差异
predict_linear(node_filesystem_free{job="node"}[1h], 4*3600) //预测系统磁盘空间在4小时之后的剩余情况
Histogram
histogram 在一段时间内进行采样,并能够对指定区间以及总数进行统计.。histogram会有一个基本的指标名称<basename>,由以下几部分组成
- <basename>_bucket{le="<upper inclusive bound>"} 用来统计满足指标的情况
# 在总共2次请求当中。http请求响应时间 <=0.005 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.005",} 0.0
# 在总共2次请求当中。http请求响应时间 <=0.01 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.01",} 0.0
- <basename>_sum 值的总和
# 实际含义: 发生的2次http请求总的响应时间为13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET",code="200",} 13.107670803000001
- <basename>_count 请求总数
# 实际含义: 当前一共发生了2次http请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="GET",code="200",} 2.0
Prometheus 的 histogram 是一种累积直方图,它的划分方式如下:假设每个 bucket 的宽度是 0.2s,那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间小于等于 0.4s 的请求数量,以此类推。也就是说,每一个 bucket 的样本包含了之前所有 bucket 的样本,所以叫累积直方图。
为什么要设计为累积直方图?
想象一下,如果 histogram 类型的指标中加入了额外的标签,或者划分了更多的 bucket,那么样本数据的分析就会变得越来越复杂。如果 histogram 是累积的,在抓取指标时就可以根据需要丢弃某些 bucket,这样可以在降低 Prometheus 维护成本的同时,还可以粗略计算样本值的分位数。通过这种方法,用户不需要修改应用代码,便可以动态减少抓取到的样本数量。
Java使用
class YourClass {
static final Histogram requestLatency = Histogram.build()
.name("requests_latency_seconds").help("Request latency in seconds.").register();
void processRequest(Request req) {
Histogram.Timer requestTimer = requestLatency.startTimer();
try {
// Your code here.
} finally {
requestTimer.observeDuration();
}
}
}
Summary
summary与histogram类似,用于表示一段时间内的采样数据,但它直接存储了分位数,而不是通过区间来计算。
Summary与Histogram相比,存在如下区别:
- 都包含 < basename>_sum和< basename>_count;
- Histogram需要通过< basename>_bucket计算quantile,而Summary直接存储了quantile的值
summary 会有一个基本的指标名称<basename>,由以下几部分组成
- <basename>{quantile="<φ>"}
# 含义:这12次http请求响应时间的中位数是3.052404983s
io_namespace_http_requests_latency_seconds_summary{path="/",method="GET",code="200",quantile="0.5",} 3.052404983
# 含义:这12次http请求响应时间的9分位数是8.003261666s
io_namespace_http_requests_latency_seconds_summary{path="/",method="GET",code="200",quantile="0.9",} 8.003261666
- <basename>_sum
#含义:这12次http请求的总响应时间为 51.029495508s
io_namespace_http_requests_latency_seconds_summary_sum{path="/",method="GET",code="200",} 51.029495508
- <basename>_count
# 含义:当前http请求发生总次数为12次
io_namespace_http_requests_latency_seconds_summary_count{path="/",method="GET",code="200",} 12.0
java 使用
class YourClass {
static final Summary receivedBytes = Summary.build()
.name("requests_size_bytes").help("Request size in bytes.").register();
static final Summary requestLatency = Summary.build()
.quantile(0.5, 0.05)
.quantile(0.9, 0.01)
.name("requests_latency_seconds").help("Request latency in seconds.").register();
void processRequest(Request req) {
Summary.Timer requestTimer = requestLatency.startTimer();
try {
// Your code here.
} finally {
receivedBytes.observe(req.size());
requestTimer.observeDuration();
}
}
}
Histogram 和 summary的区别
- Summary 的分位数是直接在客户端计算完成的,处理过程有频繁的全局锁操作,对高并发程序性能存在一定影响。histogram仅仅是在客户端给每个桶做一个原子变量的计数就可以了。Summary 会占用更多的客户端的cpu和内存。
- 在服务端,不能对Summary产生的quantile值进行aggregation运算(例如sum, avg等),histogram可以进行各种操作。因此对服务端的消耗,histogram是大于Summary的。
- histogram存储的是区间的样本数统计值,不能得到精确的分为数,而Summary可以。
两条经验
- 如果需要聚合(aggregate),选择histograms。
- 如果比较清楚要观测的指标的范围和分布情况,选择histograms。如果需要精确的分为数选择summary。