Es cierto ... se ha discutido bastante.
Sin embargo, hay mucha ambigüedad y algunas de las respuestas proporcionadas ... incluyendo duplicar referencias de jarras en la configuración u opciones de jarras / ejecutor / controlador.
Los detalles ambiguos y / u omitidos
Después de la ambigüedad, se deben aclarar los detalles poco claros y / u omitidos para cada opción:
- Cómo se ve afectado ClassPath
- Conductor
- Ejecutor (para tareas en ejecución)
- Ambos
- De ningún modo
- Carácter de separación: coma, dos puntos, punto y coma
- Si los archivos provistos se distribuyen automáticamente
- para las tareas (a cada ejecutor)
- para el controlador remoto (si se ejecuta en modo de clúster)
- tipo de URI aceptado: archivo local, hdfs, http, etc.
- Si se copia en una ubicación común, ¿dónde está esa ubicación (hdfs, local?)
Las opciones a las que afecta:
--jars
SparkContext.addJar(...)
métodoSparkContext.addFile(...)
método--conf spark.driver.extraClassPath=...
o--driver-class-path ...
--conf spark.driver.extraLibraryPath=...
o--driver-library-path ...
--conf spark.executor.extraClassPath=...
--conf spark.executor.extraLibraryPath=...
- Sin olvidar que el último parámetro del envío de chispas también es un archivo .jar.
Soy consciente de dónde puedo encontrar la documentación principal de chispa , y específicamente sobre cómo enviar , las opciones disponibles y también el JavaDoc . Sin embargo, eso me dejó todavía algunos agujeros, aunque también respondió parcialmente.
Espero que no sea tan complejo y que alguien pueda darme una respuesta clara y concisa.
Si tuviera que adivinar a partir de la documentación, parece que --jars
, y los métodos SparkContext
addJar
y addFile
son los que distribuirán automáticamente los archivos, mientras que las otras opciones simplemente modifican la ClassPath.
¿Sería seguro asumir que, por simplicidad, puedo agregar archivos jar de aplicaciones adicionales usando las 3 opciones principales al mismo tiempo:
spark-submit --jar additional1.jar,additional2.jar \
--driver-library-path additional1.jar:additional2.jar \
--conf spark.executor.extraLibraryPath=additional1.jar:additional2.jar \
--class MyClass main-application.jar
Encontré un buen artículo sobre una respuesta a otra publicación . Sin embargo, nada nuevo aprendido. El póster hace un buen comentario sobre la diferencia entre el controlador local (cliente de hilo) y el controlador remoto (grupo de hilo). Definitivamente importante tener en cuenta.
Respuestas:
ClassPath:
ClassPath se ve afectado según lo que proporcione. Hay un par de formas de configurar algo en el classpath:
spark.driver.extraClassPath
o es un alias--driver-class-path
para establecer rutas de clase adicionales en el nodo que ejecuta el controlador.spark.executor.extraClassPath
para establecer una ruta de clase adicional en los nodos Worker.Si desea que cierto JAR se efectúe tanto en el Maestro como en el Trabajador, debe especificarlos por separado en AMBOS indicadores.
Carácter de separación:
Siguiendo las mismas reglas que la JVM :
:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
;
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"
Distribución de archivos:
Esto depende del modo en el que esté ejecutando su trabajo:
Modo de cliente: Spark enciende un servidor HTTP Netty que distribuye los archivos al inicio para cada uno de los nodos de trabajo. Puedes ver eso cuando comienzas tu trabajo de Spark:
Modo de clúster: en el modo de clúster, spark seleccionó un nodo de trabajador líder para ejecutar el proceso del controlador. Esto significa que el trabajo no se ejecuta directamente desde el nodo maestro. Aquí, Spark no configurará un servidor HTTP. Debe hacer que sus JARS estén disponibles manualmente para todos los nodos de trabajo a través de HDFS / S3 / Otras fuentes que están disponibles para todos los nodos.
URI aceptados para archivos
En "Envío de solicitudes" , la documentación de Spark hace un buen trabajo al explicar los prefijos aceptados para los archivos:
Como se señaló, los JAR se copian en el directorio de trabajo para cada nodo Worker. ¿Dónde es exactamente eso? Por lo general
/var/run/spark/work
, está debajo , los verá así:Y cuando mires dentro, verás todos los JAR que desplegaste:
Opciones afectadas:
Lo más importante para entender es la prioridad . Si pasa cualquier propiedad a través del código, tendrá prioridad sobre cualquier opción que especifique
spark-submit
. Esto se menciona en la documentación de Spark:Así que asegúrese de establecer esos valores en los lugares adecuados, para que no se sorprenda cuando uno tiene prioridad sobre el otro.
Analicemos cada opción en cuestión:
--jars
vsSparkContext.addJar
: Estos son idénticos, solo uno se configura mediante envío de chispa y otro mediante código. Elija el que mejor le convenga. Una cosa importante a tener en cuenta es que el uso de cualquiera de estas opciones no agrega el JAR a su classpath de controlador / ejecutor , deberá agregarlos explícitamente usando laextraClassPath
configuración en ambos.SparkContext.addJar
vsSparkContext.addFile
: Use el primero cuando tenga una dependencia que deba usarse con su código. Use este último cuando simplemente desee pasar un archivo arbitrario a sus nodos de trabajo, lo que no es una dependencia en tiempo de ejecución en su código.--conf spark.driver.extraClassPath=...
o--driver-class-path
: estos son alias, no importa cuál elijas--conf spark.driver.extraLibraryPath=..., or --driver-library-path ...
Igual que el anterior, alias.--conf spark.executor.extraClassPath=...
: Use esto cuando tenga una dependencia que no se puede incluir en un JAR uber (por ejemplo, porque hay conflictos de tiempo de compilación entre las versiones de la biblioteca) y que necesita cargar en tiempo de ejecución.--conf spark.executor.extraLibraryPath=...
Esto se pasa como lajava.library.path
opción para la JVM. Use esto cuando necesite una ruta de biblioteca visible para la JVM.Puede asumir esto con seguridad solo para el modo Cliente, no para el modo Clúster. Como he dicho anteriormente. Además, el ejemplo que dio tiene algunos argumentos redundantes. Por ejemplo, pasar JAR a
--driver-library-path
es inútil, debe pasárselosextraClassPath
si desea que estén en su classpath. En definitiva, lo que desea hacer cuando implementa JAR externos tanto en el controlador como en el trabajador es:fuente
MANIFEST.MF
archivo)?assemblyMergeStrategy
y seleccionando las clases que necesito si hay conflictos. En general, recomendaría lo mismo.--jars
bandera como a la ruta de la clase del conductor / ejecutor.zeppelin-env.sh
y añadido--jars
aSPARK_SUBMIT_OPTIONS
. Eso funciono. El formato URI que uso es--jars=local:///mnt/dir/file.jar
.Otro enfoque
spark 2.1.0
es usar--conf spark.driver.userClassPathFirst=true
durante el envío de chispas que cambia la prioridad de la carga de dependencia y, por lo tanto, el comportamiento del trabajo de chispa, dando prioridad a los tarros que el usuario agrega a la ruta de clase con la--jars
opción.fuente
Otras opciones configurables de Spark relacionadas con jarras y classpath, en el caso de un
yarn
modo de implementación, son las siguientes:De la documentación de spark,
Los usuarios pueden configurar este parámetro para especificar sus jarras, que se incluyen en el classpath del controlador Spark.
fuente
Al usar spark-submit con --master yarn-cluster, el frasco de la aplicación junto con los frascos incluidos con la opción --jars se transferirán automáticamente al clúster. Las URL proporcionadas después de --jars deben estar separadas por comas. Esa lista está incluida en las rutas de clase del controlador y del ejecutor
Ejemplo:
spark-submit --master yarn-cluster --jars ../lib/misc.jar, ../lib/test.jar --class MainClass MainApp.jar
https://spark.apache.org/docs/latest/submitting-applications.html
fuente
Existe una restricción en el uso
--jars
: si desea especificar un directorio para la ubicación deljar/xml
archivo, no permite expansiones de directorio. Esto significa que si necesita especificar una ruta absoluta para cada jar.Si especifica
--driver-class-path
y está ejecutando en modo cluster de hilo, la clase de controlador no se actualiza. Podemos verificar si la ruta de clase se actualiza o no en spark ui o en el servidor de historial de chispas en el entorno de pestaña.La opción que funcionó para mí para pasar frascos que contienen expansiones de directorio y que funcionó en modo cluster de hilo fue la
--conf
opción. Es mejor pasar rutas de clase de controlador y ejecutor como--conf
, lo que las agrega al objeto de sesión de chispa en sí mismo y esas rutas se reflejan en Spark Configuration. Pero asegúrese de colocar frascos en la misma ruta a través del clúster.fuente
Si bien enviamos trabajos de chispa utilizando la utilidad de envío de chispas, hay una opción
--jars
. Con esta opción, podemos pasar el archivo jar a aplicaciones de chispa.fuente
—jar
opción fue mencionada por el póster original, más discutido en mucho más detalle por más de una respuesta. ¿No parece que estás proporcionando algo nuevo?