设置RAY_memory_monitor_refresh_ms为0仍遇Ray内存不足(OOM)问题求助
问题:Ray+Modin集群处理GCS大数据集时Worker因OOM被杀死
我用Modin替代Pandas处理超内存数据集,本地16GB内存跑30GB数据没问题。现在为了提速,在GCP搭了基于Ray的Modin集群:7台n1-standard-2机器(单台约7GB内存),处理GCS上50GB的Parquet数据集(拆成多个40MB左右的小文件),打算先测这个配置再搞TB级数据。但读取数据集时,就算已经设置了相关环境变量,Worker还是因为OOM被杀死,错误信息如下:
(raylet) Refer to the documentation on how to address the out of memory issue: https://docs.ray.io/en/latest/ray-core/scheduling/ray-oom-prevention.html. Consider provisioning more memory on this node or reducing task parallelism by requesting more CPUs per task. To adjust the kill threshold, set the environment variable `RAY_memory_usage_threshold` when starting Ray. To disable worker killing, set the environment variable `RAY_memory_monitor_refresh_ms` to zero.
我的Ray初始化代码如下:
import modin.pandas as pd import ray import os pd.DEFAULT_NPARTITIONS=280 os.environ["MODIN_ENGINE"] = "ray" runtime_env = { 'env_vars': { "RAY_memory_monitor_refresh_ms": "0", "RAY_memory_usage_threshold": "3" } } ray.init(runtime_env=runtime_env, _plasma_directory="/tmp") df = pd.read_parquet("gs://test-data-set/parquets/")
解决建议
- 调整分区数量:当前设置的
pd.DEFAULT_NPARTITIONS=280过大,7台n1-standard-2每台2核,总核数14,分区数建议设为总核数的2-4倍(比如28-56)。过多分区会增加Ray调度开销,同时导致内存碎片化,更容易触发OOM。 - 修正环境变量生效方式:Ray的内存监控由raylet进程管理,
RAY_memory_monitor_refresh_ms和RAY_memory_usage_threshold需要在启动Ray集群时设置(比如启动head节点和worker节点的命令行中添加),而非Python代码的runtime_env。例如启动head节点时执行RAY_memory_monitor_refresh_ms=0 ray start --head ...,worker节点启动时同样带上这些环境变量。 - 修复无效的内存阈值参数:
RAY_memory_usage_threshold的有效值是0-1之间的比例(比如0.9代表内存占用达90%时触发),你设置的"3"是无效值,会被Ray忽略,这也是内存监控未被正确禁用的原因之一。 - 更换Plasma存储目录:
_plasma_directory="/tmp"如果是内存挂载的tmpfs,会占用节点内存,建议改为磁盘上的目录(如/data/plasma),避免Plasma对象存储消耗宝贵的节点内存。 - 优化Parquet读取参数:读取时指定
engine='pyarrow',并调整batch_size参数减少单批次内存占用;同时检查是否存在个别Parquet文件远大于40MB,导致单任务内存过载。 - 监控节点内存状态:通过Ray Dashboard查看各节点的内存占用情况,定位具体是哪个任务或节点触发的OOM,针对性调整资源分配。
内容的提问来源于stack exchange,提问作者tsh
相关产品推荐
相关产品推荐

