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