本篇主要介绍actor的定义、创建,应用及内部的运行机制。actor之间的调度是并行的,同一个actor上的运行是串行的。 actor是一个有状态的worker,其在python脚本中的表示形式就是把一个类定义为远程类。着重列举了actor的几个应用实例—actor并行和串行运行、用actor进行强化学习状态共享、在神经网络中应用和actor句柄的转递。其中的神经网络的例子可以作为一个典型的事例—tensorflow代码在在Ray中运行神经网络事例。最后actor的限制问题。
Actors
远程(remote) 函数在Ray中是功能性和实用性函数。将自己限制在远程函数中可以实现分布式函数编程,这对于许多用例来说都是很好的,但是在实践中却受到了一定的限制。
Ray使用actor扩展了数据流模型。actor本质上是一个有状态的worker(或服务)。当实例化一个新actor时,将创建一个新worker,并将acto的方法调度到该特定worker上,并且可以访问该worker并更改其状态。
actor的形式之一是把一个类前面加上@ray.remote
,这个类就变成一个actor,还有其他的定义actor的形式把一个类作为参数传到ray.remote(类A)
。
假设我们已经启动Ray。
import ray
ray.init()
定义和创建一个actor
下面的例子,用ray.remote
装饰一个Counter
类作为一个actor。
@ray.remote
class Counter(object):
def __init__(self):
self.value = 0
def increment(self):
self.value += 1
return self.value
可是通过Counter.remote()
来实例化这个actor 。
a1 = Counter.remote()
a2 = Counter.remote()
实例化参与者时,将发生以下事件。
- 选择集群中的一个节点,并在该节点上创建一个工作进程(由该节点上的本地调度程序创建),以便调用对参与者的方法。
- 在worker上创建一个Counter对象,并且运行Counter构造器。
actor的应用–并行和串行
我们可以通过调用actor的方法来调度它的任务。
a1.increment.remote() # ray.get returns 1
a2.increment.remote() # ray.get returns 1
当调用a1.increment.remote()
时,有下面事件发生。
- 创建一个任务。
- 任务由驱动程序的本地调度程序直接分配给负责actor的本地调度程序。
- 一个对象ID被返回。
通过ray.get(id)
来获取这个对象ID检索真实值。
类似地,我们调用a2.increment.remote()
在第二个Counter
actor上生成一个任务。
由于这两个任务运行在不同的actor上,所以它们可以并行执行(注意,只有actor方法在actor worker上调度,而常规远程函数不会)。
另一方面,在同