不过它的架构具有通用的分布式统计抽象,可是它的架构具有通用的分布式统计抽象

Ray是UC BerkeleyRISELab新生产的高品质分布式执行框架,它选择了和观念分布式计算系统不等同的架构和对分布式总结的悬空格局,具有比斯Parker更完美的推断质量。

Ray是UC 伯克利RISELab新推出的高质量分布式执行框架,它选用了和观念分布式统计系统不一样等的架构和对分布式计算的架空格局,具有比斯Parker更非凡的计量品质。

Ray方今还处于实验室阶段,最新版本为0.2.2版本。即使Ray自称是面向AI应用的分布式总结框架,不过它的架构具有通用的分布式总计抽象。本文对Ray举办简单的介绍,协助大家更快地精晓Ray是怎样,如有描述不当的地点,欢迎不吝指正。

Ray近期还处于实验室阶段,最新版本为0.2.2版本。就算Ray自称是面向AI应用的分布式统计框架,可是它的架构具有通用的分布式统计抽象。本文对Ray举办简要的介绍,扶助大家更快地领悟Ray是什么,如有描述不当的地点,欢迎不吝指正。

一、简单开头

第一来看一下最不难易行的Ray程序是如何编写的。

# 导入ray,并初始化执行环境
import ray
ray.init()

# 定义ray remote函数
@ray.remote
def hello():
    return "Hello world !"

# 异步执行remote函数,返回结果id
object_id = hello.remote()

# 同步获取计算结果
hello = ray.get(object_id)

# 输出计算结果
print hello

在Ray里,通过Python注解@ray.remote定义remote函数。使用此声明注脚的函数都会自带一个默许的措施remote,通过此措施发起的函数调用都是以提交分布式义务的方法异步执行的,函数的再次来到值是一个对象id,使用ray.get松开操作能够协同获取该id对应的靶子。熟识Java里的Future机制的话对此相应并不生疏,或许会有人困惑那和一般性的异步函数调用没什么大的界别,不过此地最大的歧异是,函数hello是分布式异步执行的。

remote函数是Ray分布式总结抽象中的大旨概念,通过它开发者拥有了动态定制总计信赖(职分DAG)的能力。比如:

@ray.remote
def A():
    return "A"

@ray.remote
def B():
    return "B"

@ray.remote
def C(a, b):
    return "C"

a_id = A.remote()
b_id = B.remote()
c_id = C.remote(a_id, b_id)
print ray.get(c_id)

事例代码中,对函数A、B的调用是全然并行执行的,然则对函数C的调用信赖于A、B函数的回来结果。Ray可以有限支撑函数C需求等待A、B函数的结果真的计算出来后才会实施。若是将函数A、B、C类比为DAG的节点的话,那么DAG的边就是函数C参数对函数A、B总结结果的看重,自由的函数调用情势允许Ray可以肆意地定制DAG的结构和测算依赖关系。其余,提及一点的是Python的函数可以定义函数具有七个再次来到值,那也使得Python的函数更天然具备了DAG节点多入和多出的表征。

图片 1

一、简单初叶

第一来看一下最简单易行的Ray程序是何许编写的。

# 导入ray,并初始化执行环境
import ray
ray.init()

# 定义ray remote函数
@ray.remote
def hello():
    return "Hello world !"

# 异步执行remote函数,返回结果id
object_id = hello.remote()

# 同步获取计算结果
hello = ray.get(object_id)

# 输出计算结果
print hello

在Ray里,通过Python注解@ray.remote定义remote函数。使用此表明申明的函数都会自带一个默许的艺术remote,通过此措施发起的函数调用都是以提交分布式职责的法子异步执行的,函数的再次回到值是一个目的id,使用ray.get放手操作可以同步获取该id对应的靶子。熟识Java里的Future机制的话对此应当并不陌生,或许会有人怀疑这和平凡的异步函数调用没什么大的分别,然而此间最大的歧异是,函数hello是分布式异步执行的。

remote函数是Ray分布式总括抽象中的大旨概念,通过它开发者拥有了动态定制计算看重(职责DAG)的能力。比如:

