PCIe 是当前使用最广泛的硬件高速总线接口,业界主流的 GPU、网卡、存储等系统几乎都通过 PCIe 总线和 CPU 通信,因此,对于大规模数据中心来说,PCIe 的稳定性和可维护性对整个数据中心的高可靠、高可用性至关重要。Facebook 在这篇文章里介绍了在数据中心里自动化监控、修复 PCIe 错误的经验,原文链接:How Facebook deals with PCIe faults to keep our data centers running reliably
得益于传输速率的持续提升,PCIe(Peripheral component interconnect express,高速串行计算机扩展总线标准)正在不断扩展计算的边界。现在 PCIe 支持更多的并行数据传输通道,同时在主板上占用的面积也越来越小。今天,基于 PCIe 连接的硬件可以支持更快的数据传输,是将组件连接到服务器的标准方式之一。
Facebook 的数据中心包含数以百万计的基于 PCIe 的硬件组件(包括基于 ASIC 的用于视频处理和 AI 推理的加速器、GPU、网卡和 SSD)直接连接到服务器主板上的 PCI 插槽,或者连接到类似于载卡(carrier card)的 PCIe 交换机上。
和其他硬件一样,基于 PCIe 的组件也容易发生不同类型的硬件、固件或软件相关故障,也有可能出现性能下降的情况。不同的组件和供应商、大量的故障以及规模化带来的挑战,使得基于 PCIe 的组件监控、数据收集和故障隔离具有很大的挑战性。
我们开发了一套系统来检测、诊断、补救和修复这些问题。自从有了这套系统,使我们的硬件系统更可靠、更有弹性,从而获得了更高的使用效率。我们相信,整个行业都可以从这些信息、策略中受益,并帮助围绕这一常见问题建立行业标准。
aFacebook 的数据中心采用了一系列基于 PCIe 的硬件组件
PCIe 故障定位工具
首先,我们简单介绍一下使用的工具:
- PCIcrawler[1][2]:一个开源的、基于 python 的命令行工具,可以用来显示、过滤和导出 PCI 或 PCIe 总线和设备的信息,包括 PCI 拓扑和 PCIe AER(Advanced Error Reporting,高级错误报告)错误。该工具可以生成可视化的树状报告,非常便于调试。同时可以输出方便机器解析的 JSON 格式报告,从而可以借助于分析工具使得 PCIcrawler 可以适用于大规模部署。
- MachineChecker[3]:一个用于从硬件角度快速评估服务器生产价值的内部工具。MachineChecker 帮助检测和诊断硬件问题。它可以作为命令行工具运行,也可以作为一个数据库或一项服务。
- 一个用于获取目标主机硬件配置的快照以及硬件模块的内部工具。
- 一个用于解析自定义 dmesg 和 SEL(System Event Logs,系统事件日志),从而可以检测和报告数百万台服务器上的 PCIe 错误的内部实用程序服务。该工具定期解析服务器上的日志,并在相应服务器上的文件上记录可纠正错误的发生率。速率记录为每 10 分钟、每 30 分钟、每小时、每 6 小时和每天。基于不同平台和服务的要求,此速率可以用于确定哪些服务器超过了配置的可容忍的 PCIe 错误修正率阈值。
- IPMI Tool[4]:一个用于管理和配置支持 IPMI(Intelligent Platform Management Interface,智能平台管理接口)的设备的工具。IPMI 是一个开放标准,用于对独立于主 CPU、BIOS 和操作系统的硬件进行监控、日志记录、恢复、管理和控制。主要用于手动提取 SEL(System Event Logs,系统事件日志),用于检测、调试和研究。
- OpenBMC[5]:一个用于拥有 BMC(Baseboard Management Controller,基板管理控制器)的嵌入式设备的 Linux 发行版。
- FBAR(Facebook auto remediation,Facebook 自动修复)[6]:一个系统以及一组守护进程,根据检测到的各个服务器上的软件和硬件信号自动执行代码。每天,在没有人为干预的情况下,FBAR 将故障服务器从生产环境中隔离,并向我们的数据中心团队发送物理硬件维修请求,因此孤立的故障不再成为问题。
- Scuba[7]: Facebook 开发的一个快速、可扩展、分布式内存数据库,在 Facebook 用于大多数实时分析数据管理系统。
PCIe 故障分析
PCIe 硬件组件(ASIC、网卡、SSD 等)的多样性使得分析 PCIe 相关问题成为一项艰巨的任务。这些组件有不同的供应商、固件版本,以及运行在上面的不同的应用程序。在此基础上,应用程序本身可能有不同的计算和存储需求、应用配置和容错需求。
通过利用上面列出的工具,我们一直在进行研究,从而解决这些挑战,并确定 PCIe 硬件故障和性能退化的根本原因。
有些问题是显而易见的。例如,即使特定服务器上只有一个实例,PCIe 的致命未修正错误也绝对会造成糟糕的后果。MachineChecker 可以检测到这一点,并标记出有问题的硬件(最终会把它替换掉)。
根据错误条件的不同,不可纠正错误进一步分为非致命错误和致命错误。非致命错误是指那些导致特定事务不可靠,但 PCIe 链接本身功能齐全的错误。而致命错误会导致链接本身不可靠。根据我们的经验,我们发现对于任何未纠正的 PCIe 错误,更换硬件组件(有时是主板)是最有效的行动。
其他问题在一开始看起来似乎无关紧要。例如,根据标准定义,PCIe-corrected 错误是可纠正的,并在实践中大多可以得到很好的纠正。可纠正的错误应该不会对接口的功能造成影响。然而,可纠正错误发生的频率很重要。如果发生频率超过了特定的阈值,就会导致某些应用程序出现不可接受的性能下降。
我们进行了深入的研究,将性能退化和系统失速与 PCIe 错误修正率关联起来。另一个挑战是确定合适的阈值,因为不同的平台和应用程序有不同的系统配置和需求。我们推出了 PCIe 错误日志服务,观察 Scuba 中的故障、关联事件、系统暂停和 PCIe 故障,以确定每个平台的阈值。我们发现,当 PCIe 错误修正率超过特定阈值时,替换硬件是最有效的解决方案。
PCIe 定义了两种错误报告模式:基线能力和 AER 能力。所有 PCIe 组件都需要基线能力,并提供最低定义的错误报告。AER 能力是通过一个 PCIe AER 扩展能力数据结构实现的,并提供更健壮的错误报告。PCIe AER 驱动程序提供了支持 PCIe AER 能力的基础设施,我们通过 PCIcrawler 来收集这些信息。
我们建议每个供应商应当采用 PCIe AER 功能和 PCIcrawler,而不是依赖自定义工具,因为供应商自定义工具缺乏通用性。自定义工具的信息很难被解析,因此更加难以维护。此外,采用自定义工具使得集成新的供应商、新的内核版本或新的硬件类型需要大量的时间和精力。
坏的(降级的)链路速度(通常是运行在预期速度的 1/2 或 1/4)和坏的(降级的)链路带宽(通常是运行在预期链路带宽的 1/2、1/4 甚至 1/8)是需要关注的另一类 PCIe 相关故障。因为硬件本身还在工作,只是没有达到的最佳状态,所以如果没有某种自动化工具,这些故障很难被检测到。
根据我们的大规模研究发现,这些故障大部分可以通过复位硬件组件来修复。这就是为什么我们在将硬件标记为故障之前首先会去尝试这种方法的原因。
由于这些故障中的一小部分可以通过重启硬件来修复,我们还记录了历史修复操作。我们有特殊的规则来识别经常出错的硬件。例如,如果同一台服务器上的相同硬件组件在预先确定的时间间隔内发生故障的次数达到预定义的阈值,经过预先确定的复位次数后,我们自动将其标记为故障并将其替换出去。如果替换组件不能解决问题,我们将不得不进一步替换主板。
我们还密切关注修复的趋势,以识别非典型故障率。例如,在一种情况下,通过使用自定义 Scuba 表的数据及其生成的可视化图表和时间线,我们找到了一个性能下降的根本原因,是由特定厂商发布的特定固件所造成的,然后我们与供应商合作推出了新的固件来修复这个问题。
同样重要的是,我们可以将补救和修复速率限制作为一个安全网,以防止代码中的 bug、配置错误等问题泄露到生产环境,如果对这些问题处理不当,有可能会导致服务中断等严重后果。
通过这个总体方案,我们已经能够覆盖硬件健康指标,并修复数千台服务器和服务器组件。我们每周都能够检测、诊断、补救和修复数百台服务器上的各种 PCIe 故障。
PCIe 故障处理流程
以下是我们识别和修复 PCIe 故障的过程分解:
- MachineChecker 作为服务定期运行在我们生产团队中的数百万硬件服务器和交换机上。检查范围包括 PCIe 链路速度、PCIe 链路带宽、以及 PCIe 未校正和已校正错误率。
- 对于特定的 PCIe 端口,我们使用 PCIcrawler 的 PCIe 拓扑信息找到它的上游父端口,两端合起来我们称为一条 PCIe 链路。
- 我们利用 PCIcrawler 的输出,而它依赖于泛型寄存器 LnkSta、LnkSta2、LnkCtl 和 LnkCtl2。
- 计算预期速率:expected_speed = min (upstream_target_speed, endpoint_capable_speed, upstream_capable_speed)。
- 计算当前速率:current_speed = min (endpoint_current_speed, upstream_current_speed)。
- Current_speed 必须等于 expected_speed。换句话说,我们应该让任何一端的当前速率等于可用速率、上游可用速率、下游可用速率和上游目标速率的最小值。
- 对于 PCIe 链路宽度的计算:expected_width = min(pcie_upstream_device capable_width, pcie_endpoint_device capable width)。
- 如果 expected_width 小于上游的当前宽度,我们将其标记为坏链接。
- PCIe 错误日志服务独立运行在我们的硬件服务器上,并以预先确定的格式(JSON)独立记录纠正和不可纠正错误的比率和它们的出现速率。
- MachineChecker 检查未修正的错误。即使只有一个未纠正的错误事件也将服务器定性为故障。
- 在其定期运行期间,MachineChecker 还在服务器上查找生成的文件,并根据 Configerator(Facebook 的配置管理系统)中预先配置的值来检查它们,以确定每个平台的阈值。如果速率超过设定的阈值,硬件将被标记为故障。这些阈值很容易根据平台进行调整。
- PCIcrawler 预装在我们所有的硬件服务器上,用以检查 PCIe AER 问题。
- 通过 Facebook 内部的硬件配置记录工具,可以关联 PCIe 地址到给定的硬件。
- MachineChecker 使用 PCIcrawler(获取链路宽度、链路速度和 AER 信息)和 PCIe 错误解析服务(通过 SEL 和 dmesg)来识别硬件问题并创建警报或告警。MachineChecker 利用我们内部工具提供的信息来识别与 PCIe 地址相关的硬件组件,并通过提供附加信息(如组件的位置、模块信息和供应商信息)来帮助数据中心管理员(他们可能需要替换硬件)。
- 应用开发工程师可以订阅这些警报或告警,并定制用于监视、告警、补救和自定义修复的工作流。
- 我们可以对所有告警的某个子集进行特定的修正,还可以对补救措施进行微调,并添加特殊的处理,例如,如果已知在某种特定情况下,可以将补救措施限制为固件升级。
- 如果修复完全失败,将自动创建硬件修复工单,以便数据中心管理员可以将坏的硬件组件或服务器替换为测试好的硬件组件或服务器。
- 我们在几个地方设置了速率限制,从而作为一个防止代码中的 bug、错误配置泄露到生产环境中去的安全网。这类问题如果处理不当,可能会导致服务中断。
我们已经能够覆盖硬件健康指标,并通过这种方式修复了数千台服务器和服务器组件。我们每周都能够检测、诊断、补救和修复数百台服务器上的各种 PCIe 故障。这使得我们的硬件更可靠、更有弹性、有更高的使用效率。
Reference:[4] https://github.com/ipmitool/
[5] https://github.com/openbmc/
[7] https://research.fb.com/wp-content/uploads/2016/11/scuba-diving-into-data-at-facebook.pdf
[1] https://github.com/facebook/pcicrawler
[2] https://engineering.fb.com/2020/08/05/open-source/pcicrawler/