Prometheus Best Practices

Demon.Lee 2021年07月22日 2,078次浏览

结合官方文档及相关内容整理而得

度量指标

(1)自定义指标命名

  • 使用标签来区分指标的特征。
  • 不要将标签名放在指标名称中,会增加冗余,浪费存储空间。
  • 指标名称前缀应该是监控所属领域的名称,如果是对特定应用程序的监控,则前缀应该是应用名称本身。
  • 指标名称后缀应该是一个描述单位的复数,另外,累积计数需要使用 total 作为后缀。
  • 指标名称的任何部分都不应该被程序化地生成。
  • Prometheus 中没有任何单位是硬编码的,但为了更好地兼容,应该使用国际基本单位

(2)不同类型服务下的关键指标

  • 在线服务:已执行的查询数量、错误、延迟和正在进行的请求数量。
  • 离线处理:一般会分阶段处理,需要关注每个阶段的输入量、处理中数据量、已完成量和每个阶段的耗时。
  • 批处理作业:批处理作业与离线处理有一条模糊的界限,因为离线处理可能是在批处理作业中执行的。重点关注:作业每个主要阶段的耗时、总耗时、最后完成时间和完成状态等。
  • 类库:一个库可能被应用程序的多个独立部分针对不同的资源使用,所以要注意在适当的时候用标签区分用途。重点关注:库内部关注错误和延迟,若库用来调用外部资源,至少需要关注查询次数、错误数和延迟。
  • 日志:记录日志的递增计数器(个人理解:通过 label 来区分日志级别等内容)
  • 错误:处理方式与日志记录类似。每次出现故障时,都应该增加一个计数器。与日志不同的是,错误可能是更一般的错误计数器。另外要有总的处理次数,方便计算错误率。
  • 线程池:排队请求的数量、使用中的线程数量、线程总数、处理的任务数量以及它们所花的时间。另外,还有任务在队列中等待的时间。
  • 缓存:总请求数、命中率和总延迟。

(3)业务监控与运营指标

  • 对运营商和互联网企业来说,各个业务的指标体系大体可分为三类:收入类指标(Revenue)、用户类指标(User)、业务量类指标(Number),简称“RUN指标体系”。
  • 针对移动APP监控的AARRR框架,即Acquisition表示获取用户、Activation表示用户活跃度、Retention表示留存、Revenue表示收益、Refer表示传播。
  • 立足于业务、结构化体系和良好的可视化能力。

(4)度量规范化

  • 不使用无关或无法进行过滤的 label,比如用户角色:cpu_seconds_used_total{role="db-server"}。因为一旦角色发生变化,对应的指标连续性就被破坏了。
  • 如果想在输出的结果中增加额外的 label,比如用户角色,同时又想避免该 label 会在监控对象的生命周期中发生变化,可以使用关联外部标签的方式实现,具体参考这里

(5)指标计算(聚合)

  • 查询为空的指标,使用 or 命令,将空转化为 0 等默认值,如:

    1)<expression> or up{job="myjob"} * 0   
    
    2)nginx_ingress_controller_request_size_count{service="applicationserver", path=~"/QueryOpenLuckyBag"} OR on() vector(0) 
    
  • rate()sum() 之间的顺序:即先计算 rate,再求 sum。

    Take the sum of the rates, not the rate of the sums!

  • rate() 的时间窗口大小:至少需要 4 倍的抓取时间间隔。

    To be robust, use a rate() window of at least 4x the scrape interval!

(6)histograms vs summaries(待完善)

  • 如果需要聚合,请选择 histograms。
  • 如果知道将要观察的值的范围和分布,请选择一个 histograms;如果需要精确的分位数,不论值的范围和分布,请选择 summaries。

(7)其他

  • 对监控的数据进行异常检测:使用机器学习算法,对监控数据进行训练。

可视化

(1)控制台和仪表盘

  • 与其在单个大仪表盘上显示每个服务的信息,不如为每个服务构建单独的仪表盘,包括每个服务的延迟和错误。
  • 控制台上的图形不超过5个。
  • 每个图表上的图(线)不超过5个。
  • 使用控制台模板展示时,在右侧表格中数据项不要超过30个。

告警

(1)告警关注的指标

  • 在线服务:重点关注高延迟和错误率,另外一些用户不可见,但很重要的指标也需要告警,比如资金。
  • 离线处理:处理时长
  • 批处理作业:最近处理的结果(成功或失败)
  • 容量:接近阈值时告警
  • 元监控:要有警报,以确保Prometheus server、Alertmanagers、PushGateways和其他监控基础设施的可用性和正确运行,建议黑盒监控。
  • 从终端用户角度分析,他们更多的是关注可用性(即症状),而非具体原因,主要体现在:基本的可用性和正确性、延迟、完整性/新鲜度/持久性、功能是否正常。

