Prometheus监控是一概不懂啊,只知道它是个采集监控数据的,PromSQL不会写,弊端不知道,能干什么,不能干什么,这个远远不能满足当前需要。
先从几个疑问开始:
因为自己搭了Prometheus,开启了SpringActuator( endpoint * )进行上报,但是迟迟没收到数据;于是导出搜刮文章,怎么打通体系的:
VMWare: https://tanzu.vmware.com/developer/guides/spring-prometheus/?utm_source=pocket_saves
CalliCoder: https://www.callicoder.com/spring-boot-actuator-metrics-monitoring-dashboard-prometheus-grafana/?utm_source=pocket_saves 这篇文章较好,它说明需要在Prometheus配置为文件那里需要额外配置才能采集到监控数据:增加metric_path
PrometheusMeterRegistry
就是继承了MicroMeter的MeterRegistry
Micrometer provides a simple facade over the instrumentation clients for a number of popular monitoring systems. Currently, it supports the following monitoring systems: Atlas, Datadog, Graphite, Ganglia, Influx, JMX, and Prometheus.
参考yunlzheng.gitbook
Counter: 只增不减的计数器
Gauge: 速度表! CPU使用率
Histogram: 反映不同区间样本的个数, 分位数在服务端完成计算
Summary: 分位数在客户端完成计算 查询性能更好
这两个都是用于统计数据的分布情况,我记得jmap工具显示每个类的实例个数时用的就是Histogram这个单词
示例:
Histogram
prometheus_tsdb_compaction_chunk_range_bucket{le=“100”} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=“400”} 0
Summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile=“0.5”} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile=“0.9”} 0.014458005
这两个都有额外的count和sum
数学运算:加减乘除 取余 幂运算都有
逻辑运算:and or unless(差集) 也有把 大于小于变成bool的语句
字符串运算:正则 =~
正则取反 !~
是 =
不是 !=
语句示例:
http_requests_total{environment=~"staging|testing|development",method!="GET"} [5m] offset 1d
特殊标签__name__
来指标的名称
说来也简单,使用的是外推法。需要注意,外推法(extrapolation)是统计学的概念,相似的还有内插法(interpolation)都是用已有值去推测未知值。外推法有线性外推、多项式外推、锥形外推等,可参见维基百科 我在理解这个increase的外推时,怎么滴就想成了积分,这是求increase,算增量!以v2.43的源码为例https://github.com/prometheus/prometheus/blob/v2.43.0/promql/functions.go#L66 可以简单阅读到,主要计算加了外推时间的间隔extrapolateToInterval
然比sampledInterval
算得比例。其中比较重要的点有二个:一是处理了counter重置的情况(这是个非常重要),如下
resultValue = samples.Points[len(samples.Points)-1].V - samples.Points[0].V
prevValue := samples.Points[0].V
for _, currPoint := range samples.Points[1:] {
if currPoint.H != nil {
return nil // Range contains a mix of histograms and floats.
}
if !isCounter {
continue
}
if currPoint.V < prevValue {
resultValue += prevValue
}
prevValue = currPoint.V
}
另一个是外推时间的计算,系数1.1乘了平均采样周期
当然github也有一番讨论认为外推是有害的,rate()/increase() extrapolation considered harmful #3746 但是这个讨论目前被锁定了:
It’s appropriate to lock a conversation when the entire conversation is not constructive or violates your community’s code of conduct or GitHub’s Community Guidelines locking-conversations 显然prometheus开发者不接受这个提议
这篇SF回答Do I understand Prometheus’s rate vs increase functions correctly?也值得参考:理想世界中,采样时刻正好在整秒,观察时刻也在整秒
文档里说了rate和聚合同时需要时,先要rate,https://prometheus.io/docs/prometheus/latest/querying/functions/#rate 因为rate是处理了counter重置情况的(可以看函数extrapolatedRate),而聚合比如sum并不会处理,这会丢失数值,比目标值小。
Note that when combining rate() with an aggregation operator (e.g. sum()) or a function aggregating over time (any function ending in _over_time), always take a rate() first, then aggregate. Otherwise rate() cannot detect counter resets when your target restarts.
我当时写先sum再rate老半天没写出来!
3-学了表达式,就会写了,直接sum counter 重置参见解答8中的源码
4-告警有专门的alert结构
5-这是一个通用的问题,服务发现;如果prometheus不通过配置感知数据源,那么只有数据源主动上报,但是spring actuator是只能被动拉数据,所以总是需要有个配置的 annotation: prometheus.io/scrape
6-那就有一个报一个呗,当时想问什么呢?
7-Prometheus Operator ServiceMonitor CRD Git-Book
监控数据的分析,和信号处理是类似的。最近我看到我们的Kafka消费Lag居然出现了锯齿状图形,先是慢慢增加,然后突然将为零;这个根本讲不通,一个pod的消费能力不可能变化这么大;搜索一番,一个StackOverflow回答(How does a sawtooth pattern of Kafka consumer lag emerge?)是值得记录的:一种可能是观测的窗口range大小比数据收集频率大,换做信号处理就是说违背了香农采样定理: 为了不失真地恢复模拟信号,采样频率应该大于等于模拟信号频谱中最高频率的2倍。 当采样频率过小时,就会出现混叠(aliasing), 或者莫阿效应(就是手机拍屏幕出现条纹)啊,伟大信息科学技术! 就是说可能是采样频率过低导致输出图形失真。但是呢,我又想了下,因为堆积量变化不可能短时间有那么大,所以应该是消息过期了。其实也不是过期,是重平衡这个分区划到别的消费者并且过一会又划回来了。
向量不能含有labelset一样的metrics,为什么会存在labelset一样的metrics?
向量,指的是一组相关的时序
Since Prometheus is a timeseries database, all data is in the context of some timestamp. The series that maps a timestamp to recorded data is called a timeseriesa set of related timeseries is called a vector
Prometheus中,当数据被转换后,名字就被丢弃,因为你不知道它是否还代表原来的意思, issues-380
是因为vector中,当__name__
被移除后,存在相同的labelset
就需要用label_replace从__name__中截取字段生成一个新label rate时
how-to-avoid-vector-cannot-contain-metrics-with-the-same-labelset-error-when-p
rate(label_replace({__name__=~"camel_proxy.*count"},"name_label","$1","__name__", "(.+)")[5m:])
$1
指的是最后面正则表达式的域匹配label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)
[5m:]
Instant vector - a set of timeseries where every timestamp maps to a single data point at that “instant”
Range vector - a set of timeseries where every timestamp maps to a “range” of data points, recorded some duration into the past.