Muchos flujos de procesamiento de Apache Beam se pueden ejecutar con los entornos de ejecución de Dataflow predeterminados. Sin embargo, en algunos casos prácticos de procesamiento de datos, es útil usar bibliotecas o clases adicionales. En estos casos, es posible que tengas que gestionar las dependencias de tu canalización.
A continuación, se indican algunos motivos por los que puede que tengas que gestionar las dependencias de tu canalización:
- Las dependencias proporcionadas por el entorno de tiempo de ejecución predeterminado no son suficientes para tu caso de uso.
- Las dependencias predeterminadas tienen conflictos de versiones o clases y bibliotecas que no son compatibles con el código de tu canalización.
- Debes fijar versiones específicas de la biblioteca para tu canal.
- Tienes una canalización de Python que debe ejecutarse con un conjunto de dependencias coherente.
La forma de gestionar las dependencias depende de si tu canalización usa Java, Python o Go.
Java
Las clases y bibliotecas incompatibles pueden provocar problemas de dependencia de Java. Si tu pipeline contiene código y ajustes específicos de un usuario, el código no puede contener versiones mixtas de bibliotecas.
Problemas de dependencia de Java
Si tu canalización tiene problemas de dependencia de Java, puede que se produzca uno de los siguientes errores:
NoClassDefFoundError
: este error se produce cuando una clase completa no está disponible durante el tiempo de ejecución.NoSuchMethodError
: este error se produce cuando la clase de la ruta de clases usa una versión que no contiene el método correcto o cuando ha cambiado la firma del método.NoSuchFieldError
: este error se produce cuando la clase de la ruta de clases usa una versión que no tiene un campo necesario durante el tiempo de ejecución.FATAL ERROR
: este error se produce cuando no se puede cargar correctamente una dependencia integrada. Si usas un archivo JAR uber (con sombreado), no incluyas bibliotecas que usen firmas en el mismo archivo JAR, como Conscrypt.
Gestión de dependencias
Para simplificar la gestión de dependencias de las canalizaciones de Java, Apache Beam usa artefactos de lista de materiales (BOM). La lista de materiales ayuda a las herramientas de gestión de dependencias a seleccionar combinaciones de dependencias compatibles. Para obtener más información, consulta las dependencias del SDK de Apache Beam para Java en la documentación de Apache Beam.
Para usar una lista de materiales con tu canalización y añadir explícitamente otras dependencias a la lista de dependencias, añade la siguiente información al archivo pom.xml
del artefacto del SDK. Para importar la BOM de las bibliotecas correctas, usa 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>
El artefacto beam-sdks-java-core
solo contiene el SDK principal. Debes añadir explícitamente otras dependencias, como E/S y runners, a la lista de dependencias.
Python
Cuando ejecutas tareas de Dataflow con el SDK de Apache Beam para Python, la gestión de dependencias es útil en los siguientes casos:
- Tu canal usa paquetes públicos del índice de paquetes de Python (PyPI) y quieres que estos paquetes estén disponibles de forma remota.
- Quieres crear un entorno reproducible.
- Para reducir el tiempo de inicio, debes evitar la instalación de dependencias en los trabajadores en el tiempo de ejecución.
Definir dependencias de la canalización de Python
Aunque puedes usar una sola secuencia de comandos o un solo cuaderno de Python para escribir una canalización de Apache Beam, en el ecosistema de Python, el software se suele distribuir como paquetes. Para que sea más fácil mantener tu flujo de procesamiento, si el código de tu flujo de procesamiento abarca varios archivos, agrupa los archivos del flujo de procesamiento como un paquete de Python.
- Define las dependencias de la canalización en el archivo
setup.py
de tu paquete. - Organiza el paquete para los trabajadores mediante la opción de canalización
--setup_file
.
Cuando los trabajadores remotos empiecen, instalarán tu paquete. Para ver un ejemplo, consulta juliaset en GitHub de Apache Beam.
Para estructurar tu flujo de trabajo como un paquete de Python, sigue estos pasos:
Crea un archivo
setup.py
para tu proyecto. En el archivosetup.py
, incluye el argumentoinstall_requires
para especificar el conjunto mínimo de dependencias de tu canalización. En el siguiente ejemplo se muestra un archivosetup.py
básico.import setuptools setuptools.setup( name='PACKAGE_NAME', version='PACKAGE_VERSION', install_requires=[], packages=setuptools.find_packages(), )
Añade 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. Este grupo de archivos es el paquete de Python de tu canalización. La estructura del archivo es similar al siguiente ejemplo:root_dir/ package_name/ __init__.py my_pipeline_launcher.py my_custom_transforms.py ...other files... setup.py main.py
Para ejecutar tu canalización, instala el paquete en el entorno de envío. Usa la opción de canalización
--setup_file
para organizar 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 la canalización, sobre todo cuando el código aumenta de tamaño y complejidad. Para ver otras formas de especificar dependencias, consulta Gestión de dependencias de la canalización de Python en la documentación de Apache Beam.
Usar contenedores personalizados para controlar el entorno de ejecución
Para ejecutar un flujo de trabajo con el SDK de Python de Apache Beam, los trabajadores de Dataflow necesitan un entorno de Python que contenga un intérprete, el SDK de Apache Beam y las dependencias del flujo de trabajo. Las imágenes de contenedor Docker proporcionan el entorno adecuado para ejecutar el código de tu flujo de trabajo.
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. Para obtener más información, consulta las dependencias del SDK de Apache Beam para 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, la dependencia debe instalarse en el tiempo de ejecución. Instalar paquetes en tiempo de ejecución puede tener las siguientes consecuencias:
- El tiempo de inicio de los trabajadores aumenta debido a la resolución, descarga e instalación de dependencias.
- La canalización requiere una conexión a Internet para ejecutarse.
- El no determinismo se produce debido a las versiones de software de las dependencias.
Para evitar estos problemas, proporcione el entorno de tiempo de ejecución en una imagen de contenedor Docker personalizada. Usar una imagen de contenedor Docker personalizada con las dependencias de la canalización preinstaladas tiene las siguientes ventajas:
- Asegura que el entorno de ejecución de la canalización tenga el mismo conjunto de dependencias cada vez que inicies tu trabajo de Dataflow.
- Te permite controlar el entorno de ejecución de tu flujo de trabajo.
- Evita que se resuelvan dependencias al inicio, lo que puede llevar mucho tiempo.
Cuando uses imágenes de contenedor personalizadas, ten en cuenta las siguientes directrices:
- No uses la etiqueta
:latest
con tus imágenes personalizadas. Etiqueta tus compilaciones con una fecha, una versión o un identificador único. Este paso te permite volver a una configuración que sabes que funciona si es necesario. - Usa un entorno de lanzamiento compatible con tu imagen de contenedor. Para obtener más información sobre cómo usar contenedores personalizados, consulte Crear una imagen de contenedor.
Para obtener información sobre cómo preinstalar dependencias de Python, consulta Preinstalar dependencias de Python.
Controlar el entorno de lanzamiento con plantillas de Dataflow
Si tu canalización requiere dependencias adicionales, es posible que tengas que instalarlas tanto en el entorno de tiempo de ejecución como en el de lanzamiento. El entorno de lanzamiento ejecuta la versión de producción de la canalización. Como el entorno de lanzamiento debe ser compatible con el entorno de tiempo de ejecución, usa las mismas versiones de las dependencias en ambos entornos.
Para tener un entorno de lanzamiento contenedorizado y reproducible, usa plantillas Flex de Dataflow. Para obtener más información, consulta el artículo Crear y ejecutar una plantilla flexible. Cuando uses plantillas Flex, ten en cuenta los siguientes factores:
- Si configuras la canalización como un paquete, instala el paquete en el Dockerfile de la plantilla.
Para configurar la plantilla Flex, especifica
FLEX_TEMPLATE_PYTHON_SETUP_FILE
. Para obtener más información, consulta Definir variables de entorno de Dockerfile obligatorias. - Si usas una imagen de contenedor personalizada con tu canalización, proporciónala cuando inicies la plantilla. Para obtener más información, consulta Usar un contenedor personalizado para las dependencias.
- Para compilar la imagen Docker de tu plantilla flexible de Dataflow, usa la misma imagen de contenedor personalizada que la imagen base. Para obtener más información, consulta Usar imágenes de contenedor personalizadas.
Esta construcción hace que tu entorno de lanzamiento sea reproducible y compatible con tu entorno de tiempo de ejecución.
Para ver un ejemplo que sigue este enfoque, consulta el tutorial sobre la plantilla flexible de una canalización con dependencias y un contenedor personalizado en GitHub.
Para obtener más información, consulta los artículos Hacer que el entorno de lanzamiento sea compatible con el entorno de ejecución y Controlar las dependencias que usa la canalización de la documentación de Apache Beam.
Go
Cuando ejecutas tareas de Dataflow con el SDK de Apache Beam Go, se usan módulos de Go para gestionar las dependencias. El siguiente archivo contiene las dependencias de compilación y de tiempo de ejecución predeterminadas que usa tu canal:
https://raw.githubusercontent.com/apache/beam/vVERSION_NUMBER/sdks/go.sum
Sustituye VERSION_NUMBER por la versión del SDK que estés usando.
Para obtener información sobre cómo gestionar las dependencias de tu canalización de Go, consulta Gestión de dependencias en la documentación de Go.