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

监控 DreamHack——全球最大的数字盛会

2015年6月24日作者 Christian Svensson (DreamHack 网络团队)

编者按:本文是一篇由 Prometheus 用户撰写的客座博文。

如果你要为数万名挑剔的游戏玩家运营网络,你就必须真正了解网络内部正在发生什么。哦,对了,一切都需要在短短五天内从零开始构建。

如果你从未听说过 DreamHack ,这里简单介绍一下:它将 20,000 人聚集在一起,其中大多数人都会自带电脑。再加上职业电竞(eSports)、编程竞赛和现场音乐会,最终形成了全球最大的纯数字节日。

要实现这样的活动,必须有大量的配套基础设施。这种规模的常规基础设施建设通常需要几个月的时间,但 DreamHack 的工作人员在短短五天内就从零开始构建了一切。这当然包括配置网络交换机等工作,也包括铺设电力分配系统、搭建餐饮店,甚至亲手制作现场使用的桌子。

负责构建和运营网络相关所有事务的团队被正式称为“网络团队”(Network team),但我们通常自称为 techdhtech。本文将重点介绍 dhtech 的工作,以及我们在 2015 年夏季 DreamHack 期间如何使用 Prometheus 将监控水平提升到一个新的高度。

设备

事实证明,要为 10,000 多台电脑构建高性能网络,至少需要同等数量的网络端口。在我们的案例中,这些端口由约 400 台 Cisco 2950 交换机提供。我们称之为接入交换机(access switches)。它们分布在会场内所有参赛者就座的地方。

Access switches

*接入交换机整齐排列,准备以高速连接迎接 DreamHack 的参与者们。*

显然,仅仅将所有电脑连接到交换机是不够的。这些交换机还需要连接到其他交换机。这时就需要用到汇聚交换机(distribution switches,简称 dist switches)。这些交换机将来自所有接入交换机的数百个链路汇聚到更易于管理的 10-Gbit/s 高容量光纤中。随后,这些汇聚交换机再进一步接入我们的核心层,流量在那里被路由到目的地。

除此之外,我们还运营自己的 WiFi 网络、DNS/DHCP 服务器以及其他基础设施。完成后,我们的核心架构看起来就像下图这样。

Network planning map

*汇聚层和核心层的规划图。核心层在“D 厅”清晰可见*

总而言之,这已经成为了一个很长的监控列表,那么让我们言归正传:我们如何确保时刻掌握网络状况?

隆重推出:dhmon

dhmon 是我们系统的统称,它不仅监控网络,还允许其他团队收集他们所需的任何指标。

由于网络需要在五天内建成,监控系统必须易于部署,并能在我们进行最后时刻的基础设施更改(如增加或移除设备)时保持同步,这一点至关重要。当我们开始构建网络时,我们需要尽快启用监控,以便能够发现设备问题或其他我们未曾预料到的故障。

过去,我们尝试过使用多种常用软件的组合,例如 Cacti、SNMPc 和 Opsview 等。虽然这些工具能用,但它们往往是封闭的系统,且仅提供最基本的功能。几年前,团队中的一些人说:“够了,我们可以做得更好!”于是开始编写自定义的监控解决方案。

当时的选择有限。多年来,该系统经历了从使用 Graphite(扩展性问题)、自定义 Cassandra 存储(高复杂度)和 InfluxDB(软件不成熟)的过程,最终落地于 Prometheus。我是在 2014 年见到 Julius Volz 时第一次了解到 Prometheus 的,从那以后我就一直渴望尝试它。今年夏天,我们终于用 Prometheus 取代了之前编写的基于 InfluxDB 的度量指标存储。剧透一下:我们回不去了。

架构

该监控解决方案由三层组成:采集、存储和呈现。我们最关键的采集器是 snmpcollector (SNMP) 和 ipplan-pinger (ICMP),紧随其后的是 dhcpinfo(DHCP 租约统计)。我们还有一些脚本将其他系统的统计信息转储到 node_exporter  的文本文件采集器中。

dhmon Architecture

*2015 年夏季 dhmon 的当前架构规划*

我们使用 Prometheus 作为中央时序存储和查询引擎,但也使用 Redis 和 memcached 来导出我们收集的二进制信息的快照视图。这些数据无法以任何合理的方式存储在 Prometheus 中,或者我们需要在需要访问极新数据时使用。

其中一个案例是在我们的呈现层。我们使用 dhmap Web 应用程序来概览接入交换机的整体健康状况。为了有效地解决错误,我们需要从数据采集到呈现保持约 10 秒的延迟。我们的目标是在客户注意到之前,或者至少在他们走到支持人员那里报告问题之前解决问题。因此,从一开始我们就一直在使用 memcached 来访问网络的最新快照。

今年我们继续在低延迟数据上使用 memcached,而将 Prometheus 用于所有历史数据或对延迟不敏感的数据。做出这一决定仅仅是因为我们不确定 Prometheus 在极短采样间隔下的表现如何。最终,我们发现没有理由不在这些数据上也使用 Prometheus——我们肯定会在下次 DreamHack 时尝试用 Prometheus 取代 memcached。

dhmon Visualization

*由 dhmon 可视化的接入层概览*

Prometheus 设置

目前被称为 Prometheus 的模块实际上包含三个产品:Prometheus PromDash Alertmanager 。设置相当基础,这三个组件都运行在同一台主机上。所有服务均由 Apache Web 服务器提供,它仅充当反向代理。

ProxyPass /prometheus https://:9090/prometheus
ProxyPass /alertmanager https://:9093/alertmanager
ProxyPass /dash https://:3000/dash

