调试失败#

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

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

Ray API 是未来的 API(实际上,可以将 Ray 对象引用转换为标准的 Python 未来 API <async-ref-to-futures>),并且错误处理模型是相同的。当任何远程任务或角色失败时,返回的对象引用包含一个异常。当你调用 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。

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

  • 有意系统故障:这意味着 Ray 失败了,但这种失败是有意的。例如,当你调用取消 API 如 ``ray.cancel``(用于任务)或 ``ray.kill``(用于角色)时,系统会失败远程任务和角色,但这是有意的。

  • 非预期的系统故障:这意味着由于意外的系统故障(例如,由于内存不足错误导致的进程崩溃或节点故障),远程任务和参与者失败。

    1. Linux 内存不足杀手Ray 内存监控器 会终止高内存使用量的进程以避免内存不足。

    2. 机器关闭(例如,现场实例终止)或 raylet 崩溃(例如,由于意外故障)。

    3. 系统高度过载或压力过大(无论是机器还是系统组件,如 Raylet 或 GCS),这使得系统不稳定并可能导致失败。

调试应用程序故障#

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

打印#

print 调试是调试 Python 程序最常见的方法之一。默认情况下,Ray 的任务和 Actor 日志会打印到 Ray Driver,这允许你简单地使用 print 函数来调试应用程序故障。

调试器#

许多 Python 开发者使用调试器来调试 Python 程序,而 Python pdb) 是其中一种流行的选择。Ray 与 pdb 有原生集成。你只需在 Actors 和 Tasks 代码中添加 breakpoint() 即可启用 pdb。查看 Ray 调试器 了解更多详情。

文件描述符不足 (打开文件过多)#

在Ray集群中,任意两个系统组件可以相互通信并建立1个或多个连接。例如,一些工作节点可能需要与GCS通信以调度Actor(工作节点 <-> GCS连接)。您的驱动程序可以调用Actor方法(工作节点 <-> 工作节点连接)。

Ray 可以支持数千个 raylet 和数万个工作进程。当 Ray 集群变大时,每个组件可能会有越来越多的网络连接,这需要文件描述符。

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

Too may open files

对于头节点 GCS 进程来说,这种情况尤其常见,因为它是 Ray 中许多其他组件与之通信的集中式组件。当你看到这个错误信息时,我们建议你通过 ulimit 命令调整每个进程的最大文件描述符限制。

我们建议您将 ulimit -n 65536 应用于您的宿主机配置。不过,您也可以选择性地为 Ray 组件应用它(查看下方示例)。通常,每个工作线程有 2~3 个连接到 GCS。每个 raylet 有 1~2 个连接到 GCS。65536 个文件描述符可以处理 10000~15000 个工作线程和 1000~2000 个节点。如果您有更多的工作线程,您应该考虑使用高于 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)。

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

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

由于内存问题导致的失败#

查看 调试内存问题 了解更多详情。

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