Ray 究竟是如何与工人共享数据的?

Posted

技术标签:

【中文标题】Ray 究竟是如何与工人共享数据的?【英文标题】:How exactly does Ray share data to workers? 【发布时间】:2020-01-24 16:18:45 【问题描述】:

有许多简单的教程以及 SO 问题和答案声称 Ray 以某种方式与工作人员共享数据,但这些都没有详细说明如何在哪个操作系统上共享数据。

例如在这个 SO 答案中:https://***.com/a/56287012/1382437 一个 np 数组被序列化到共享对象存储中,然后被多个访问相同数据的工作人员使用(从该答案复制的代码):

import numpy as np
import ray

ray.init()

@ray.remote
def worker_func(data, i):
    # Do work. This function will have read-only access to
    # the data array.
    return 0

data = np.zeros(10**7)
# Store the large array in shared memory once so that it can be accessed
# by the worker tasks without creating copies.
data_id = ray.put(data)

# Run worker_func 10 times in parallel. This will not create any copies
# of the array. The tasks will run in separate processes.
result_ids = []
for i in range(10):
    result_ids.append(worker_func.remote(data_id, i))

# Get the results.
results = ray.get(result_ids)

ray.put(data) 调用将数据的序列化表示放入共享对象存储中,并为它传回句柄/id。

然后当worker_func.remote(data_id, i) 被调用时,worker_func 被传递反序列化的数据。

但是这两者之间究竟发生了什么?显然,data_id 用于定位数据的序列化版本并对其进行反序列化。

Q1:当数据“反序列化”时,是否总是会创建原始数据的副本?我想是的,但我不确定。

一旦数据被反序列化,它就会被传递给工作人员。现在,如果需要将相同的数据传递给另一个工作人员,有两种可能性:

Q2:当一个已经反序列化的对象被传递给一个工作者时,它是通过另一个副本还是完全相同的对象?如果它是完全相同的对象,这是否使用标准共享内存方法在进程之间共享数据?在 Linux 上,这意味着写时复制,那么这是否意味着一旦对象被写入,就会创建它的另一个副本?

Q3: 一些教程/答案似乎表明,根据数据类型(Numpy 与非 Numpy),反序列化和在工作人员之间共享数据的开销有很大不同,那么详细信息是什么?那里?为什么 numpy 数据共享更有效,并且当客户端尝试写入该 numpy 数组时这仍然有效(我认为这总是会为进程创建一个本地副本?)?

【问题讨论】:

【参考方案1】:

Ray 在内部运行一个 redis 服务器来跨进程共享数据。

如果你想了解更多,redis 是在 localhost 中打开一个端口来获取/放置数据,与多个进程通信。基本上,所有数据都必须是“字符串”或“字符串列表”。所以ray也实现了redis的序列化/反序列化。

【讨论】:

谢谢!您能否更详细地解释一下序列化是如何完成的以及何时复制数据?请参阅原始问题中的 Q1、Q2、Q3。我发现了这个arrow.apache.org/blog/2017/10/15/…,它解释了一些基础知识,但没有解释箭头如何与redis交互,以及何时可以使用零拷贝读取/共享内存 Q1,是的,它会创建一个副本(序列化,作为字符串)。例如,之前你有 ndarray[1, 1, 1],现在你有 "ndarray, [1, 1, 1]" 字符串。此字符串存储到 Redis 服务器(独立)Q2 中,对于“完全相同的对象”,如果您的意思是指针指向相同的内存地址,那么答案是否定的,worker 没有获得相同的内存地址。相反,worker 获取字符串“ndarray, [1, 1, 1]”,然后将其反转(反序列化)为 new ndarray [1, 1, 1]。不知道第三季度。 谢谢。我认为这并不完全正确,请参阅我发布的链接“Arrow 支持零拷贝读取,因此对象可以自然地存储在共享内存中并供多个进程使用”。这就是我想要详细说明的原因。

以上是关于Ray 究竟是如何与工人共享数据的?的主要内容,如果未能解决你的问题,请参考以下文章

请高手解答在windows7中的为此网络启用联邦信息处理标准(FIPS)兼容究竟是啥意思大神们帮帮忙

漫画秒懂区块链(Blockchain)究竟是什么

Android:如何在使用相同证书签名的项目之间共享代码

在 gunicorn 工人之间共享一把锁

ShellExecute成功后返回值究竟是啥?

内存数据库究竟是如何发挥内存优势的?