对象容错#
一个 Ray 对象既有数据(调用 ray.get
时返回的值)也有元数据(例如,值的位置)。数据存储在 Ray 对象存储中,而元数据存储在对象的 所有者 处。对象的所有者是创建原始 ObjectRef
的工作进程,例如通过调用 f.remote()
或 ray.put()
。请注意,这个工作进程通常与创建对象 值 的工作进程是不同的进程,除非在 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 将通过 重新执行 先前创建该值的任务来自动恢复该值。任务的参数通过相同的机制递归地重建。
谱系重建目前有以下限制:
该对象及其任何传递依赖项,必须由任务(角色或非角色)生成。这意味着 通过 ray.put 创建的对象是不可恢复的。
任务被假定为确定性和幂等的。因此,默认情况下,由actor任务创建的对象是不可重建的。要允许重建actor任务的结果,请将``max_task_retries``参数设置为非零值(更多详情请参见 actor故障容错)。
任务只会被重新执行到其最大重试次数。默认情况下,非角色任务最多可以重试3次,而角色任务不能重试。这可以通过
max_retries
参数为 远程函数 和max_task_retries
参数为 角色 来覆盖。对象的所有者必须仍然存活(参见 下文)。
谱系重建可能会导致比平时更高的驱动程序内存使用量,因为驱动程序会保留任何可能因故障而重新执行的任务的描述。为了限制谱系使用的内存量,请将环境变量 ``RAY_max_lineage_bytes``(默认1GB)设置为在超过阈值时驱逐谱系。
要完全禁用血统重建,请在 ray start
或 ray.init
期间设置环境变量 RAY_TASK_MAX_RETRIES=0
。使用此设置,如果某个对象的副本不再存在,将引发 ObjectLostError
。
从所有者故障中恢复#
对象的所有者可能因为节点或工作进程的失败而死亡。目前,Ray 不支持从所有者失败中恢复。在这种情况下,Ray 将清理对象值的任何剩余副本以防止内存泄漏。任何随后尝试获取对象值的工作者将收到一个 OwnerDiedError
异常,该异常可以手动处理。
理解 ObjectLostErrors
#
当由于应用程序或系统错误无法检索对象时,Ray 会向应用程序抛出 ObjectLostError
。这可能发生在 ray.get()
调用期间或获取任务参数时,并且可能由于多种原因发生。以下是了解不同错误类型根本原因的指南:
OwnerDiedError
: 对象的所有者,即通过.remote()
或ray.put()
首次创建ObjectRef
的 Python 工作者,已经死亡。所有者存储关键的对象元数据,如果此进程丢失,则无法检索对象。ObjectReconstructionFailedError
: 如果一个对象或该对象依赖的另一个对象由于上述 限制 无法重建,则会抛出此错误。ReferenceCountingAssertionError
: 该对象已被删除,因此无法检索。Ray 通过分布式引用计数实现自动内存管理,因此通常不应发生此错误。然而,存在一个 已知的边缘情况 可能会产生此错误。ObjectFetchTimedOutError
: 节点在尝试从远程节点获取对象副本时超时。此错误通常表明存在系统级错误。超时期限可以使用RAY_fetch_fail_timeout_milliseconds
环境变量进行配置(默认10分钟)。ObjectLostError
: 对象已成功创建,但没有副本是可访问的。这是一个通用错误,当禁用血统重建且对象的所有副本都从集群中丢失时抛出。