Administra dependencias de canalización en Dataflow

Muchas canalizaciones de Apache Beam pueden ejecutarse mediante los entornos de ejecución predeterminados de Dataflow. Sin embargo, algunos casos de uso de procesamiento de datos se benefician del uso de clases o bibliotecas adicionales. En estos casos, es posible que debas administrar las dependencias de tu canalización.

En la siguiente lista, se proporcionan algunos motivos por los que podrías necesitar administrar tus dependencias de canalización:

  • Las dependencias que proporciona el entorno de ejecución predeterminado no son suficientes para tu caso de uso.
  • Las dependencias predeterminadas tienen colisiones de versiones o clases y bibliotecas que son incompatibles con el código de tu canalización.
  • Debes fijar las versiones específicas de la biblioteca para tu canalización.
  • Tienes una canalización de Python que debe ejecutarse con un conjunto coherente de dependencias.

La forma en que administras las dependencias depende de si tu canalización usa Java, Python o Go.

Java

Las clases y bibliotecas incompatibles pueden causar problemas de dependencia de Java. Si tu canalización contiene código y configuración específicos del usuario, el código no puede contener versiones mixtas de las bibliotecas.

Problemas de dependencia de Java

Cuando tu canalización tiene problemas de dependencia de Java, puede ocurrir uno de los siguientes errores:

  • NoClassDefFoundError: Este error ocurre cuando una clase completa no está disponible durante el tiempo de ejecución.
  • NoSuchMethodError: Este error se produce cuando la clase en la ruta de clase usa una versión que no contiene el método correcto o cuando cambió la firma del método.
  • NoSuchFieldError: Este error se produce cuando la clase en la ruta de clase usa una versión que no tiene un campo obligatorio durante el entorno de ejecución.
  • FATAL ERROR: Este error ocurre cuando una dependencia integrada no se puede cargar de forma correcta. Cuando uses un archivo Uber JAR (sombreado), no incluyas bibliotecas que usen firmas en el mismo archivo JAR, como Conscrypt.

Administración de dependencias

A fin de simplificar la administración de dependencias para las canalizaciones de Java, Apache Beam usa artefactos de lista de materiales (BOM). La BOM ayuda a las herramientas de administración de dependencias a seleccionar combinaciones de dependencias compatibles. Si deseas obtener más información, consulta SDK de Apache Beam para dependencias de Java en la documentación de Apache Beam.

Para usar una BOM con tu canalización y agregar de forma explícita otras dependencias a la lista de dependencias, agrega la siguiente información al archivo pom.xml para el artefacto del SDK. Para importar la BOM de las bibliotecas correctas, usa 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>

El artefacto beam-sdks-java-core contiene solo el SDK principal. Debes agregar de forma explícita otras dependencias, como E/S y los ejecutores, a la lista de dependencias.

Python

Cuando ejecutas trabajos de Dataflow con el SDK de Python de Apache Beam, la administración de dependencias es útil en las siguientes situaciones:

  • Tu canalización usa paquetes públicos del índice de paquetes de Python (PiPy) y deseas que estos paquetes estén disponibles de forma remota.
  • Deseas crear un entorno reproducible.
  • Para reducir el tiempo de inicio, deseas evitar la instalación de dependencias en los trabajadores en el entorno de ejecución.

Define dependencias de canalización de Python

Aunque puedes usar una sola secuencia de comandos o notebook de Python para escribir una canalización de Apache Beam, en el ecosistema de Python, el software se suele distribuir como paquetes. Para facilitar el mantenimiento de tu canalización, cuando el código de tu canalización abarque varios archivos, agrupa los archivos de canalización como un paquete de Python.

  • Define las dependencias de la canalización en el archivo setup.py de tu paquete.
  • Almacena el paquete en etapa intermedia en los trabajadores mediante la opción de canalización --setup_file.

Cuando se inician los trabajadores remotos, instalan tu paquete. Para ver un ejemplo, consulta juliaset en GitHub de Apache Beam.

Para estructurar tu canalización como un paquete de Python, sigue estos pasos:

  1. Crea un archivo setup.py para tu proyecto. En el archivo setup.py, incluye el argumento install_requires a fin de especificar el conjunto mínimo de dependencias para tu canalización. En el siguiente ejemplo, se muestra un archivo setup.py básico.

    import setuptools
    
    setuptools.setup(
      name='PACKAGE_NAME',
      version='PACKAGE_VERSION',
      install_requires=[],
      packages=setuptools.find_packages(),
    )
    
  2. Agrega el archivo setup.py, el archivo de flujo de trabajo principal y un directorio con el resto de los archivos al directorio raíz de tu proyecto. Esta agrupación de archivos es el paquete de Python para tu canalización. La estructura del archivo se ve como el siguiente ejemplo:

    root_dir/
      package_name/
        my_pipeline_launcher.py
        my_custom_transforms.py
        ...other files...
      setup.py
      main.py
    
  3. Para ejecutar tu canalización, instala el paquete en el entorno de envío. Usa la opción de canalización --setup_file para almacenar en etapa intermedia el paquete en los trabajadores. Por ejemplo:

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

