监控 DreamHack - 世界最大的数字节

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

编者注:本文是 Prometheus 用户撰写的客座文章。

如果您正在运营一个拥有数万名挑剔的游戏玩家的网络,您就需要真正了解网络内部的情况。哦,而且所有东西都需要在短短五天内从零开始构建。

如果您从未听说过 DreamHack ,那么它的核心理念是:聚集 20,000 人,让他们中的大多数自带电脑。混合专业游戏(电子竞技)、编程竞赛和现场音乐会。结果就是世界上最大的完全专注于数字内容的数字节。

要实现这样的活动,就需要有大量的基础设施。普通规模的基础设施需要数月才能建成,但 DreamHack 的团队却能在短短五天内从零开始构建所有东西。这当然包括配置网络交换机等工作,还要建设电力分配、设置食品和饮料商店,甚至建造实际的桌子。

负责构建和运营所有网络相关事宜的团队正式名称是网络团队,但我们通常称自己为techdhtech。这篇文章将重点介绍 dhtech 的工作以及我们在 2015 年 DreamHack 夏季活动中如何利用 Prometheus 来提升我们的监控水平。

设备

事实证明,要为 10,000 多台计算机构建高性能网络,您至少需要相同数量的网络端口。在我们的例子中,这些是大约 400 台 Cisco 2950 交换机。我们称它们为接入交换机。这些交换机遍布参与者将携带电脑就座的场馆。

Access switches

*整齐排列,接入交换机已准备好为 DreamHack 玩家提供高速连接。*

显然,仅仅将所有这些计算机连接到交换机是不够的。这些交换机还需要连接到其他交换机。这时就需要接入交换机(或称 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  的 textfile 收集器中。

dhmon Architecture

*dhmon 的当前架构图(截至 2015 年夏季)*

我们将 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 的记录规则来预计算重查询。

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?