在 Dataflow 中管理流水线依赖项

许多 Apache Beam 流水线都可以使用默认的 Dataflow 运行时环境运行。但是,某些数据处理使用场景使用其他库或类更有优势。在这些情况下,您可能需要管理流水线依赖项。

以下列表列出了一些您可能需要管理流水线依赖项的原因:

  • 默认运行时环境提供的依赖项不足以满足您的使用场景。
  • 默认依赖项存在版本冲突,或者包含与流水线代码不兼容的类和库。
  • 您需要为流水线固定到特定的库版本。
  • 您有一个 Python 流水线,需要使用一组一致的依赖项来运行。

管理依赖项的方式取决于您的流水线使用的是 JavaPython 还是 Go

Java

不兼容的类和库可能会导致 Java 依赖项问题。 如果您的流水线包含特定于用户的代码和设置,则代码不能包含混合版本的库。

Java 依赖项问题

如果您的流水线存在 Java 依赖项问题,则可能会发生以下错误之一:

  • NoClassDefFoundError:如果在运行时整个类都不可用,就会出现此错误。
  • NoSuchMethodError:如果类路径中的类使用不包含正确方法的版本或者方法签名发生变化,就会出现此错误。
  • NoSuchFieldError:如果类路径中的类在运行时使用没有必需字段的版本,就会出现此错误。
  • FATAL ERROR:当无法正确加载内置依赖项时,会发生此错误。 使用超级 JAR 文件(阴影)时,请勿在同一 JAR 文件中包含使用签名的库(如 Conscrypt)。

依赖项管理

为了简化 Java 流水线的依赖项管理,Apache Beam 使用物料清单 (BOM) 制品。BOM 可帮助依赖项管理工具选择兼容的依赖项组合。如需了解详情,请参阅 Apache Beam 文档中的 Java 版 Apache Beam SDK 依赖项

如需对流水线使用 BOM,并将其他依赖项明确添加到依赖项列表,请将以下信息添加到 SDK 工件的 pom.xml 文件中。如需导入正确的库 BOM,请使用 beam-sdks-java-google-cloud-platform-bom

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.beam</groupId>
      <artifactId>beam-sdks-java-google-cloud-platform-bom</artifactId>
      <version>LATEST</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>org.apache.beam</groupId>
    <artifactId>beam-sdks-java-core</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.beam</groupId>
    <artifactId>beam-runners-google-cloud-dataflow-java</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.beam</groupId>
    <artifactId>beam-sdks-java-io-google-cloud-platform</artifactId>
  </dependency>
</dependencies>

beam-sdks-java-core 工件仅包含核心 SDK。您需要将其他依赖项(例如 I/O 和运行程序)明确添加到依赖项列表。

Python

使用 Apache Beam Python SDK 运行 Dataflow 作业时,在以下场景中,依赖项管理非常有用:

  • 您的流水线使用 Python 软件包索引 (PiPy) 中的公开软件包,并且您希望远程提供这些软件包。
  • 您希望创建一个可重现的环境。
  • 为了缩短启动时间,您需要避免在运行时在工作器上安装依赖项。

定义 Python 流水线依赖项

虽然您可以使用单个 Python 脚本或笔记本编写 Apache Beam 流水线,但在 Python 生态系统中,软件通常以软件包的形式分发。为了便于维护流水线,当流水线代码跨越多个文件时,请将流水线文件分组为 Python 软件包。

  • 在软件包的 setup.py 文件中定义流水线的依赖项。
  • 使用 --setup_file 流水线选项将软件包暂存到工作器。

远程工作器启动时,会安装您的软件包。如需查看示例,请参阅 Apache Beam GitHub 中的 juliaset

如需将流水线构建为 Python 软件包,请按以下步骤操作:

  1. 为您的项目创建一个 setup.py 文件。在 setup.py 文件中,添加 install_requires 参数来为流水线指定数目最少的一组依赖项。以下示例展示了一个基本的 setup.py 文件。

    import setuptools
    
    setuptools.setup(
      name='PACKAGE_NAME',
      version='PACKAGE_VERSION',
      install_requires=[],
      packages=setuptools.find_packages(),
    )
    
  2. setup.py 文件(主工作流文件)以及包含其余文件的目录添加到项目的根目录中。此文件分组是流水线的 Python 软件包。文件结构类似如下示例:

    root_dir/
      package_name/
        __init__.py
        my_pipeline_launcher.py
        my_custom_transforms.py
        ...other files...
      setup.py
      main.py
    
  3. 如需运行流水线,请在提交环境中安装该软件包。使用 --setup_file 流水线选项将软件包暂存到工作器。例如:

    python -m pip install -e .
    python main.py --runner DataflowRunner --setup_file ./setup.py  <...other options...>
    