(2)告警监控原则

  • 以客户端角度(即服务端对外暴露的能力)的监控为主,以服务端内部监控为辅
  • 从终端用户角度分析,他们更多的是关注可用性(即症状),而非具体原因,主要体现在:基本的可用性和正确性、延迟、完整性/新鲜度/持久性、功能是否正常
  • 导致一个警告产生的原因有很多,不可能把服务端所有的内容都监控到,即使监控到,相应的规则配置会引起越来越多的混乱。而从客户端监控症状是一种更好的方式,可以更方便、更全面、更稳健地捕捉更多的问题。
  • 但服务端监控也是需要的(即监控原因)。比如 cpu/memory/disk 即将耗尽配额等情况,通常从客户端角度是看不到任何症状的,所以要让规则通知我们。
  • 如果需要编写一个代表原因的规则,要检查对应的症状是否也已经被监控了。
  • 告警策略中标签要要有,否则 alertmanager 中的分组,静默等不好处理
  • 有些情况下,对 root cause 进行告警,有助于减少噪声。但大多数情况下,要删除或调整那些嘈杂的、持续的或其他低价值的基于原因的规则。
  • 保持简单的警报,对用户关注的重点问题发出警报,争取尽可能少的警报。警报应该链接到相关的控制台,并使其容易弄清哪个组件出了问题。
  • 要有一个告警对应的 bug 管理平台,对告警的问题进行持续跟踪和问责。
  • 告警的规则要有说明文档(或操作手册),简明扼要的阐述警报规则的含义,以及当前问题的进度等(对应到 bug 管理平台上哪条记录)。

(3)告警策略的持续时间配置

  • Make this at least 5m (usually) ,即最小为 5分钟;
  • Make this at most 1h (usually),即最大不超过 1 小时

存储

(1)容量规划

  • Prometheus的数据存储分为本地存储和远端存储两种方式:本地存储读写性能好,但有存储容量限制。
  • 本地存储磁盘容量规划:需要磁盘容量=保留时间(秒)×每秒采样数×采样大小(字节数) ,一般情况下一个采样占用 1~2 个字节,另保留时间也是确定的。所以,减少容量主要通过每秒采样数来控:减少指标数量 或 增加采样的时间间隔,考虑到 Prometheus 会对时间序列进行压缩,所以减少指标数量效果更好。

(2)远端存储(待实践)

  • 如果存储到远端,则需要部署单独的插件:Remote Storage Adapter,由它将数据转到第三方存储服务中。(个人理解,即使开启了远端存储,本地存储仍然有数据的)

部署方案及高可用

(1)exporter

  • 一个进程一个 exporter,而不是一个节点有一个总的 exporter 进行汇聚,否则这个总的代理 exporter 会成为瓶颈。

(2)pushgateway

  • 一般情况下不要用 pushgateway,除非是与机器或实例无关的批处理作业。

(3)自动化

  • 生产环境大量服务器下自动化部署 Prometheus 等组件:使用Ansible。
  • 在 kubernetes 云原生环境下需要用 Prometheus-operator 进行安装。

(4)HA 原则

  • 没到上千台服务实例的情况下,一般不需要进行服务的水平伸缩(提供单实例的内存和cpu,同时保证存储基本就够了)。

    A single Prometheus server can easily handle millions of time series. That's enough for a thousand servers with a thousand time series each scraped every 10 seconds. As your systems scale beyond that, Prometheus can scale too.

  • 一般情况下一个数据中心一个 Prometheus 就足够了,如果有多个数据中心,则每个数据中心一个 Prometheus 实例。
  • 多个数据中心的监控数据如果要聚合展示的话,可以配置一个全局的 Prometheus 实例,由它从各个数据中心的 Prometheus 实例中拉取数据即可。
  • 如果到了超大的集群规模,比如一个服务就有上千个实例,那时再考虑使用分片的 Prometheus 实例,即一个 Prometheus 实例监控一部分实例,再通过一个 leader Prometheus 进行聚合。

(5)Prometheus HA(待实践)

  • 联邦集群架构不是 HA 最佳实践(当然,也可以用)

    原因:Prometheus 设计之初的定位是实时监控系统;缺少统一的全局视图;未考虑历史数据的存储问题,也就缺失了对历史数据进行降准采样的能力。 架构参考图:
    prometheus-HA

  • 不要使用联邦集群来进行指标的同步,即将一个 prometheus 实例的数据全部同步到另一个 Prometheus 实例中。但可以使用联邦集群来同步指定指标的数据记录,比如其他团队的指标数据。

  • HA 集群解决方案推荐使用:Thanos (比联邦集群复杂)

    Thanos可实现Global query视图、Prometheus的HA以及持久存储能力,其官网部署图(sidecar 模式)如下:Thanos

(6)Alertmanager HA(待实践)

  • Alertmanager 引入 Gossip 协议,为多个Alertmanager之间提供了信息传递的机制。确保即使在多个Alertmanager分别接收到相同告警信息的情况下,也只有一个告警通知被发送给Receiver。
    Alertmanager-HA

  • 具体实现,参考书籍《Prometheus监控技术与实践》第 14 章节。

日志监控

(1)处理流程

  • 日志监控首先需要进行格式化处理,然后通过类似 exporter 提供各种指标,最后由 Prometheus 进行抓取。

(2)主流实现方案

  • 常见的三种处理方式:mtail, fluentd + prometheus-plugin, grok_exporter,对比如下
  • mtail:由谷歌的SRE团队编写,功能强大,通过正则表达式自定义规则程序创建导出器的日志指标,官方网址。延伸:caching_exporternginx-prometheus-exporter
  • fluentd + prometheus-plugin:支持的指标比较少,对高级的正则表达式支持不太完善,官方网址
  • grok_exporter:导出的指标较少,并且一个文件需要运行一个实例,不太方便,官方网址

参考链接