@ray.remote
def A():
    return "A"

@ray.remote
def B():
    return "B"

@ray.remote
def C(a, b):
    return "C"

a_id = A.remote()
b_id = B.remote()
c_id = C.remote(a_id, b_id)
print ray.get(c_id)

事例代码中,对函数A、B的调用是全然并行执行的,可是对函数C的调用看重于A、B函数的回到结果。Ray可以确保函数C要求等待A、B函数的结果的确总结出来后才会执行。即使将函数A、B、C类比为DAG的节点的话,那么DAG的边就是函数C参数对函数A、B计算结果的借助,自由的函数调用方式允许Ray可以自由地定制DAG的布局和计量器重关系。其余,提及一点的是Python的函数能够定义函数具有七个再次回到值,那也使得Python的函数更自然具备了DAG节点多入和多出的风味。

图片 2

二、系统架构

Ray是运用什么的架构对分布式统计做出如上抽象的吗,一下付给了Ray的种类架构(来自Ray诗歌,参考文献1)。

图片 3

作为分布式计算系统,Ray依旧根据了卓绝的Master-Slave的宏图:Master负责全局协调和境况维护,Slave执行分布式计算义务。不过和价值观的分布式总括系统分裂的是,Ray使用了混合义务调度的思路。在集群陈设格局下,Ray启动了以下重点组件:

  1. GlobalScheduler:Master上启动了一个大局调度器,用于吸纳本地调度器提交的职分,并将义务分发给方便的本土任务调度器执行。
  2. RedisServer:Master上启动了一到多个RedisServer用于保存分布式职务的动静音讯(ControlState),包涵对象机器的投射、义务描述、职分debug音讯等。
  3. LocalScheduler:每个Slave上启动了一个地面调度器,用于提交任务到全局调度器,以及分配职责给当下机械的Worker进度。
  4. Worker:每个Slave上可以启动几个Worker进程执行分布式义务,并将计算结果存储到ObjectStore。
  5. ObjectStore:每个Slave上启动了一个ObjectStore存储只读数据对象,Worker可以由此共享内存的法门访问这个目的数据,那样能够使得地压缩内存拷贝和目的种类化开销。ObjectStore底层由Apache
    Arrow完结。
  6. Plasma:每个Slave上的ObjectStore都由一个名为Plasma的目的管理器进行田间管理,它可以在Worker访问本地ObjectStore上不存在的远程数据对象时,主动拉取其它Slave上的对象数据到当前机械。

亟需表明的是,Ray的舆论中提及,全局调度器可以启动一到七个,而眼前Ray的兑现文档里切磋的内容都是根据一个大局调度器的情况。我揣度可能是Ray尚在建设中,一些体制还未周到,后续读者可以小心此处的底细变化。

Ray的天职也是经过类似Spark中Driver的定义的方式展开付出的,有所差距的是:

  1. 斯Parker的Driver提交的是职分DAG,一旦付出则不行改变。
  2. 而Ray提交的是更细粒度的remote
    function,职务DAG着重关系由函数看重关系自由定制。

舆论给出的架构图里不曾画出Driver的定义,由此我在其基础上做了部分改动和扩张。

图片 4

Ray的Driver节点和和Slave节点启动的组件大致一样,但是却有以下分别:

  1. Driver上的劳作经过DriverProcess一般只有一个,即用户启动的PythonShell。Slave可以根据必要创造四个WorkerProcess。
  2. Driver只好交给任务,却不可能收到来自全局调度器分配的职分。Slave可以付出职务,也得以接到全局调度器分配的职分。
  3. Driver可以主动绕过全局调度器给Slave发送Actor调用任务(此处设计是还是不是成立尚不探讨)。Slave只可以吸收全局调度器分配的测算任务。

二、系统架构

Ray是运用什么的架构对分布式统计做出如上抽象的吗,一下付给了Ray的连串架构(来自Ray诗歌,参考文献1)。

图片 5

