• prometheus基础概念


      本章将介绍 Prometheus 一些基础概念,包括:

    • 理解时间序列
    • 四种 Metric Type
    • 作业与实例

     

    1.理解时间序列

      Prometheus 存储的是时序数据, 即按照相同时序(相同的名字和标签),以时间维度存储连续的数据的集合。

      之前章节通过Node Exporter暴露的HTTP服务,Prometheus可以采集到当前主机所有监控指标的样本数据。例如:

    # HELP node_cpu Seconds the cpus spent in each mode.
    # TYPE node_cpu counter
    node_cpu{cpu="cpu0",mode="idle"} 362812.7890625
    # HELP node_load1 1m load average.
    # TYPE node_load1 gauge
    node_load1 3.0703125

      其中非#开头的每一行表示当前Node Exporter采集到的一个监控样本:node_cpu和node_load1表明了当前指标的名称、大括号中的标签则反映了当前样本的一些特征和维度、浮点数则是该监控样本的具体值。

     

    1.1 样本

      Prometheus会将所有采集到的样本数据以时间序列(time-series)的方式保存在内存数据库中,并且定时保存到硬盘上。time-series是按照时间戳和值的序列顺序存放的,我们称之为向量(vector). 每条time-series通过指标名称(metrics name)和一组标签集(labelset)命名。如下所示,可以将time-series理解为一个以时间为Y轴的数字矩阵:

      ^
      │   . . . . . . . . . . . . . . . . .   . .   node_cpu{cpu="cpu0",mode="idle"}
      │     . . . . . . . . . . . . . . . . . . .   node_cpu{cpu="cpu0",mode="system"}
      │     . . . . . . . . . .   . . . . . . . .   node_load1{}
      │     . . . . . . . . . . . . . . . .   . .  
      v
        <------------------ 时间 ---------------->

      在time-series中的每一个点称为一个样本(sample),样本由以下三部分组成:

    • 指标(metric):metric name和描述当前样本特征的labelsets;
    • 时间戳(timestamp):一个精确到毫秒的时间戳;
    • 样本值(value): 一个float64的浮点型数据表示当前样本的值。
    <--------------- metric ---------------------><-timestamp -><-value->
    http_request_total{status="200", method="GET"}@1434417560938 => 94355
    http_request_total{status="200", method="GET"}@1434417561287 => 94334
    
    http_request_total{status="404", method="GET"}@1434417560938 => 38473
    http_request_total{status="404", method="GET"}@1434417561287 => 38544
    
    http_request_total{status="200", method="POST"}@1434417560938 => 4748
    http_request_total{status="200", method="POST"}@1434417561287 => 4785

    1.2 指标(Metric)

      在形式上,所有的指标(Metric)都通过如下格式标示:

    <metric name>{<label name>=<label value>, ...}

      指标的名称(metric name)可以反映被监控样本的含义(比如,http_request_total - 表示当前系统接收到的HTTP请求总量)。指标名称只能由ASCII字符、数字、下划线以及冒号组成并必须符合正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*。

      标签(label)反映了当前样本的特征维度,通过这些维度Prometheus可以对样本数据进行过滤,聚合等。标签的名称只能由ASCII字符、数字以及下划线组成并满足正则表达式[a-zA-Z_][a-zA-Z0-9_]*。

      其中以__作为前缀的标签,是系统保留的关键字,只能在系统内部使用。标签的值则可以包含任何Unicode编码的字符。在Prometheus的底层实现中指标名称实际上是以__name__=<metric name>的形式保存在数据库中的,因此以下两种方式均表示的同一条time-series:

    api_http_requests_total{method="POST", handler="/messages"}

      等同于:

    {__name__="api_http_requests_total",method="POST", handler="/messages"}

      在Prometheus源码中也可以找到指标(Metric)对应的数据结构,如下所示:

    type Metric LabelSet
    
    type LabelSet map[LabelName]LabelValue
    
    type LabelName string
    
    type LabelValue string

    2.Metrics类型

      Prometheus 时序数据分为CounterGaugeHistogramSummary四种类型。

      在Exporter返回的样本数据中,其注释中也包含了该样本的类型。例如:

    # HELP node_cpu Seconds the cpus spent in each mode.
    # TYPE node_cpu counter
    node_cpu{cpu="cpu0",mode="idle"} 362812.7890625

    2.1 Counter:只增不减的计数器

      Counter类型的指标其工作方式和计数器一样,只增不减(除非系统发生重置)。常见的监控指标,如http_requests_total,node_cpu都是Counter类型的监控指标。 一般在定义Counter类型指标的名称时推荐使用_total作为后缀。

      Counter是一个简单但有强大的工具,例如我们可以在应用程序中记录某些事件发生的次数,通过以时序的形式存储这些数据,我们可以轻松的了解该事件产生速率的变化。 PromQL内置的聚合操作和函数可以让用户对这些数据进行进一步的分析:

      例如,通过rate()函数获取HTTP请求量的增长率:

    rate(http_requests_total[5m])

      查询当前系统中,访问量前10的HTTP地址:

    topk(10, http_requests_total)

     

    2.2 Gauge

      与Counter不同,Gauge 表示搜集的数据是一个瞬时的值,与时间没有关系,可以任意变高变低,Gauge类型的指标侧重于反应系统的当前状态。因此这类指标的样本数据可增可减。常见指标如:node_memory_MemFree(主机当前空闲的内容大小)、node_memory_MemAvailable(可用内存大小)都是Gauge类型的监控指标。

      通过Gauge指标,用户可以直接查看系统的当前状态:

    node_memory_MemFree

      对于Gauge类型的监控指标,通过PromQL内置函数delta()可以获取样本在一段时间返回内的变化情况。例如,计算CPU温度在两个小时内的差异:

    delta(cpu_temp_celsius{host="zeus"}[2h])

      还可以使用deriv()计算样本的线性回归模型,甚至是直接使用predict_linear()对数据的变化趋势进行预测。例如,预测系统磁盘空间在4个小时之后的剩余情况:

    predict_linear(node_filesystem_free{job="node"}[1h], 4 * 3600)

    2.3 Histogram

      Histogram 由 <basename>_bucket{le="<upper inclusive bound>"},<basename>_bucket{le="+Inf"}, <basename>_sum,<basename>_count 组成,主要用于表示一段时间范围内对数据进行采样(通常是请求持续时间或响应大小),并能够对其指定区间以及总数进行统计,通常它采集的数据展示为直方图。

      例如 Prometheus server 中 prometheus_local_storage_series_chunks_persisted, 表示 Prometheus 中每个时序需要存储的 chunks 数量,我们可以用它计算待持久化的数据的分位数。

    2.4 Summary

      Summary 和 Histogram 类似,由 <basename>{quantile="<φ>"},<basename>_sum,<basename>_count 组成,主要用于表示一段时间内数据采样结果(通常是请求持续时间或响应大小),它直接存储了 quantile 数据,而不是根据统计区间计算出来的。

      例如 Prometheus server 中 prometheus_target_interval_length_seconds。

    2.5 Histogram vs Summary

      都包含<basename>_sum,<basename>_count

      Histogram 需要通过 <basename>_bucket 计算 quantile, 而 Summary 直接存储了 quantile 的值。

     

    2.6 使用Histogram和Summary分析数据分布情况

      除了Counter和Gauge类型的监控指标以外,Prometheus还定义了Histogram和Summary的指标类型。Histogram和Summary主用用于统计和分析样本的分布情况。

      在大多数情况下人们都倾向于使用某些量化指标的平均值,例如CPU的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统API调用的平均响应时间为例:如果大多数API请求都维持在100ms的响应时间范围内,而个别请求的响应时间需要5s,那么就会导致某些WEB页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。

      为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在0~10ms之间的请求数有多少而10~20ms之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram和Summary都是为了能够解决这样问题的存在,通过Histogram和Summary类型的监控指标,我们可以快速了解监控样本的分布情况。

      例如,指标prometheus_tsdb_wal_fsync_duration_seconds的指标类型为Summary。 它记录了Prometheus Server中wal_fsync处理的处理时间,通过访问Prometheus Server的/metrics地址,可以获取到以下监控样本数据:

    # HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
    # TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
    prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
    prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
    prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
    prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
    prometheus_tsdb_wal_fsync_duration_seconds_count 216

      从上面的样本中可以得知当前Prometheus Server进行wal_fsync操作的总次数为216次,耗时2.888716127000002s。其中中位数(quantile=0.5)的耗时为0.012352463,9分位数(quantile=0.9)的耗时为0.014458005s。

      在Prometheus Server自身返回的样本数据中,我们还能找到类型为Histogram的监控指标prometheus_tsdb_compaction_chunk_range_bucket。

    # HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction
    # TYPE prometheus_tsdb_compaction_chunk_range histogram
    prometheus_tsdb_compaction_chunk_range_bucket{le="100"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="400"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="1600"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="6400"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="25600"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="102400"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="409600"} 0
    prometheus_tsdb_compaction_chunk_range_bucket{le="1.6384e+06"} 260
    prometheus_tsdb_compaction_chunk_range_bucket{le="6.5536e+06"} 780
    prometheus_tsdb_compaction_chunk_range_bucket{le="2.62144e+07"} 780
    prometheus_tsdb_compaction_chunk_range_bucket{le="+Inf"} 780
    prometheus_tsdb_compaction_chunk_range_sum 1.1540798e+09
    prometheus_tsdb_compaction_chunk_range_count 780

      与Summary类型的指标相似之处在于Histogram类型的样本同样会反应当前指标的记录的总数(以_count作为后缀)以及其值的总量(以_sum作为后缀)。不同在于Histogram指标直接反应了在不同区间内样本的个数,区间通过标签len进行定义。

      同时对于Histogram的指标,我们还可以通过histogram_quantile()函数计算出其值的分位数。不同在于Histogram通过histogram_quantile函数是在服务器端计算的分位数。 而Sumamry的分位数则是直接在客户端计算完成。因此对于分位数的计算而言,Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。反之对于客户端而言Histogram消耗的资源更少。在选择这两种方式时用户应该按照自己的实际场景进行选择。

     

    3.实际案例

    3.1 实例

      Prometheus 中,将任意一个独立的数据源(target)称之为实例(instance)。包含相同类型的实例的集合称之为作业(job)。 如下是一个含有四个重复实例的作业:

    - job: api-server
        - instance 1: 1.2.3.4:5670
        - instance 2: 1.2.3.4:5671
        - instance 3: 5.6.7.8:5670
        - instance 4: 5.6.7.8:5671

    3.2 自生成标签和时序

      Prometheus 在采集数据的同时,会自动在时序的基础上添加标签,作为数据源(target)的标识,以便区分:

    job: The configured job name that the target belongs to.
    instance: The <host>:<port> part of the target's URL that was scraped.

      如果其中任一标签已经在此前采集的数据中存在,那么将会根据 honor_labels 设置选项来决定新标签。详见官网解释:scrape configuration documentation

      对每一个实例而言,Prometheus 按照以下时序来存储所采集的数据样本:

    up{job="<job-name>", instance="<instance-id>"}: 1 表示该实例正常工作
    up{job="<job-name>", instance="<instance-id>"}: 0 表示该实例故障
    scrape_duration_seconds{job="<job-name>", instance="<instance-id>"} 表示拉取数据的时间间隔
    scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"} 表示采用重定义标签(relabeling)操作后仍然剩余的样本数
    scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}  表示从该数据源获取的样本数

      其中up时序可以有效应用于监控该实例是否正常工作。

    作者:小家电维修

    相见有时,后会无期。

  • 相关阅读:
    Faster-RCNN Pytorch实现的minibatch包装
    RuntimeError: cuda runtime error (10) : invalid device ordinal
    pip使用技巧
    Pytorch model saving and loading 模型保存和读取
    vs 附加包含目录不起作用
    微服务杂谈
    spring 学习笔记
    java 发送 http 请求
    PHP7 错误及异常机制
    Mac OS 下定制终端颜色
  • 原文地址:https://www.cnblogs.com/lizexiong/p/15578713.html
Copyright © 2020-2023  润新知