调试故障#
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 因意外的系统故障而失败,例如进程崩溃(例如,因内存溢出错误)或节点故障。
Linux 内存溢出杀手 或 Ray 内存监控器 会杀死内存使用量过高的进程,以避免内存溢出。
机器关闭(例如,竞价实例终止)或 Raylet 崩溃(例如,因意外故障)。
系统负载过高或压力过大(无论是机器本身还是系统组件,如 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 时遇到的一些常见问题以及一些已知问题。如果你遇到其他问题,请告知我们。