Estos pasos simplifican el mantenimiento del código de canalización, en especial cuando el código aumenta en tamaño y complejidad. Para conocer otras formas de especificar dependencias, consulta Administra dependencias de canalización de Python en la documentación de Apache Beam.

Usa contenedores personalizados para controlar el entorno de ejecución

A fin de ejecutar una canalización con el SDK de Python para Apache Beam, los trabajadores de Dataflow necesitan un entorno de Python que contenga un intérprete, el SDK de Apache Beam y las dependencias de canalización. Las imágenes de contenedor de Docker proporcionan el entorno adecuado para ejecutar el código de tu canalización.

Las imágenes de contenedor de Stock se lanzan con cada versión del SDK de Apache Beam, y estas imágenes incluyen las dependencias del SDK de Apache Beam. Si deseas obtener más información, consulta SDK de Apache Beam para dependencias de Python en la documentación de Apache Beam.

Cuando tu canalización requiere una dependencia que no está incluida en la imagen de contenedor predeterminada, esta debe instalarse en el entorno de ejecución. Instalar paquetes en el entorno de ejecución puede tener las siguientes consecuencias:

  • El tiempo de inicio del trabajador aumenta debido a la resolución, la descarga y la instalación de la dependencia.
  • La canalización requiere una conexión a Internet para ejecutarse.
  • El no determinismo ocurre debido a las actualizaciones de software en las dependencias.

Para evitar estos problemas, proporciona el entorno de ejecución en una imagen de contenedor de Docker personalizada. El uso de una imagen de contenedor de Docker personalizada que tenga las dependencias de canalización preinstaladas tiene los siguientes beneficios:

  • Garantiza que el entorno de ejecución de la canalización tenga el mismo conjunto de dependencias cada vez que inicias tu trabajo de Dataflow.
  • Te permite controlar el entorno de ejecución de la canalización.
  • Evita la resolución de dependencias que puede llevar mucho tiempo durante el inicio.

Cuando uses imágenes de contenedor personalizadas, ten en cuenta la siguiente guía:

  • Evita usar la etiqueta :latest con las imágenes personalizadas. Etiqueta tus compilaciones con una fecha, una versión o un identificador único. Este paso te permite revertir a una configuración de trabajo conocida si es necesario.
  • Usa un entorno de lanzamiento que sea compatible con tu imagen de contenedor. Para obtener más orientación sobre el uso de contenedores personalizados, consulta Compila una imagen de contenedor.

Para obtener detalles sobre la instalación previa de dependencias de Python, consulta Instalación previa de dependencias de Python.

Controla el entorno de lanzamiento con plantillas de Dataflow

Si tu canalización requiere dependencias adicionales, es posible que debas instalarlas en el entorno de ejecución y en el de lanzamiento. El entorno de lanzamiento ejecuta la versión de producción de la canalización. Debido a que el entorno de inicio debe ser compatible con el entorno de ejecución, usa las mismas versiones de dependencias en ambos entornos.

Para tener un entorno de inicio reproducible en contenedores, usa plantillas de Flex de Dataflow. Para obtener más información, consulta Compila y ejecuta una plantilla de Flex. Cuando uses plantillas de Flex, ten en cuenta los siguientes factores:

Esta construcción hace que tu entorno de lanzamiento sea reproducible y compatible con tu entorno de ejecución.

Si deseas ver un ejemplo que sigue este enfoque, consulta el instructivo Plantilla de Flex para una canalización con dependencias y un contenedor personalizado en GitHub.

Para obtener más información, consulta Haz que el entorno de lanzamiento sea compatible con el entorno de ejecución y Controla las dependencias que usa la canalización en la documentación de Apache Beam.

Go

Cuando ejecutas trabajos de Dataflow con el SDK de Go de Apache Beam, los módulos de Go se usan para administrar las dependencias. El siguiente archivo contiene las dependencias de compilación y entorno de ejecución predeterminadas que usa tu canalización:

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

Reemplaza VERSION_NUMBER por la versión del SDK que usas.

Si deseas obtener información sobre cómo administrar las dependencias en tu canalización de Go, consulta Administra dependencias en la documentación de Go.