机器学习训练任务的成功率突然暴跌25%,监控大屏却显示一切正常——这是Pinterest工程师去年面对的真实困境。问题藏在最不起眼的地方:一个默认开启却从未使用的系统代理,像僵尸一样在后台不断"繁殖",最终拖垮了整片计算集群的网络性能。

这场排查始于PinCompute平台的异常。作为Pinterest运行半数以上离线机器学习任务的Kubernetes底座,这里每月要拉起数万个Ray集群。但部分业务的训练成功率持续下滑,伴随而来的是弹性网络适配器(ENA)设备重置和数据包丢失。诡异的是,聚合层面的CPU利用率指标完全健康,故障被完美掩盖。

打开网易新闻 查看精彩图片

被迫离开高层监控面板后,基础设施团队下沉到单核粒度分析。借助mpstat工具,他们发现个别核心会周期性飙至100%系统CPU占用,每次持续数秒。这个细节至关重要:ENA驱动依赖NAPI轮询线程处理网络中断,一旦负责该任务的核心被饿死超过5秒,传输完成确认停滞,设备就会触发自愈重置——Ray作业随之崩溃。

为锁定元凶,工程师们在12小时的复现窗口内滚动采集了两分钟粒度的perf性能剖析数据。借助Netflix开源的Flamescope可视化工具,他们将时间轴精确对齐到网络重置发生的瞬间。异常清晰可见:kubelet进程——正常应低于1%CPU占用——正飙升至约6.5%,其中绝大部分时间消耗在内核函数mem_cgroup_nr_lru_pages中。

追溯至AWS深度学习AMI镜像后,真相浮出水面。该基础镜像默认启用了Amazon ECS代理,但Pinterest从未使用这项服务。这个代理处于持续崩溃重启的循环中,每次都在泄漏内存控制组(memcg)。当调查人员清点时发现,系统内堆积了近7万个"僵尸"memcg,而实际活跃使用的仅有240个。kubelet每次同步cgroup统计时都必须遍历这份膨胀的列表,单核因此被独占数秒之久。

修复方案本身并不复杂:在基础镜像中禁用ECS代理的systemd单元,并重启受影响的机器以清理已堆积的控制组。但达成这个结论需要穿透多层抽象——从应用表象到编排器行为,再到内核状态,最终定位到一个冗余的用户空间守护进程对内核资源的污染。

变更部署后,内存控制组数量保持稳定,ENA设备重置现象消失。Pinterest在复盘时指出,现代云原生栈的抽象层级往往成为故障排查的迷雾。当应用层表现为网络超时、编排层显示为作业失败、内核层呈现为中断处理延迟时,真正的根因可能潜伏在最基础的系统镜像配置中。

这次事件也暴露了监控体系的盲区。聚合指标在分布式系统中具有欺骗性,单核饱和完全可能被整体平均所稀释。团队最终依赖的是逐核分析和细粒度性能剖析的组合拳,而非传统仪表盘。

值得注意的是,Pinterest目前仍采用人工剖析的方式处理此类问题。技术博客的结尾暗示了自动化根因分析的方向——当系统复杂度超越人类排查的带宽时,让工具自动穿透抽象层级或许将成为必选项。但至少在这个案例中,工程师对内核行为的深度理解,仍是解开谜题的关键钥匙。