请参与 Prometheus 用户调研(2026 年 3 月版) ,帮助社区确定未来开发工作的优先级!

ShowMax 访谈

2016年5月1日作者 Brian Brazil

这是 Prometheus 用户系列访谈的第二篇,旨在分享用户在评估和使用 Prometheus 过程中的经验。

您能介绍一下您自己以及 ShowMax 是做什么的吗?

我是 Antonin Kral,目前负责 ShowMax  的研发与架构工作。在此之前,我在过去 12 年里一直担任架构师和 CTO 职务。

ShowMax 是一家订阅制视频点播服务商,于 2015 年在南非推出。我们的内容目录非常丰富,拥有超过 20,000 集电视剧和电影。目前,我们的服务覆盖全球 65 个国家。当那些更知名的竞争对手在欧美市场展开角逐时,ShowMax 正在攻克一个更艰巨的问题:如何在撒哈拉以南非洲几乎没有网络覆盖的村庄里流畅地刷剧?虽然全球 35% 的视频已经实现流媒体化,但仍有许多地方尚未被这场革命触及。

ShowMax logo

我们管理着约 50 个服务,它们大多运行在基于 CoreOS 构建的私有集群上。这些服务主要处理来自客户端(Android、iOS、AppleTV、JavaScript、三星电视、LG 电视等)的 API 请求,其中一些则用于内部。最大的内部流水线之一是视频编码,在处理大规模摄入批次时,它会占用 400 多台物理服务器。

我们的大多数后端服务使用 Ruby、Go 或 Python 编写。我们在编写 Ruby 应用时使用 EventMachine(MRI 上的 Goliath,JRuby 上的 Puma)。Go 通常用于需要高吞吐量且业务逻辑较少的应用。对于使用 Python 编写的服务,我们对 Falcon 非常满意。数据存储在 PostgreSQL 和 ElasticSearch 集群中。我们使用 etcd 和自定义工具来配置 Varnish 以进行请求路由。

在使用 Prometheus 之前,您的监控体验是怎样的?

监控系统的主要使用场景包括:

  • 主动监控和探测(通过 Icinga)
  • 指标采集以及基于这些指标的告警创建(现在使用 Prometheus)
  • 后端服务的日志采集
  • 应用生成的事件和日志采集

后两个场景由我们的日志基础设施处理。它由运行在服务容器中的收集器组成,该收集器监听本地 Unix socket。应用使用该 socket 将消息发送到外部。消息通过 RabbitMQ 服务器传输给消费者。消费者是自定义编写的或基于 hekad 构建的。主要的消息流之一是流向服务 ElasticSearch 集群,这使得日志可以被 Kibana 访问并进行即席查询。我们还将所有处理过的事件保存到 GlusterFS,用于存档和/或进一步处理。

我们过去曾并行运行两条指标采集流水线。第一条基于 Collectd + StatsD + Graphite + Grafana,另一条使用 Collectd + OpenTSDB。我们在两条流水线上都遇到了相当大的困难。我们不得不应对 Graphite 的 I/O 繁重,或者 OpenTSDB 的复杂性和工具支持不足的问题。

你们为什么决定研究 Prometheus?

在吸取了之前监控系统的教训后,我们寻找了替代方案。只有少数几个解决方案进入了我们的候选名单。Prometheus 是最早入选的之一,因为我们当时的运维负责人 Jiri Brunclik 收到了曾在 Google 工作的同事对该系统的个人推荐。

概念验证(PoC)进展非常顺利。我们很快就构建了一个可用的系统。我们也曾评估将 InfluxDB 作为主系统以及 Prometheus 的长期存储方案。但由于最近的发展,这可能不再是我们可行的选择。

你们是如何过渡的?

我们最初在其中一台服务服务器上使用 LXC 容器,但很快转向了 Hetzner 的专用服务器,我们的大多数服务都托管在那里。我们使用的是 PX70-SSD,配置为 Intel® Xeon® E3-1270 v3 四核 Haswell 处理器和 32GB 内存,因此我们有足够的算力来运行 Prometheus。SSD 使我们能够将数据保留时间设置为 120 天。我们的日志基础设施围绕本地获取日志(在 Unix socket 上接收)并将它们推送到各种 worker 节点而构建。

Diagram of ShowMax logging infrastructure. Shows flow of log messages from the source via processors to various consumers.

有了这种基础设施,推送指标(尤其是 Prometheus 出现之前)是一个合理的选择。另一方面,Prometheus 主要是围绕拉取指标的范式设计的。我们希望保持一致,起初将所有指标推送给 Prometheus。我们创建了一个名为 prometheus-pusher 的 Go 守护进程。它负责从本地导出器(exporters)抓取指标并将其推送到 Pushgateway。推送指标有一些积极的方面(例如简化了服务发现),但也有不少缺点(例如难以区分网络分区和崩溃的服务)。我们已将 prometheus-pusher 发布在 GitHub  上,您可以亲自试用。

Grafana dashboard showing April 5th 2016 log processors traffic.

接下来的步骤是找出用于管理仪表板和图表的工具。我们喜欢 Grafana 的集成,但不喜欢它管理仪表板配置的方式。我们是在 Docker 容器中运行 Grafana 的,因此任何更改都应该保存在容器之外。另一个问题是 Grafana 缺乏变更跟踪功能。

因此,我们决定编写一个生成器,它读取 git 中维护的 YAML 文件,并为 Grafana 仪表板生成 JSON 配置。此外,它还能够将仪表板部署到在一个全新容器中启动的 Grafana,而无需持久化容器内的更改。这为您提供了自动化、可重复性和审计能力。

我们很高兴地宣布,该工具现在也已在 Apache 2.0 许可证下发布在 GitHub  上。

切换后你们看到了哪些改进?

我们立即看到的一个改进是 Prometheus 的稳定性。在此之前,我们一直在为 Graphite 的稳定性和可扩展性而苦恼,因此解决这个问题对我们来说是一个巨大的胜利。此外,Prometheus 的速度和稳定性使得开发人员获取指标变得非常容易。Prometheus 确实正在帮助我们拥抱 DevOps 文化。

我们的后端开发人员之一 Tomas Cerevka 正在使用 JRuby 测试一个新版本的服务。他需要快速查看该特定服务的堆内存消耗情况。他瞬间就获取到了这些信息。对于我们来说,这种速度至关重要。

Heap size consumed by JRuby worker during troubleshooting memory issues on JVM.

您认为 ShowMax 和 Prometheus 的未来会怎样?

Prometheus 已成为 ShowMax 监控系统中不可或缺的一部分,在可预见的未来它都将陪伴我们。我们已经用 Prometheus 替换了全部的指标存储,但摄入链路仍然基于推送模式。因此,我们正在考虑遵循 Prometheus 的最佳实践,转向拉取(pull)模式。

我们已经尝试过告警功能。我们希望在这个主题上投入更多时间,并提出日益复杂的告警规则。