在 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 文档中的管理依赖项