作为分布式计算系统,Ray如故根据了独立的Master-Slave的安插性:Master负责全局协调和气象维护,Slave执行分布式总结职务。可是和价值观的分布式总结系统分裂的是,Ray使用了错落义务调度的笔触。在集群安插形式下,Ray启动了以下重点零部件:

  1. GlobalScheduler:Master上启动了一个大局调度器,用于吸纳本地调度器提交的天职,并将职务分发给方便的当地义务调度器执行。
  2. RedisServer:Master上启动了一到多少个RedisServer用于保存分布式任务的情形音信(ControlState),包蕴对象机器的映照、任务描述、任务debug音信等。
  3. LocalScheduler:每个Slave上启动了一个本地调度器,用于提交任务到全局调度器,以及分配义务给当下机械的Worker进程。
  4. Worker:每个Slave上可以启动多个Worker进度执行分布式职责,并将计算结果存储到ObjectStore。
  5. ObjectStore:每个Slave上启动了一个ObjectStore存储只读数据对象,Worker可以因此共享内存的方法访问这么些目的数据,这样可以有效地回落内存拷贝和目的种类化开销。ObjectStore底层由Apache
    Arrow完结。
  6. Plasma:每个Slave上的ObjectStore都由一个名为Plasma的对象管理器进行田间管理,它可以在Worker访问本地ObjectStore上不存在的远程数据对象时,主动拉取别的Slave上的靶子数据到当前机械。

亟需表明的是,Ray的舆论中提及,全局调度器可以启动一到多少个,而眼前Ray的兑现文档里研究的情节都是基于一个大局调度器的情景。我估摸可能是Ray尚在建设中,一些体制还未周详,后续读者能够小心此处的底细变化。

Ray的天职也是透过类似Spark中Driver的概念的措施举办提交的,有所分化的是:

  1. 斯Parker的Driver提交的是义务DAG,一旦付出则不足变更。
  2. 而Ray提交的是更细粒度的remote
    function,职务DAG看重关系由函数看重关系自由定制。

舆论给出的架构图里从未画出Driver的概念,由此我在其基础上做了一部分改动和伸张。

图片 6

Ray的Driver节点和和Slave节点启动的零件差不离相同,但是却有以下分别:

  1. Driver上的工作进度DriverProcess一般唯有一个,即用户启动的PythonShell。Slave可以依据须要创建多少个WorkerProcess。
  2. Driver只好交给任务,却不可能接受来自全局调度器分配的义务。Slave可以提交职责,也可以接收全局调度器分配的天职。
  3. Driver可以主动绕过全局调度器给Slave发送Actor调用任务(此处设计是不是合理尚不研讨)。Slave只好接收全局调度器分配的乘除义务。

三、焦点操作

按照上述架构,我们简要研讨一下Ray中第一的操作和流程。

三、宗旨操作

基于上述架构,大家差不多商讨一下Ray中关键的操作和流程。

1. ray.init()

在PythonShell中,使用ray.init()可以在地面启动ray,包蕴Driver、HeadNode(Master)和若干Slave。

import ray
ray.init()

只如果直连已有的Ray集群,只须求指定RedisServer的地方即可。

ray.init(redis_address="<redis-address>")

当地启动Ray得到的输出如下:

>>> ray.init()
Waiting for redis server at 127.0.0.1:58807 to respond...
Waiting for redis server at 127.0.0.1:23148 to respond...
Allowing the Plasma store to use up to 13.7439GB of memory.
Starting object store with directory /tmp and huge page support disabled
Starting local scheduler with 8 CPUs, 0 GPUs

======================================================================
View the web UI at http://localhost:8888/notebooks/ray_ui62614.ipynb?token=7c253b0fd66fe41294d9f2c6739e3f002c1e76f6f59b99f5
======================================================================

{'object_store_addresses': [ObjectStoreAddress(name='/tmp/plasma_store73540254', manager_name='/tmp/plasma_manager78072648', manager_port=39874)], 'redis_address': '127.0.0.1:58807', 'local_scheduler_socket_names': ['/tmp/scheduler98624129'], 'webui_url': 'http://localhost:8888/notebooks/ray_ui62614.ipynb?token=7c253b0fd66fe41294d9f2c6739e3f002c1e76f6f59b99f5', 'node_ip_address': '127.0.0.1'}
>>> 

