强制Dask数据帧子集上的局部性

强制Dask数据帧子集上的局部性,dask,dask-distributed,Dask,Dask Distributed,我试图在多台机器上分发一个大型Dask数据帧,以便(稍后)在该数据帧上进行分布式计算。我正在使用分布式dask 我看到的所有dask分布式示例/文档都是从网络资源(hdfs、s3等)填充初始数据负载,似乎没有将DAG优化扩展到负载部分(似乎假设网络负载是一个必要的恶魔,只会消耗初始成本)。这在另一个问题的答案中得到强调: 然而,我可以看到我们希望这样做的情况。例如,如果我们在这个数据库的节点上有一个分片数据库+dask工作区,那么我们希望强制将仅来自本地分片的记录填充到本地dask工作区。从文档

我试图在多台机器上分发一个大型Dask数据帧,以便(稍后)在该数据帧上进行分布式计算。我正在使用分布式dask

我看到的所有dask分布式示例/文档都是从网络资源(hdfs、s3等)填充初始数据负载,似乎没有将DAG优化扩展到负载部分(似乎假设网络负载是一个必要的恶魔,只会消耗初始成本)。这在另一个问题的答案中得到强调:

然而,我可以看到我们希望这样做的情况。例如,如果我们在这个数据库的节点上有一个分片数据库+dask工作区,那么我们希望强制将仅来自本地分片的记录填充到本地dask工作区。从文档/示例来看,网络交叉似乎是一种必然的假设成本是否可以强制从特定工作人员处获取单个数据帧的部分内容?

我已经尝试过的另一种方法是,尝试并强制每个工作者运行一个函数(迭代提交给每个工作者),其中该函数只加载该机器/碎片的本地数据。这是可行的,我有一堆具有相同列模式的最佳局部数据帧——然而——现在我没有一个数据帧,而是n个数据帧是否可以跨多台计算机合并/融合数据帧,以便有一个数据帧引用,但各部分与特定计算机具有亲缘关系(在合理范围内,由任务DAG决定)?

您可以生成dask“集合”,例如来自未来和延迟对象的数据帧,它们之间相互配合得很好

对于每个分区,您知道哪台机器应该加载它,您可以生成一个未来,如下所示:

f = c.submit(make_part_function, args, workers={'my.worker.ip'})
其中
c
是dask客户机,地址是您希望看到它发生的机器。您还可以给出
allow\u other\u workers=True
这是一个首选项而不是要求

要制作一个数据帧,从这样的未来列表中,您可以

df = dd.from_delayed([dask.delayed(f) for f in futures])

理想情况下,提供一个
meta=
,给出预期数据帧的描述。现在,在给定分区上的进一步操作更倾向于在已保存数据的同一个工作进程上进行调度。

我还希望能够将计算限制到特定节点(以及本地化到该节点的数据)。我试图用一个简单的脚本(见下文)实现上述内容,但查看结果数据帧,结果是错误(来自dask/dataframe/utils.py::check_meta()):

例如:

from dask.distributed import Client
import dask.dataframe as dd
import dask

client = Client(address='<scheduler_ip>:8786')
client.restart()

filename_1 = 'http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv'
filename_2 = 'http://samplecsvs.s3.amazonaws.com/SalesJan2009.csv'

future_1 = client.submit(dd.read_csv, filename_1, workers='w1')
future_2 = client.submit(dd.read_csv, filename_2, workers='w2')

client.has_what()
# Returns: {'tcp://<w1_ip>:41942': ('read_csv-c08b231bb22718946756cf46b2e0f5a1',),
#           'tcp://<w2_ip>:41942': ('read_csv-e27881faa0f641e3550a8d28f8d0e11d',)}

df = dd.from_delayed([dask.delayed(f) for f in [future_1, future_2]])

type(df)
# Returns: dask.dataframe.core.DataFrame

df.head()
# Returns:
#      ValueError: Metadata mismatch found in `from_delayed`.
#      Expected partition of type `DataFrame` but got `DataFrame`
来自dask.distributed import客户端
将dask.dataframe作为dd导入
进口达斯克
客户机=客户机(地址=':8786')
client.restart()
文件名\u 1=http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv'
文件名\u 2=http://samplecsvs.s3.amazonaws.com/SalesJan2009.csv'
future_1=client.submit(dd.read_csv,文件名_1,workers='w1')
future_2=client.submit(dd.read_csv,filename_2,workers='w2')
客户,你有什么
#返回:{'tcp://:41942':('read_csv-c08b231bb22718946756cf46b2e0f5a1',),
#‘tcp://:41942’:(‘读取csv-e27881faa0f641e3550a8d28f8d0e11d’)
df=dd.from_delayed([future_1,future_2]]中f的[dask.delayed(f)])
类型(df)
#返回:dask.dataframe.core.dataframe
df.head()
#返回:
#ValueError:在“from\u delayed”中发现元数据不匹配。
#应为'DataFrame'类型的分区,但得到'DataFrame'`
注意dask环境有两个工作节点(别名为w1和w2)和一个调度程序节点,脚本在外部主机上运行。
dask==1.2.2,distributed==1.28.1

并行调用许多dask数据帧函数是很奇怪的。也许你是想同时打电话给很多熊猫

# future_1 = client.submit(dd.read_csv, filename_1, workers='w1')
# future_2 = client.submit(dd.read_csv, filename_2, workers='w2')
future_1 = client.submit(pandas.read_csv, filename_1, workers='w1')
future_2 = client.submit(pandas.read_csv, filename_2, workers='w2')
有关更多信息,请参阅

# future_1 = client.submit(dd.read_csv, filename_1, workers='w1')
# future_2 = client.submit(dd.read_csv, filename_2, workers='w2')
future_1 = client.submit(pandas.read_csv, filename_1, workers='w1')
future_2 = client.submit(pandas.read_csv, filename_2, workers='w2')