You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ray集群无法在各节点均匀分配Worker导致头节点内存溢出崩溃

Ray集群单节点调度过载问题排查方案

问题背景

3台12CPU的私有化部署机器搭建Ray集群,单Actor分配1CPU,手动启动头节点和工作节点后,所有Worker持续被调度到头节点导致头节点内存耗尽崩溃,其余工作节点无调度负载。

头节点启动命令参考:

ray start --head --port=... --redis-shard-ports=... --node-manager-port=... --object-manager-port=... --min-worker-port=... --max-worker-port=... --ray-client-server-port=... --gcs-server-port=... --num-cpus=12

工作节点启动命令参考:

ray start --address='<HEAD_IP>' --redis-password='...' --node-manager-port=... --object-manager-port=...  --min-worker-port=... --max-worker-port=... --dashboard-port=... --gcs-server-port=... --num-cpus=12

排查解决步骤

按以下顺序逐一排查,绝大多数场景下前3步就能定位问题:

1. 确认工作节点是否真正接入集群

很多时候工作节点启动命令执行完无报错,但实际没有成功注册到集群,自然不会被分配任务:

  • 头节点执行ray status命令,查看输出的节点列表:
    • 如果总CPU数只有12,说明工作节点完全没接入,优先排查网络连通性:确认头节点和工作节点之间手动指定的所有端口(GCS端口、节点管理端口、对象管理端口、worker端口范围)没有被防火墙拦截,工作节点填写的头节点IP是内网可达的真实IP,禁止填127.0.0.1这类回环地址。
    • 检查工作节点/tmp/ray/session_latest/logs/路径下的raylet.out、gcs_server.out日志,排查是否存在连接拒绝、密码错误、版本不匹配的报错,这类问题都会直接导致节点注册失败。
    • 执行ray --version核对3台机器的Ray版本,注意:所有节点的Ray版本必须完全一致,哪怕是小版本差异都可能导致节点注册异常、无法接收任务。
  • 如果ray status能看到3个节点IP,但工作节点的可用CPU显示为0,先在对应工作节点执行ray stop --force清理残留进程,再重新执行启动命令。

2. 修正头节点资源配置

当前头节点启动参数中--num-cpus=12的配置,等于把所有CPU资源全开放给Worker调度,但头节点本身要运行GCS、Raylet、对象存储等核心管理进程,这些进程和Worker抢资源时很容易触发调度异常:

  • 调整头节点启动参数,给管理进程预留2核左右资源,把--num-cpus=12改成--num-cpus=10。
  • 所有节点启动时显式指定可用内存,不要用系统自动检测的数值:比如机器总内存64G的话,加参数--memory=50000000000(单位为字节),留10G以上给系统和管理进程;同时加--object-store-memory=10737418240给对象存储固定分配10G内存,避免对象存储无限制占用内存触发OOM。

3. 调整调度策略避免单节点堆积

老版本Ray默认的bin-pack调度策略会优先往已有负载的节点塞任务,直到节点资源耗尽才会调度到其他节点,由于Worker单进程内存占用高,很容易出现CPU还没占满、内存先耗尽的情况:

  • 全局开启分散调度:代码里初始化Ray连接时指定策略,示例:
    import ray
    ray.init(address="auto", scheduling_strategy="SPREAD")
    
  • 如果不想修改全局策略,也可以单独给高内存的Actor指定分散调度,在Actor装饰器加参数即可:
    @ray.remote(num_cpus=1, scheduling_strategy="SPREAD")
    class YourActor:
        pass
    

4. 排查错误的调度约束

如果前面的配置都没问题,检查代码里是否误加了调度限制:

  • 有没有给Actor指定只有头节点才有的自定义资源,比如调试时加的节点标签、特殊资源约束,工作节点没有对应标签的话,任务只会调度到头节点。
  • 有没有残留硬编码的节点指定逻辑,比如resources={"node:<头节点IP>": 0.01}这类强制指定节点运行的配置,调试结束后忘记删除。

5. 优化内存检测阈值避免崩溃

所有节点启动时加以下参数,提高内存异常响应速度,避免内存耗尽直接崩溃:

--memory-monitor-interval-ms=100
--raylet-death-on-oom=false

参数作用是把内存检测间隔缩短到100ms,内存达到阈值时优先触发任务迁移、对象驱逐,不会等内存完全耗尽导致raylet进程直接崩溃。


内容的提问来源于stack exchange,提问作者andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:18:27