本地启动Ray时,可以见到Ray的WebUI的拜访地址。

1. ray.init()

在PythonShell中,使用ray.init()可以在地点启动ray,包括Driver、HeadNode(Master)和多少Slave。

import ray
ray.init()

万一是直连已有些Ray集群,只必要指定RedisServer的地点即可。

ray.init(redis_address="<redis-address>")

本土启动Ray得到的出口如下:

>>> ray.init()
Waiting for redis server at 127.0.0.1:58807 to respond...
Waiting for redis server at 127.0.0.1:23148 to respond...
Allowing the Plasma store to use up to 13.7439GB of memory.
Starting object store with directory /tmp and huge page support disabled
Starting local scheduler with 8 CPUs, 0 GPUs

======================================================================
View the web UI at http://localhost:8888/notebooks/ray_ui62614.ipynb?token=7c253b0fd66fe41294d9f2c6739e3f002c1e76f6f59b99f5
======================================================================

{'object_store_addresses': [ObjectStoreAddress(name='/tmp/plasma_store73540254', manager_name='/tmp/plasma_manager78072648', manager_port=39874)], 'redis_address': '127.0.0.1:58807', 'local_scheduler_socket_names': ['/tmp/scheduler98624129'], 'webui_url': 'http://localhost:8888/notebooks/ray_ui62614.ipynb?token=7c253b0fd66fe41294d9f2c6739e3f002c1e76f6f59b99f5', 'node_ip_address': '127.0.0.1'}
>>> 

地点启动Ray时,能够观望Ray的WebUI的走访地址。

2. ray.put()

使用ray.put()可以将Python对象存入本地ObjectStore,并且异步再次回到一个唯一的ObjectID。通过该ID,Ray可以访问集群中任一个节点上的靶子(远程对象通过查阅Master的目的表获得)。

目的一旦存入ObjectStore便不可更改,Ray的remote函数可以将平昔将该对象的ID作为参数传入。使用ObjectID作为remote函数参数,可以使得地减小函数参数的写ObjectStore的次数。

@ray.remote
def f(x):
    pass

x = "hello"

# 对象x往ObjectStore拷贝里10次
[f.remote(x) for _ in range(10)]

# 对象x仅往ObjectStore拷贝1次
x_id = ray.put(x)
[f.remote(x_id) for _ in range(10)]

2. ray.put()

使用ray.put()可以将Python对象存入本地ObjectStore,并且异步再次回到一个唯一的ObjectID。通过该ID,Ray可以访问集群中任一个节点上的对象(远程对象通过查看Master的目的表得到)。

对象一旦存入ObjectStore便不可改变,Ray的remote函数可以将直接将该对象的ID作为参数传入。使用ObjectID作为remote函数参数,可以使得地压缩函数参数的写ObjectStore的次数。

@ray.remote
def f(x):
    pass

x = "hello"

# 对象x往ObjectStore拷贝里10次
[f.remote(x) for _ in range(10)]

# 对象x仅往ObjectStore拷贝1次
x_id = ray.put(x)
[f.remote(x_id) for _ in range(10)]

3. ray.get()

使用ray.get()可以经过ObjectID获取ObjectStore内的靶子并将之转换为Python对象。对于数组类型的目的,Ray使用共享内存机制裁减数额的正片费用。而对于其他对象则必要将数据从ObjectStore拷贝到进程的堆内存中。

即使调用ray.get()操作时,对象尚未创造好,则get操作会阻塞,直到对象创立落成后赶回。get操作的要害流程如下:

  1. Driver或者Worker进度首先到ObjectStore内请求ObjectID对应的靶子数据。
  2. 万一当地ObjectStore没有相应的对象数据,本地对象管理器Plasma会检查Master上的目标表查看对象是还是不是存储其余节点的ObjectStore。
  3. 要是目标数据在其他节点的ObjectStore内,Plasma会发送网络请求将目的数据拉到本地ObjectStore。
  4. 倘诺目的数据还一直不创立好,Master会在对象创造已毕后文告请求的Plasma读取。
  5. 比方目的数据已经被有着的ObjectStore移除(被LRU策略删除),本地调度器会基于职分血缘关系执行对象的双重创立工作。
  6. 假使目标数据在本土ObjectStore可用,Driver或者Worker进度会通过共享内存的方法间接将对象内存区域映射到温馨的进度地址空间中,并反系列化为Python对象。