这些步骤可简化流水线代码维护,尤其是在代码规模和复杂性不断增加时。如需了解指定依赖项的其他方法,请参阅 Apache Beam 文档中的管理 Python 流水线依赖项

使用自定义容器来控制运行时环境

如需使用 Apache Beam Python SDK 运行流水线,Dataflow 工作器需要包含解释器、Apache Beam SDK 和流水线依赖项的 Python 环境。Docker 容器映像可提供适合运行流水线代码的环境。

每个版本的 Apache Beam SDK 都会发布库存容器映像,这些映像包含 Apache Beam SDK 依赖项。如需了解详情,请参阅 Apache Beam 文档中的 Python 版 Apache Beam SDK 依赖项

如果流水线需要默认容器映像中未包含的依赖项,则必须在运行时安装该依赖项。在运行时安装软件包可能会产生以下后果:

  • 由于依赖项解析、下载和安装,工作器启动时间增加。
  • 流水线需要连接到互联网才能运行。
  • 由于依赖项中的软件版本,会出现不确定性。

为避免这些问题,请在自定义 Docker 容器映像中提供运行时环境。使用预安装了流水线依赖项的自定义 Docker 容器映像具有以下优势:

  • 确保每次启动 Dataflow 作业时流水线运行时环境都具有一组相同的依赖项。
  • 让您可以控制流水线的运行时环境。
  • 避免在启动时进行可能耗时的依赖项解析。

使用自定义容器映像时,请考虑以下指导原则:

  • 请勿将 :latest 标记用于您的自定义映像。使用日期、版本或唯一标识符标记构建。通过此步骤,您可以在需要时还原到已知的正常工作配置。
  • 使用与容器映像兼容的启动环境。 如需详细了解如何使用自定义容器,请参阅构建容器映像

如需详细了解如何预安装 Python 依赖项,请参阅预安装 Python 依赖项

使用 Dataflow 模板控制启动环境

如果流水线需要其他依赖项,您可能需要在运行时环境和启动环境中安装这些依赖项。启动环境运行的是流水线的生产版。由于启动环境必须与运行时环境兼容,因此请在两个环境中使用相同版本的依赖项。

如需获得容器化的可重现启动环境,请使用 Dataflow Flex 模板。如需了解详情,请参阅使用 Flex 模板打包 Dataflow 流水线以进行部署。 使用 Flex 模板时,请考虑以下因素:

  • 如果您将流水线配置为软件包,请在模板 Dockerfile 中安装该软件包。 如需配置 Flex 模板,请指定 FLEX_TEMPLATE_PYTHON_SETUP_FILE。 如需了解详情,请参阅设置所需的 Dockerfile 环境变量
  • 如果您在流水线中使用自定义容器映像,请在启动模板时提供该映像。如需了解详情,请参阅使用自定义容器处理依赖项
  • 如需构建 Dataflow Flex 模板 Docker 映像,请使用相同的自定义容器映像作为基础映像。如需了解详情,请参阅使用自定义容器映像

这种构建方式可确保启动环境既可重现,又与运行时环境兼容。

如需查看遵循此方法的示例,请参阅 GitHub 中的具有依赖项和自定义容器的流水线的 Flex 模板教程。

如需了解详情,请参阅 Apache Beam 文档中的使启动环境与运行时环境兼容以及控制流水线使用的依赖项

Go

使用 Apache Beam Go SDK 运行 Dataflow 作业时,使用 Go 模块来管理依赖项。以下文件包含流水线使用的默认编译和运行时依赖项:

https://raw.githubusercontent.com/apache/beam/vVERSION_NUMBER/sdks/go.sum

VERSION_NUMBER 替换为您使用的 SDK 版本。

如需了解如何管理 Go 流水线的依赖项,请参阅 Go 文档中的管理依赖项