管理环境

关键在于,您的每个 dask 工作进程在使用 Dask 执行代码时,必须使用相同的一套 python 软件包和模块。连接到分布式 Client 后,Dask 会自动检查一些关键软件包(包括 Dask 本身)的版本,并警告您任何不匹配的情况。

您在 Dask 上运行的大多数函数都需要导入。即使传递任何不是 python 内建的对象也是如此 - pickle 序列化方法会保存对导入模块的引用,而不是尝试发送所有源代码。

因此,您必须确保工作进程能够访问您需要的所有模块,理想情况下版本也完全相同。

单机调度器

如果您使用线程调度器,则无需执行任何操作,因为工作进程在同一个进程中,对象只需共享而无需序列化和反序列化。

类似地,如果您使用多进程调度器,新进程将从原始进程复制,或者以与原始进程相同的方式启动,因此您只需确保没有更改与启动 python 和导入代码相关的环境变量(例如 PATH、PYTHONPATH、sys.path)。

如果您在单机上使用分布式调度器,这大致相当于使用上面的多进程调度器,如果您使用 Client(...)LocalCluster(...) 启动。

但是,如果您从命令行启动工作进程,则必须确保在相同的环境中运行(virtualenv、pipenv 或 conda)。

本页的其余部分仅涉及分布式集群。

保持环境一致

如果您自己管理环境,那么设置模块一致性可以像在每台机器上从相同的 pip 或 conda 规范创建环境一样简单。您应该查阅 pippipenvconda 的文档,无论您通常使用哪种。您通常会希望尽可能具体地指定软件包版本,并在安装前将相同的环境文件分发给工作进程。

但是,其他常见的直接分发环境(而不是在原地构建)的方法包括:

  • docker 镜像,其中环境已构建到镜像中;这是在 docker 支持的基础设施(如 kubernetes)上运行时常用的方法。

  • conda-pack 是一个用于打包现有 conda 环境的工具,以便可以将它们迁移到其他机器。此工具专为 YARN/hadoop 集群上的 dask 创建,但也可以用于其他地方。

  • 共享文件系统,例如 NFS,所有机器都可以看到。请注意,导入 python 模块的 IO 密集度相当高,因此您的服务器需要能够处理大量请求。

  • 集群安装方法(例如 parcels):根据您的基础设施,可能有方法可以将特定二进制文件安装到集群中的所有工作进程上。

临时安装

工作进程插件 distributed.diagnostics.plugin.PipInstall 允许您在工作进程上运行 pip 安装命令,并可选择在成功后重启它们。请阅读插件文档了解如何使用此功能。

__main__ 中的对象

您创建的没有任何模块引用的对象,例如在 repl 或 notebook 单元格中直接定义的类,不会被 pickle 序列化时引用任何导入的模块。您可以重新定义此类对象,Dask 将完全序列化它们,包括源代码。这是在分布式设置中尝试新事物的好方法。

发送源代码

特别是在开发期间,您可能希望直接将文件发送到已经在运行的工作进程。

在这些情况下,您应该使用 client.upload_file。有关更多详细信息,请参阅 API 文档 和 StackOverflow 问题 “Can I use functions imported from .py files in Dask/Distributed?”(我可以在 Dask/Distributed 中使用从 .py 文件导入的函数吗?)。此函数支持独立文件和用于更大模块的 setuptools .egg 文件。