另外,ray.get()可以一遍性读取八个目标的数量:

result_ids = [ray.put(i) for i in range(10)]
ray.get(result_ids)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

3. ray.get()

使用ray.get()可以经过ObjectID获取ObjectStore内的对象并将之转换为Python对象。对于数组类型的靶子,Ray使用共享内存机制减弱多少的正片开支。而对于其他对象则须求将数据从ObjectStore拷贝到过程的堆内存中。

假诺调用ray.get()操作时,对象尚未创造好,则get操作会阻塞,直到对象创制达成后回来。get操作的要害流程如下:

  1. Driver或者Worker进程首先到ObjectStore内请求ObjectID对应的靶子数据。
  2. 万一当地ObjectStore没有相应的对象数据,本地对象管理器Plasma会检讨Master上的目的表查看对象是还是不是存储别的节点的ObjectStore。
  3. 即便目的数据在别的节点的ObjectStore内,Plasma会发送互连网请求将目的数据拉到本地ObjectStore。
  4. 即使目的数据还没有创设好,Master会在目的创造完结后通报请求的Plasma读取。
  5. 如若目的数据现已被所有的ObjectStore移除(被LRU策略删除),本地调度器会根据职务血缘关系执行对象的双重创建工作。
  6. 只要目的数据在本土ObjectStore可用,Driver或者Worker进程会通过共享内存的法门一向将目的内存区域映射到祥和的进度地址空间中,并反系列化为Python对象。

另外,ray.get()可以三回性读取八个对象的数量:

result_ids = [ray.put(i) for i in range(10)]
ray.get(result_ids)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

4. @ray.remote

Ray中运用申明@ray.remote可以声雅培个remote
function。remote函数时Ray的宗旨职分调度单元,remote函数定义后会立刻被连串化存储到RedisServer中,并且分配了一个唯一的ID,那样就确保了集群的具有节点都可以看出那一个函数的定义。

不过,这样对remote函数定义有了一个隐秘的渴求,即remote函数内即使调用了别样的用户函数,则必须提前定义,否则remote函数不可以找到相应的函数定义内容。

remote函数内也得以调用其余的remote函数,Driver和Slave每回调用remote函数时,其实都是向集群提交了一个计算职务,从此间也可以看来Ray的分布式总括的自由性。

Ray中调用remote函数的主要流程如下:

  1. 调用remote函数时,首先会创设一个义务目标,它含有了函数的ID、参数的ID或者值(Python的主题对象直接传值,复杂对象会先通过ray.put()操作存入ObjectStore然后归来ObjectID)、函数再次来到值对象的ID。
  2. 职责目的被发送到本地调度器。
  3. 地面调度器决定任务目的是在该地调度照旧发送给全局调度器。假使任务目的的信赖(参数)在地面的ObejctStore已经存在且当地的CPU和GPU统计资源富集,那么地点调度器将义务分配给当地的WorkerProcess执行。否则,职分目标被发送给全局调度器并蕴藏到义务表(TaskTable)中,全局调度器依据当前的天职景况信息决定将任务发给集群中的某一个当地调度器。
  4. 当地调度器收到职务目的后(来自地点的任务照旧全局调度分配的任务),会将其放入一个任务队列中,等待总计资源和本土看重满意后分配给WorkerProcess执行。
  5. Worker收到任务目标后执行该职分,并将函数重回值存入ObjectStore,并立异Master的对象表(ObjectTable)音讯。

@ray.remote诠释有一个参数num_return_vals用以表明remote函数的重返值个数,基于此落成remote函数的多再次来到值机制。