探索网络

Prometheus 拥有一个强大的查询引擎,允许你对从网络各处收集的流式信息进行一些非常酷的操作。然而,有时查询需要处理过多的数据,无法在合理的时间内完成。当我们想要绘制总共约 18,000 个链路中利用率最高的 5 个链路时,就遇到了这种情况。虽然查询有效,但它大约需要花费我们设置的超时上限时间,这意味着它既慢又不稳定。我们决定使用 Prometheus 的 记录规则 (recording rules) 来预计算繁重的查询。

precomputed_link_utilization_percent = rate(ifHCOutOctets{layer!='access'}[10m])*8/1000/1000
                                         / on (device,interface,alias)
                                       ifHighSpeed{layer!='access'}

此后,运行 topk(5, precomputed_link_utilization_percent) 的速度变得极快。

被动式响应:告警

至此,我们已经有了一个可以查询网络状态的系统。既然我们是人类,我们不想把时间花在一直运行查询来看事情是否按预期运行上,所以显然我们需要告警。

例如:我们知道所有的接入交换机都使用 GigabitEthernet0/2 作为上行链路。有时,当网线在仓库中存放时间过长时,它们会氧化,导致无法协商出我们想要的 1000 Mbps 全速。

网络端口的协商速度可以在 SNMP OID IF-MIB::ifHighSpeed 中找到。不过,熟悉 SNMP 的人会意识到,这个 OID 是由任意接口索引建立索引的。为了理解这个索引,我们需要将其与 SNMP OID IF-MIB::ifDescr 中的数据进行交叉引用,以获取实际的接口名称。

幸运的是,我们的 snmpcollector 支持这种在生成 Prometheus 指标时的交叉引用。这使我们不仅可以轻松查询数据,还可以定义有用的告警。在我们的设置中,我们配置了 SNMP 采集,使用 ifDescr 注释 IF-MIB::ifTableIF-MIB::ifXTable OID 下的任何指标。当我们只需要指定我们只关心 GigabitEthernet0/2 端口而不在乎其他接口时,这就派上用场了。

让我们看看这样的告警定义是什么样子的。

ALERT BadUplinkOnAccessSwitch
  IF ifHighSpeed{layer='access', interface='GigabitEthernet0/2'} < 1000 FOR 2m
  SUMMARY "Interface linking at {{$value}} Mbps"
  DESCRIPTION "Interface {{$labels.interface}} on {{$labels.device}} linking at {{$value}} Mbps"

搞定!现在,如果交换机的上行链路突然以非最佳速度链接,我们就会收到告警。

再来看看 DHCP 范围几乎占满时的告警是什么样的

ALERT DhcpScopeAlmostFull
  IF ceil((dhcp_leases_current_count / dhcp_leases_max_count)*100) > 90 FOR 2m
  SUMMARY "DHCP scope {{$labels.network}} is almost full"
  DESCRIPTION "DHCP scope {{$labels.network}} is {{$value}}% full"

我们发现定义告警的语法非常容易阅读和理解,即使你之前没有任何 Prometheus 或时序数据库的经验。

Prometheus alerts for DreamHack

*糟糕!事实证明我们有一些不良的上行链路,最好跑过去修复它!*

主动式规划:仪表板

虽然告警是监控的重要组成部分,但有时你只是想对网络健康状况有一个很好的概览。为了实现这一点,我们使用了 PromDash。每当有人问我们关于网络的问题时,我们就编写一个查询来获取答案,并将其保存为仪表板小部件。然后,最有趣的那些被添加到我们自豪地展示的概览仪表板中。

dhmon Dashboard

*由 PromDash 提供支持的 DreamHack 概览仪表板*

未来

虽然改变任何系统的组成部分都是一项复杂的工作,我们很高兴能在一次活动中成功集成 Prometheus,但毫无疑问,仍有很多地方需要改进。有些领域非常基础:使用更多的预计算指标来提高性能、添加更多的告警以及调整现有的告警。另一个领域是让操作员的工作更轻松:创建一个适合我们网络运营中心 (NOC) 的告警仪表板,考虑是否要呼叫待命人员,或者仅仅让 NOC 升级告警。

我们计划添加的一些更大的功能:syslog 分析(我们有大量的 syslog!)、来自入侵检测系统的告警、与我们的 Puppet 设置集成,以及在 DreamHack 的不同团队之间进行更深入的集成。我们成功创建了一个概念验证,将电流传感器的电能数据接入到我们的监控中,从而很容易看出设备是故障了,还是仅仅断电了。我们还在努力与活动现场商店中使用的销售点系统集成。谁不想绘制冰淇淋的销售图表呢?

最后,团队运营的服务并非全部都在现场,有些在活动结束后仍 24/7 运行。我们也想用 Prometheus 监控这些服务,从长远来看,当 Prometheus 支持联邦时,利用非现场的 Prometheus 来复制来自活动现场 Prometheus 的指标。

结语

我们对 Prometheus 非常兴奋,它使从零开始建立可扩展的监控和告警变得如此简单。

向活动期间在 FreeNode 的 #prometheus 频道中帮助我们的每个人表示感谢。特别感谢 Brian Brazil、Fabian Reinartz 和 Julius Volz。感谢你们的帮助,即使是在我们明显没有仔细阅读文档的情况下。

最后,dhmon 是完全开源的,所以如果你有兴趣,请访问 https://github.com/dhtech/  查看。如果你觉得想参与其中,只需前往 QuakeNet  上的 #dreamhack 频道与我们聊天。谁知道呢,也许下一次 DreamHack 的构建你也能贡献一份力量?