Hacking Limbo

Reading / Coding / Hacking

Prometheus 初体验

初步印象

首先,纠正发音,Prometheus 的音标是 /prəˈmiːθɪəs/,注意尾音是 ɪə 而不是 u:.

从官方文档和 Systems Monitoring with PrometheusMonitoring your Python with Prometheus 这两份 slides 得到的初步印象:

  1. 数据收集是 pull-based 而不是 push-based.
  2. Server 负责主动收集、存储并提供查询接口。
  3. Server 只支持单机部署,没有分布式方案,未来可能支持汇总多个 server 的数据(所谓 Federation)。
  4. Altermanager 根据 Server 的状态变化发送告警,但是这货暂时也没有 HA 方案。

关于 pull-based 的设计,见 Push vs Pull for Monitoring 一文的介绍. Prometheus 提供的接入方式有:

  1. 用对应语言的 client 库在代码里记录指标,通过单独运行的 HTTP server 暴露接口给 Prometheus Server. 有点怀疑在 Python uWSGI / Gunicorn 环境里是否可靠。

  2. 第三方服务(比如 Redis / MySQL 这些)通过额外的监控进程 (exporter) 提供数据,比较不喜欢一个服务一个监控进程的设计,部署起来太繁琐。

  3. 离线脚本之类的代码可以向 push gateway 发送数据。

  4. 通过各种 "bridge" 接收 collectd / StatsD / Graphite Collector 推送的数据。

根据上述信息拍脑袋想出来的架构:

prometheus-components

试用

在 macOS 上运行 Graphite 和 Prometheus, 然后在虚拟机里跑 collectd 和 node-exporter, 收集了大概一小时的 CPU 使用率数据,在 Grafana 里对照图表,目测差异不大。由于默认收集频率较高,某些时间点的数据变化看起来 Prometheus 更精准一点。

试用感受:

  • 查询语言略复杂,比如 node-exporter 收集了单位 interval 内每个 CPU 的使用时间,要想将其转换成直观的百分比,要用这样写:

    sum by (mode) (
      rate(
        node_cpu{instance='zerus',cpu=~'user|system|iowait'}[5m]
      )
    ) * 100
    /
    scalar(
      count(
        count by (cpu)(node_cpu{instance='zerus',cpu=~'user|system|iowait'})
      )
    )

    这种写法怎么可能靠看教程学会啊 🙄。

  • 查询速度没有想象中的快,不知道是机器性能问题,查询语句复杂度问题,还是它就这么慢。

  • Server 重启的话会丢掉 polling 间隙的数据,因为 exporter 只会提供当前数据,没有缓冲 / 暂存机制。

  • 每个 exporter 只负责收集特定的指标,这种设定挺烦的,要在服务器上运行 N 个 exporter, 部署和配置管理都略繁琐。除非自己重写一个 exporter 把各种指标收集的功能合并到一个服务里,要么写个 exporter supervisor 之类的工具。

  • exporter 的指标收集也实现得不完全,而且多数都依赖命令传递参数,没有配置文件。难以想象 SoundCloud 靠这些工具来监控线上服务(连 conntrack 指标都木有)。