@ray.remote(num_return_vals=2)
def f():
    return 1, 2

x_id, y_id = f.remote()
ray.get(x_id)  # 1
ray.get(y_id)  # 2

@ray.remote诠释的另一个参数num_gpus能够为天职指定GPU的资源。使用内置函数ray.get_gpu_ids()可以收获当前任务可以动用的GPU音讯。

@ray.remote(num_gpus=1)
def gpu_method():
    return "This function is allowed to use GPUs {}.".format(ray.get_gpu_ids())

4. @ray.remote

Ray中使用注脚@ray.remote可以声飞鹤个remote
function。remote函数时Ray的基本义务调度单元,remote函数定义后会马上被体系化存储到RedisServer中,并且分配了一个唯一的ID,那样就保证了集群的具有节点都得以看到那些函数的概念。

可是,那样对remote函数定义有了一个潜在的要求,即remote函数内假如调用了其它的用户函数,则必须超前定义,否则remote函数不可能找到呼应的函数定义内容。

remote函数内也得以调用其余的remote函数,Driver和Slave每一回调用remote函数时,其实都是向集群提交了一个总结职分,从此间也得以看来Ray的分布式总结的自由性。

Ray中调用remote函数的基本点流程如下:

  1. 调用remote函数时,首先会成立一个任务目的,它包蕴了函数的ID、参数的ID或者值(Python的基本对象直接传值,复杂对象会先通过ray.put()操作存入ObjectStore然后归来ObjectID)、函数再次来到值对象的ID。
  2. 职分目的被发送到本地调度器。
  3. 地点调度器决定职分目标是在地方调度仍然发送给全局调度器。如若职分目的的依靠(参数)在地面的ObejctStore已经存在且当地的CPU和GPU计算资源丰盛,那么当地调度器将义务分配给地点的WorkerProcess执行。否则,职责目的被发送给全局调度器并蕴藏到职务表(TaskTable)中,全局调度器依据当下的任务状态音讯决定将职责发给集群中的某一个当地调度器。
  4. 当地调度器收到职分目的后(来自本地的义务仍然全局调度分配的天职),会将其放入一个职分队列中,等待总括资源和本地看重满足后分配给WorkerProcess执行。
  5. Worker收到职责目的后执行该职责,并将函数重返值存入ObjectStore,并更新Master的靶子表(ObjectTable)音信。

@ray.remote申明有一个参数num_return_vals用来讲明remote函数的再次回到值个数,基于此已毕remote函数的多再次来到值机制。

@ray.remote(num_return_vals=2)
def f():
    return 1, 2

x_id, y_id = f.remote()
ray.get(x_id)  # 1
ray.get(y_id)  # 2

@ray.remote声明的另一个参数num_gpus能够为天职指定GPU的资源。使用内置函数ray.get_gpu_ids()能够收获当前职责可以动用的GPU音信。

@ray.remote(num_gpus=1)
def gpu_method():
    return "This function is allowed to use GPUs {}.".format(ray.get_gpu_ids())

5. ray.wait()

ray.wait()操作帮忙批量的职分等待,基于此可以落成四回性取得多少个ObjectID对应的数目。

# 启动5个remote函数调用任务
results = [f.remote(i) for i in range(5)]
# 阻塞等待4个任务完成,超时时间为2.5s
ready_ids, remaining_ids = ray.wait(results, num_returns=4, timeout=2500)

上述例子中,results包蕴了5个ObjectID,使用ray.wait操作能够平昔等待有4个任务完毕后赶回,并将不辱任务的数额对象放在第二个list类型重回值内,未形成的ObjectID放在第四个list重临值内。即便设置了晚点时间,那么在逾期时间截至后仍未等到预期的再次来到值个数,则已逾期已毕时的再次来到值为准。

5. ray.wait()

ray.wait()操作协理批量的天职等待,基于此可以完结四回性取得多少个ObjectID对应的数量。

# 启动5个remote函数调用任务
results = [f.remote(i) for i in range(5)]
# 阻塞等待4个任务完成,超时时间为2.5s
ready_ids, remaining_ids = ray.wait(results, num_returns=4, timeout=2500)

