调试故障#

Ray 中存在哪些类型的故障?#

Ray 由两个主要 API 组成:.remote() 用于创建任务或 Actor,ray.get 用于获取结果。调试 Ray 意味着识别和修复由 .remote API 创建的、在远程进程中运行函数和类(任务和 Actor)时发生的故障。

Ray API 是未来的 API(事实上,可以将 Ray 对象引用转换为标准的 Python future API),并且错误处理模型相同。当任何远程任务或 Actor 失败时,返回的对象引用包含一个异常。当你对该对象引用调用 get API 时,它会抛出异常。

import ray
@ray.remote
def f():
    raise ValueError("it's an application error")

# Raises a ValueError.
try:
  ray.get(f.remote())
except ValueError as e:
  print(e)
...
ValueError: it's an application error

在 Ray 中,有三种类型的故障。更多详情请参见异常 API。

  • 应用故障:这意味着远程任务/Actor 因用户代码而失败。在这种情况下,get API 将抛出 RayTaskError,其中包含从远程进程抛出的异常。

  • 有意系统故障:这意味着 Ray 发生故障,但这种故障是预期的。例如,当你调用取消 API(如任务的 ray.cancel 或 Actor 的 ray.kill)时,系统会使远程任务和 Actor 失败,但这是有意的。

  • 无意系统故障:这意味着远程任务和 Actor 因意外的系统故障而失败,例如进程崩溃(例如,因内存溢出错误)或节点故障。

    1. Linux 内存溢出杀手Ray 内存监控器 会杀死内存使用量过高的进程,以避免内存溢出。

    2. 机器关闭(例如,竞价实例终止)或 Raylet 崩溃(例如,因意外故障)。

    3. 系统负载过高或压力过大(无论是机器本身还是系统组件,如 Raylet 或 GCS),导致系统不稳定并发生故障。

调试应用故障#

Ray 将用户代码分发到多台机器上的多个进程中。应用故障意味着用户代码中存在错误。Ray 提供了类似于调试单进程 Python 程序的调试体验。

print#

print 调试是调试 Python 程序最常用的方法之一。Ray 的任务和 Actor 日志默认会打印到 Ray Driver,这让你只需使用 print 函数即可调试应用故障。

调试器#

许多 Python 开发者使用调试器来调试 Python 程序,而 Python pdb) 是其中一种流行的选择。Ray 内建集成了 pdb。你只需在 Actor 和任务代码中添加 breakpoint() 即可启用 pdb。更多详情请参见 Ray 调试器

文件描述符不足 (Too many open files)#

在 Ray 集群中,任意两个系统组件都可以相互通信,并建立 1 个或多个连接。例如,一些 worker 可能需要与 GCS 通信以调度 Actor(worker <-> GCS 连接)。你的 Driver 可以调用 Actor 方法(worker <-> worker 连接)。

Ray 可以支持数千个 raylet 和数万个 worker 进程。当 Ray 集群变大时,每个组件的网络连接数量会增加,这需要文件描述符。

Linux 通常将每个进程的默认文件描述符限制为 1024。当组件的连接数超过 1024 时,可能会出现以下错误消息。

Too may open files

这在头节点 GCS 进程中尤其常见,因为它是一个中心化组件,Ray 中的许多其他组件都与它通信。当你看到此错误消息时,我们建议你通过 ulimit 命令调整每个进程的最大文件描述符限制。

我们建议你将 ulimit -n 65536 应用到你的主机配置中。但是,你也可以为 Ray 组件选择性地应用(见下面的示例)。通常,每个 worker 与 GCS 有 2~3 个连接。每个 raylet 与 GCS 有 1~2 个连接。65536 个文件描述符可以处理 10000~15000 个 worker 和 1000~2000 个节点。如果你有更多的 worker,你应该考虑使用比 65536 更大的数字。

# Start head node components with higher ulimit.
ulimit -n 65536 ray start --head

# Start worker node components with higher ulimit.
ulimit -n 65536 ray start --address <head_node>

# Start a Ray driver with higher ulimit.
ulimit -n 65536 <python script>

如果这不起作用,请通过运行 ulimit -Hn 仔细检查硬限制是否足够大。如果太小,你可以按以下方式增加硬限制(这些说明适用于 EC2)。

  • 通过运行以下命令,在系统范围内增加打开文件描述符的硬 ulimit。

    sudo bash -c "echo $USER hard nofile 65536 >> /etc/security/limits.conf"
    
  • 注销并重新登录。

内存问题导致的故障#

更多详情请参见 调试内存问题

本文档讨论了使用 Ray 时遇到的一些常见问题以及一些已知问题。如果你遇到其他问题,请告知我们