在 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-io-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 Package Index (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/
        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 模板。使用 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 文档中的管理依赖项