上述例子中,results包括了5个ObjectID,使用ray.wait操作可以直接等候有4个义务到位后回到,并将不负众望的数码对象放在首个list类型重回值内,未到位的ObjectID放在第四个list重返值内。若是设置了晚点时间,那么在逾期时间停止后仍未等到预期的重临值个数,则已过期达成时的重回值为准。

6. ray.error_info()

使用ray.error_info()可以取得职责执行时暴发的错误新闻。

>>> import time
>>> @ray.remote
>>> def f():
>>>     time.sleep(5)
>>>     raise Exception("This task failed!!")
>>> f.remote()
Remote function __main__.f failed with:

Traceback (most recent call last):
  File "<stdin>", line 4, in f
Exception: This task failed!!


  You can inspect errors by running

      ray.error_info()

  If this driver is hanging, start a new one with

      ray.init(redis_address="127.0.0.1:65452")
>>> ray.error_info()
[{'type': 'task', 'message': 'Remote function \x1b[31m__main__.f\x1b[39m failed with:\n\nTraceback (most recent call last):\n  File "<stdin>", line 4, in f\nException: This task failed!!\n', 'data': '{\'function_id\': "Hm\\xde\\x93\'\\x91\\xce\\x13ld\\xf4O\\xd7\\xce\\xc2\\xe1\\x151\\x1e3", \'function_name\': u\'__main__.f\'}'}]

6. ray.error_info()

使用ray.error_info()可以博得职责履行时发生的错误音讯。

>>> import time
>>> @ray.remote
>>> def f():
>>>     time.sleep(5)
>>>     raise Exception("This task failed!!")
>>> f.remote()
Remote function __main__.f failed with:

Traceback (most recent call last):
  File "<stdin>", line 4, in f
Exception: This task failed!!


  You can inspect errors by running

      ray.error_info()

  If this driver is hanging, start a new one with

      ray.init(redis_address="127.0.0.1:65452")
>>> ray.error_info()
[{'type': 'task', 'message': 'Remote function \x1b[31m__main__.f\x1b[39m failed with:\n\nTraceback (most recent call last):\n  File "<stdin>", line 4, in f\nException: This task failed!!\n', 'data': '{\'function_id\': "Hm\\xde\\x93\'\\x91\\xce\\x13ld\\xf4O\\xd7\\xce\\xc2\\xe1\\x151\\x1e3", \'function_name\': u\'__main__.f\'}'}]

7. Actor

Ray的remote函数只好处理无状态的计量要求,有动静的乘除要求须要动用Ray的Actor已毕。在Python的class定义前应用@ray.remote可以评释Actor。

@ray.remote
class Counter(object):
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1
        return self.value

行使如下格局创设Actor对象。

a1 = Counter.remote()
a2 = Counter.remote()

Ray创造Actor的流程为:

  1. Master接纳一个Slave,并将Actor创立职分分发给它的当地调度器。
  2. 创立Actor对象,并实施它的构造函数。

从流程能够见见,Actor对象的创始时互相的。

透过调用Actor对象的法子运用Actor。

a1.increment.remote()  # ray.get returns 1
a2.increment.remote()  # ray.get returns 1

调用Actor对象的点子的流程为:

  1. 先是创设一个任务。
  2. 该任务被Driver间接分配到开创该Actor对应的本土执行器执行,这几个操作绕开了全局调度器(Worker是或不是也足以行使Actor直接分配职责尚存疑问)。
  3. 重回Actor方法调用结果的ObjectID。

为了保障Actor状态的一致性,对同一个Actor的措施调用是串行执行的。

7. Actor

Ray的remote函数只可以处理无状态的揣摸须要,有状态的计量须求须要运用Ray的Actor完结。在Python的class定义前应用@ray.remote能够申明Actor。

@ray.remote
class Counter(object):
    def __init__(self):
        self.value = 0

    def increment(self):
        self.value += 1
        return self.value

采纳如下形式成立Actor对象。

