对象容错#

Ray 对象同时包含数据(调用 ray.get 时返回的值)和元数据(例如,值的存储位置)。数据存储在 Ray 对象存储中,而元数据存储在对象的所有者处。对象的所有者是创建原始 ObjectRef 的 worker 进程,例如通过调用 f.remote()ray.put()。请注意,此 worker 通常与创建对象的 worker 进程不同,ray.put 的情况除外。

import ray
import numpy as np


@ray.remote
def large_array():
    return np.zeros(int(1e5))


x = ray.put(1)  # The driver owns x and also creates the value of x.

y = large_array.remote()
# The driver is the owner of y, even though the value may be stored somewhere else.
# If the node that stores the value of y dies, Ray will automatically recover
# it by re-executing the large_array task.
# If the driver dies, anyone still using y will receive an OwnerDiedError.

Ray 可以自动从数据丢失中恢复,但不能从所有者故障中恢复。

从数据丢失中恢复#

当对象值从对象存储中丢失时,例如在节点故障期间,Ray 将使用血缘重建来恢复对象。Ray 将首先自动尝试通过在其他节点上查找同一对象的副本进行恢复。如果找不到副本,则 Ray 将通过重新执行先前创建该值的任务来自动恢复该值。任务的参数通过相同的机制进行递归重建。

血缘重建目前存在以下限制

  • 对象及其任何传递依赖项必须由任务(actor 或非 actor)生成。这意味着 ray.put 创建的对象不可恢复

  • 任务被假定为确定性和幂等的。因此,默认情况下,actor 任务创建的对象不可重建。要允许重建 actor 任务结果,请将 max_task_retries 参数设置为非零值(更多详细信息请参阅actor 容错)。

  • 任务只会重试达到其最大重试次数。默认情况下,非 actor 任务最多可重试 3 次,而 actor 任务不可重试。这可以通过远程函数max_retries 参数和actormax_task_retries 参数进行覆盖。

  • 对象的所有者必须仍然存活(参见下文)。

血缘重建可能导致驱动程序内存使用量高于平时,因为驱动程序会保留在发生故障时可能需要重新执行的任何任务的描述。要限制血缘使用的内存量,请设置环境变量 RAY_max_lineage_bytes(默认 1GB),如果超出阈值,则会驱逐血缘信息。

要完全禁用血缘重建,请在 ray startray.init 期间设置环境变量 RAY_TASK_MAX_RETRIES=0。在此设置下,如果没有对象的副本剩余,将抛出 ObjectLostError 异常。

从所有者故障中恢复#

对象的所有者可能由于节点或 worker 进程故障而死亡。目前,Ray 不支持从所有者故障中恢复。在这种情况下,Ray 将清理对象值的任何剩余副本,以防止内存泄漏。任何后续尝试获取对象值的 worker 都将收到 OwnerDiedError 异常,可以手动处理该异常。

理解 ObjectLostErrors#

当由于应用或系统错误导致无法检索对象时,Ray 会向应用抛出 ObjectLostError 异常。这可能在调用 ray.get() 或获取任务参数时发生,可能有多种原因。以下是理解不同错误类型根本原因的指南:

  • OwnerDiedError: 对象的所有者(即首次通过 .remote()ray.put() 创建 ObjectRef 的 Python worker)已死亡。所有者存储关键的对象元数据,如果该进程丢失,则无法检索对象。

  • ObjectReconstructionFailedError: 如果对象或此对象依赖的另一对象由于上文所述的限制之一而无法重建,则会抛出此错误。

  • ReferenceCountingAssertionError: 对象已被删除,因此无法检索。Ray 通过分布式引用计数实现自动内存管理,因此通常不会发生此错误。但是,存在一个已知边缘情况,可能导致此错误。

  • ObjectFetchTimedOutError: 节点尝试从远程节点检索对象副本时超时。此错误通常表示系统级 bug。可以使用 RAY_fetch_fail_timeout_milliseconds 环境变量(默认 10 分钟)配置超时时长。

  • ObjectLostError: 对象已成功创建,但没有可到达的副本。当禁用血缘重建且对象的所有副本都从集群中丢失时,会抛出此通用错误。