管理环境

Dask worker 在执行代码时使用相同的 Python 包和模块集至关重要,这样 Dask 才能正常工作。连接到分布式 Client 后,Dask 将自动检查一些关键包(包括 Dask 本身)的版本,并在版本不匹配时发出警告。

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

因此,您必须确保 worker 能够访问您需要的所有模块,并且最好版本完全一致。

单机调度器

如果您使用线程调度器,则无需执行任何操作,因为 worker 位于同一进程中,并且对象只是共享,而不是序列化和反序列化。

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

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

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

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

维护一致的环境

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

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

  • docker 镜像,其中环境已构建到镜像中;当您在支持 docker 的基础设施(例如 kubernetes)上运行时,这是通常的途径

  • conda-pack 是一个用于打包现有 conda 环境的工具,以便可以将它们重新定位到其他机器。此工具是专门为在 YARN/hadoop 集群上运行 Dask 而创建的,但也可用于其他地方

  • 共享文件系统,例如 NFS,所有机器都可以看到。请注意,导入 Python 模块的 I/O 相当密集,因此您的服务器需要能够处理许多请求

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

临时安装

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

__main__ 中的对象

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

发送源代码

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

在这些情况下,您应该使用 client.upload_file。有关更多详细信息,请参阅 API 文档 以及 StackOverflow 上的一个问题 “我可以在 Dask/Distributed 中使用从 .py 文件导入的函数吗?” 此函数支持独立的单个文件和 setuptools 的 .egg 文件,适用于较大的模块。