a1 = Counter.remote()
a2 = Counter.remote()

Ray创立Actor的流程为:

  1. Master接纳一个Slave,并将Actor创立任务分发给它的地点调度器。
  2. 创办Actor对象,并进行它的构造函数。

从流水线可以见见,Actor对象的创立即互动的。

经过调用Actor对象的方法应用Actor。

a1.increment.remote()  # ray.get returns 1
a2.increment.remote()  # ray.get returns 1

调用Actor对象的点子的流程为:

  1. 先是创立一个义务。
  2. 该职责被Driver直接分配到开创该Actor对应的地点执行器执行,那一个操作绕开了全局调度器(Worker是不是也足以应用Actor间接分配职务尚存疑问)。
  3. 回到Actor方法调用结果的ObjectID。

为了有限支撑Actor状态的一致性,对同一个Actor的措施调用是串行执行的。

四、安装Ray

一经只是使用Ray,可以运用如下命令直接设置。

pip intall ray

即使急需编译Ray的流行源码进行设置,根据如下步骤进行(马克斯OS):

# 更新编译依赖包
brew update
brew install cmake pkg-config automake autoconf libtool boost wget
pip install numpy cloudpickle funcsigs click colorama psutil redis flatbuffers cython --ignore-installed six
# 下载源码编译安装
git clone https://github.com/ray-project/ray.git
cd ray/python
python setup.py install
# 测试
python test/runtest.py

# 安装WebUI需要的库[可选]
pip install jupyter ipywidgets bokeh

# 编译Ray文档[可选]
cd ray/doc
pip install -r requirements-doc.txt
make html
open _build/html/index.html

自我在MacOS上安装jupyter时,遭逢了Python的setuptools库不能升迁的景色,原因是MacOS的安全性设置难题,可以动用如下情势缓解:

  1. 重启电脑,启动时按住Command+R进入Mac尊崇形式。
  2. 开拓命令行,输入指令csrutils disable关闭系统安全策略。
  3. 重启电脑,继续安装jupyter。
  4. 设置到位后,重复如上的方法执行csrutils enable,再度重启即可。

进入PythonShell,输入代码本地启动Ray:

import ray
ray.init()

浏览器内开辟WebUI界面如下:

图片 7

四、安装Ray

比方只是利用Ray,可以采取如下命令直接设置。

pip intall ray

若果需求编译Ray的风行源码举办设置,根据如下步骤进行(马克斯OS):

# 更新编译依赖包
brew update
brew install cmake pkg-config automake autoconf libtool boost wget
pip install numpy cloudpickle funcsigs click colorama psutil redis flatbuffers cython --ignore-installed six
# 下载源码编译安装
git clone https://github.com/ray-project/ray.git
cd ray/python
python setup.py install
# 测试
python test/runtest.py

# 安装WebUI需要的库[可选]
pip install jupyter ipywidgets bokeh

# 编译Ray文档[可选]
cd ray/doc
pip install -r requirements-doc.txt
make html
open _build/html/index.html

自己在MacOS上安装jupyter时,遭受了Python的setuptools库无法提高的意况,原因是MacOS的安全性设置难题,可以行使如下情势解决:

  1. 重启电脑,启动时按住Command+R进去Mac爱惜形式。
  2. 开辟命令行,输入指令csrutils disable关闭系统安全策略。
  3. 重启电脑,继续安装jupyter。
  4. 安装落成后,重复如上的不二法门履行csrutils enable,再度重启即可。

进去PythonShell,输入代码本地启动Ray:

import ray
ray.init()

浏览器内打开WebUI界面如下:

图片 8

参考资料

  1. Ray论文:Real-Time Machine Learning: The Missing
    Pieces
  2. Ray开发手册:http://ray.readthedocs.io/en/latest/index.html
  3. Ray源代码:https://github.com/ray-project/ray

参考资料

  1. Ray论文:Real-Time Machine Learning: The Missing
    Pieces
  2. Ray开发手册:http://ray.readthedocs.io/en/latest/index.html
  3. Ray源代码:https://github.com/ray-project/ray

相关文章