AI资讯 3天前 更新于 10小时前 88

Pinterest 工程师消除 CPU 僵尸进程,解决生产环境瓶颈

Pinterest解决了其Kubernetes机器学习平台PinCompute上由间歇性CPU资源饥饿引发的任务崩溃问题。根本原因在于基础镜像中一个未使用的AWS ECS代理在崩溃循环中泄漏了大量“僵尸”内存控制组,导致kubelet进程周期性独占CPU核心。通过禁用该代理并重启机器,团队恢复了系统

85
热度
90
质量
92
影响力

深度分析

一、问题背景与现象:一个“看不见”的幽灵故障

Pinterest的分布式机器学习平台PinCompute基于Kubernetes,承载了公司超过一半的离线ML工作负载。该平台面临了一个棘手的故障:机器学习训练任务间歇性失败,成功率在某些场景下下降超过25%。伴随而来的症状是间歇性网络故障和任务崩溃。

问题的隐蔽性极强:

  • 表象正常,内里溃烂:传统的聚合监控仪表盘显示CPU总利用率一切正常,掩盖了底层严重的个别核心资源争夺。
  • 连锁反应:问题最终表现为弹性网络适配器(ENA)设备重置和数据包丢失,但这只是表层现象。

二、排查过程:抽丝剥茧,定位内核饱和

工程师的排查路径体现了系统化的深度诊断思维:

  1. 从宏观监控转向微观分析:由于高级仪表盘无效,团队转向使用 mpstat 进行逐核CPU使用分析,发现了关键线索:个别CPU内核的系统CPU使用率会持续数秒飙升至100%
  2. 理解故障传导链:工程师将点连成线,构建了清晰的因果链:
    • 内核饱和ENA网络中断处理的NAPI轮询线程受阻触发ENA设备重置(一种5秒超时的自愈机制)网络连接中断Ray分布式任务崩溃
  3. 精准捕获故障现场:团队利用在12小时重现窗口内每两分钟运行一次的性能数据捕获,并通过Netflix的Flamescope进行可视化。这让他们能精确观察到网络重置发生前一刹那的系统状态。
  4. 锁定可疑进程:可视化分析显示,在关键时刻,通常CPU占用不足1%的 kubelet 进程飙升至约6.5%,且其绝大部分时间消耗在内核函数 mem_cgroup_nr_lru_pages 中。这指向了与内存控制组(cgroup) 相关的问题。

三、根本原因:一个“僵尸”代理制造的资源泄漏

调查的终极发现揭示了问题的本质,其根源远超应用层:

  • 问题源头:用于创建节点的 AWS深度学习AMI(基础镜像) 中默认安装并启用了 Amazon ECS代理。然而,Pinterest的平台并未使用该代理
  • 关键机制:这个“无用”的代理在每次系统启动时都会陷入崩溃循环,并在崩溃过程中泄漏内存控制组(memcgs)
  • 量变引发质变:正常情况下活跃的memcgs仅约240个,但泄漏累积的 “僵尸”memcgs数量达到了近70,000个
  • 性能瓶颈kubelet 进程需要定期同步cgroup状态。当它被迫遍历这个极度膨胀的列表时,就会独占一个CPU内核长达数秒,从而触发上述整个故障链。

简单来说:一个被遗忘在系统镜像里的、不断崩溃的默认服务,其“垃圾”日积月累,最终“淹”死了负责系统管理的关键进程。

四、解决方案与深层启示

1. 解决方法:简单但需洞察力

  • 直接手段:在基础镜像中禁用了ECS代理的systemd服务单元,并重启受影响的节点以清理累积的“僵尸”cgroups。
  • 立竿见影:此后,内存cgroup数量稳定,网络重置现象消失。

2