命名角色#
一个角色可以在其 命名空间 中被赋予一个唯一的名称。这允许您从 Ray 集群中的任何作业中检索该角色。如果您无法直接将角色句柄传递给需要它的任务,或者如果您尝试访问由另一个驱动程序启动的角色,这将非常有用。请注意,如果没有任何句柄存在,角色仍然会被垃圾回收。有关更多详细信息,请参阅 Actor 生命周期。
import ray
@ray.remote
class Counter:
pass
# Create an actor with a name
counter = Counter.options(name="some_name").remote()
# Retrieve the actor later somewhere
counter = ray.get_actor("some_name")
// Create an actor with a name.
ActorHandle<Counter> counter = Ray.actor(Counter::new).setName("some_name").remote();
...
// Retrieve the actor later somewhere
Optional<ActorHandle<Counter>> counter = Ray.getActor("some_name");
Assert.assertTrue(counter.isPresent());
// Create an actor with a globally unique name
ActorHandle<Counter> counter = ray::Actor(CreateCounter).SetGlobalName("some_name").Remote();
...
// Retrieve the actor later somewhere
boost::optional<ray::ActorHandle<Counter>> counter = ray::GetGlobalActor("some_name");
我们还支持C++中的非全局命名角色,这意味着角色名称仅在作业内有效,并且无法从另一个作业访问该角色。
// Create an actor with a job-scope-unique name
ActorHandle<Counter> counter = ray::Actor(CreateCounter).SetName("some_name").Remote();
...
// Retrieve the actor later somewhere in the same job
boost::optional<ray::ActorHandle<Counter>> counter = ray::GetActor("some_name");
备注
命名角色由命名空间限定。如果没有分配命名空间,它们将默认放置在匿名命名空间中。
import ray
@ray.remote
class Actor:
pass
# driver_1.py
# Job 1 creates an actor, "orange" in the "colors" namespace.
ray.init(address="auto", namespace="colors")
Actor.options(name="orange", lifetime="detached").remote()
# driver_2.py
# Job 2 is now connecting to a different namespace.
ray.init(address="auto", namespace="fruit")
# This fails because "orange" was defined in the "colors" namespace.
ray.get_actor("orange")
# You can also specify the namespace explicitly.
ray.get_actor("orange", namespace="colors")
# driver_3.py
# Job 3 connects to the original "colors" namespace
ray.init(address="auto", namespace="colors")
# This returns the "orange" actor we created in the first job.
ray.get_actor("orange")
import ray
class Actor {
}
// Driver1.java
// Job 1 creates an actor, "orange" in the "colors" namespace.
System.setProperty("ray.job.namespace", "colors");
Ray.init();
Ray.actor(Actor::new).setName("orange").remote();
// Driver2.java
// Job 2 is now connecting to a different namespace.
System.setProperty("ray.job.namespace", "fruits");
Ray.init();
// This fails because "orange" was defined in the "colors" namespace.
Optional<ActorHandle<Actor>> actor = Ray.getActor("orange");
Assert.assertFalse(actor.isPresent()); // actor.isPresent() is false.
// Driver3.java
System.setProperty("ray.job.namespace", "colors");
Ray.init();
// This returns the "orange" actor we created in the first job.
Optional<ActorHandle<Actor>> actor = Ray.getActor("orange");
Assert.assertTrue(actor.isPresent()); // actor.isPresent() is true.
获取或创建命名角色#
一个常见的用例是仅在不存在时创建一个actor。Ray为actor创建提供了一个``get_if_exists``选项,可以开箱即用地实现这一点。这个方法在你通过``.options()``为actor设置名称后可用。
如果角色已经存在,将返回对该角色的句柄,并且参数将被忽略。否则,将使用指定的参数创建一个新角色。
import ray
@ray.remote
class Greeter:
def __init__(self, value):
self.value = value
def say_hello(self):
return self.value
# Actor `g1` doesn't yet exist, so it is created with the given args.
a = Greeter.options(name="g1", get_if_exists=True).remote("Old Greeting")
assert ray.get(a.say_hello.remote()) == "Old Greeting"
# Actor `g1` already exists, so it is returned (new args are ignored).
b = Greeter.options(name="g1", get_if_exists=True).remote("New Greeting")
assert ray.get(b.say_hello.remote()) == "Old Greeting"
// This feature is not yet available in Java.
// This feature is not yet available in C++.
Actor 生命周期#
此外,演员的生命周期可以与作业分离,使得演员在作业的驱动进程退出后仍然可以持续存在。我们称这些演员为 分离的。
counter = Counter.options(name="CounterActor", lifetime="detached").remote()
即使运行上述脚本的驱动程序退出,CounterActor
也会保持活动状态。因此,可以在不同的驱动程序中运行以下脚本:
counter = ray.get_actor("CounterActor")
请注意,一个角色可以被命名但不能被分离。如果我们只指定了名称而没有指定 lifetime="detached"
,那么 CounterActor 只能在原始驱动程序仍在运行时被检索。
System.setProperty("ray.job.namespace", "lifetime");
Ray.init();
ActorHandle<Counter> counter = Ray.actor(Counter::new).setName("some_name").setLifetime(ActorLifetime.DETACHED).remote();
即使运行上述进程的驱动程序退出后,CounterActor 仍将保持活动状态。因此,可以在不同的驱动程序中运行以下代码:
System.setProperty("ray.job.namespace", "lifetime");
Ray.init();
Optional<ActorHandle<Counter>> counter = Ray.getActor("some_name");
Assert.assertTrue(counter.isPresent());
自定义 actor 的生命周期在 C++ 中尚未实现。
与普通角色不同,分离的角色不会被 Ray 自动垃圾回收。一旦确定不再需要分离的角色,必须手动销毁。为此,使用 ray.kill
来 手动终止 该角色。在此调用之后,角色的名称可以被重新使用。