Cómo administrar las dependencias de Python en PySpark

Christian Russo
orbit-software
5 min readMar 5, 2021

--

Controlar el entorno de una aplicación a menudo es un desafío en un entorno informático distribuido: es difícil garantizar que todos los nodos tengan el entorno deseado para ejecutar, puede ser complicado saber dónde se está ejecutando realmente el código del usuario, etc.

Apache Spark ™ proporciona varias formas estándar de administrar las dependencias en los nodos de un clúster mediante opciones de secuencia de comandos como — jars, — packages y configuraciones cómo spark.jars. * Para que los usuarios administren sin problemas las dependencias en sus clústeres.

Por el contrario, los usuarios de PySpark a menudo preguntan cómo hacerlo con las dependencias de Python; se han presentado varios problemas, como SPARK-13587, SPARK-16367, SPARK-20001 y SPARK-25433. Un ejemplo simple que ilustra el escenario de gestión de dependencias es cuando los usuarios ejecutan pandas UDF.

Si no tienen las dependencias requeridas instaladas en todos los demás nodos, falla y se queja de que PyArrow y pandas deben instalarse.

Un método sencillo es utilizar opciones de script como — py-files o la configuración spark.submit.pyFiles, pero esta funcionalidad no puede cubrir muchos casos, como la instalación de archivos de rueda o cuando las bibliotecas de Python dependen de bibliotecas de C y C ++, como pyarrow y NumPy.

Esta publicación de blog presenta cómo controlar las dependencias de Python en Apache Spark de manera integral. La mayor parte del contenido también se documentará en el próximo Apache Spark 3.1 como parte del Proyecto Zen. Consulte Actualización de Project Zen: Mejora de Apache Spark para usuarios de Python para obtener más detalles.

Usando Conda

Conda es uno de los sistemas de gestión de paquetes de Python más utilizados. Los usuarios de PySpark pueden usar directamente un entorno Conda para enviar sus paquetes Python de terceros aprovechando conda-pack, que es una herramienta de línea de comandos que crea entornos Conda reubicables. Es compatible con todo tipo de clústeres en el próximo Apache Spark 3.1. En Apache Spark 3.0 o versiones inferiores, solo se puede usar con YARN.

El siguiente ejemplo crea un entorno Conda para usar tanto en el controlador como en el ejecutor y lo empaqueta en un archivo de almacenamiento. Este archivo captura el entorno de Conda para Python y almacena tanto el intérprete de Python como todas sus dependencias relevantes.

Después de eso, puede enviarlo junto con scripts o en el código usando la opcion — archives ó la configuracion spark.archives (spark.yarn.dist.archives in YARN). Descomprime automáticamente el archivo en ejecutores.

En el caso de un spark-submit script, puede usarlo de la siguiente manera:

Tener en cuenta qué PYSPARK_DRIVER_PYTHON anterior no debe configurarse para los modos de clúster en YARN o Kubernetes.

Para pyspark shell:

Si está en un shell o portátil de Python normal, puede probarlo como se muestra a continuación:

Usando Virtualenv

Virtualenv es una herramienta de Python para crear entornos Python aislados. Desde Python 3.3, un subconjunto de sus características se ha integrado en Python como una biblioteca estándar en el módulo venv. En el próximo Apache Spark 3.1, los usuarios de PySpark pueden usar virtualenv para administrar las dependencias de Python en sus clústeres usando venv-pack de manera similar a conda-pack. En el caso de Apache Spark 3.0 y versiones inferiores, solo se puede usar con YARN.

Se puede crear un entorno virtual para usar tanto en el controlador como en el ejecutor, como se muestra a continuación. Empaqueta el entorno virtual actual en un archivo de almacenamiento y contiene tanto el intérprete de Python como las dependencias. Sin embargo, requiere que todos los nodos de un clúster tengan instalado el mismo intérprete de Python porque venv-pack incluye el intérprete de Python como un enlace simbólico.

Puede pasar / descomprimir directamente el archivo de almacenamiento y habilitar el entorno en los ejecutores aprovechando la opcion

— archives ó spark.archives configuration (spark.yarn.dist.archives in YARN).

Para spark-submit, puede usarlo ejecutando el comando de la siguiente manera. Además, observe que

PYSPARK_DRIVER_PYTHON debe estar desarmado en los modos de clúster de Kubernetes o YARN.

Para el caso de un pyspark shell:

Para el caso de un regular Python shells or notebooks:

Usando PEX

PySpark también puede usar PEX para enviar los paquetes de Python juntos. PEX es una herramienta que crea un entorno Python autónomo. Esto es similar a Conda o virtualenv, pero un archivo .pex es ejecutable por sí mismo.

El siguiente ejemplo crea un archivo .pex para que lo utilicen el controlador y el ejecutor. El archivo contiene las dependencias de Python especificadas con el comando pex.

Este archivo se comporta de manera similar con un intérprete de Python normal.

Sin embargo .pex El archivo no incluye un intérprete de Python bajo el capó, por lo que todos los nodos de un clúster deben tener instalado el mismo intérprete de Python.

Para transferir y utilizar el.pex archivo en un clúster, debe enviarlo a través del spark.files configuration (spark.yarn.dist.files in YARN) or — files option porque son archivos normales en lugar de directorios o archivos de almacenamiento.

Para enviar la solicitud, ejecute los comandos como se muestra a continuación PYSPARK_DRIVER_PYTHON no debe configurarse para modos de clúster en YARN o Kubernetes.

Para lo interactivo pyspark shell, los comandos son casi los mismos:

Para cuadernos o shells de Python normales:

Conclusión

En Apache Spark, Conda, virtualenv y PEX se pueden aprovechar para enviar y administrar las dependencias de Python.

Conda: este es uno de los sistemas de gestión de paquetes más utilizados. En Apache Spark 3.0 y versiones inferiores, Conda solo se puede admitir con el clúster YARN y funciona con todos los demás tipos de clústeres en el próximo Apache Spark 3.1.

Virtualenv: los usuarios pueden hacerlo sin una instalación adicional porque es una biblioteca incorporada en Python pero debería tener el mismo Python instalado en todos los nodos, mientras que Conda no lo requiere. Virtualenv funciona solo con el clúster YARN en Apache Spark 3.0 y versiones inferiores, y todos los demás tipos de clústeres lo admiten en el próximo Apache Spark 3.1.

PEX: se puede usar con cualquier tipo de clúster en cualquier versión de Apache Spark, aunque podría decirse que se usa menos y requiere tener el mismo Python instalado en todos los nodos, mientras que Conda no lo requiere.

Estos sistemas de administración de paquetes pueden manejar cualquier paquete de Python que la configuración — py-files o spark.submit.pyFiles no pueda cubrir. Los usuarios pueden enviar sin problemas no solo pandas y PyArrow, sino también otras dependencias para interactuar juntas cuando trabajan con PySpark.

En el caso de los cuadernos de Databricks, no solo proporcionamos un mecanismo elegante al tener una interfaz de usuario bien diseñada, sino que también permitimos a los usuarios usar directamente pip y Conda para abordar esta gestión de dependencia de Python. Pruébelos hoy gratis en Databricks.

--

--