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 :
- Linux: dos puntos
:
- p.ej:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
- Windows: un punto y coma
;
- p.ej:
--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:
16/05/08 17:29:12 INFO HttpFileServer: HTTP File server directory is /tmp/spark-48911afa-db63-4ffc-a298-015e8b96bc55/httpd-84ae312b-5863-4f4c-a1ea-537bfca2bc2b
16/05/08 17:29:12 INFO HttpServer: Starting HTTP Server
16/05/08 17:29:12 INFO Utils: Successfully started service 'HTTP file server' on port 58922.
16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/foo.jar at http://***:58922/jars/com.mycode.jar with timestamp 1462728552732
16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/aws-java-sdk-1.10.50.jar at http://***:58922/jars/aws-java-sdk-1.10.50.jar with timestamp 1462728552767
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:
Cuando se utiliza el envío de chispas, el frasco de la aplicación junto con los frascos incluidos con la opción --jars se transferirán automáticamente al clúster. Spark usa el siguiente esquema de URL para permitir diferentes estrategias para diseminar frascos:
- archivo: - Las rutas absolutas y el archivo: / URI son servidos por el servidor de archivos HTTP del controlador, y cada ejecutor extrae el archivo del servidor HTTP del controlador.
- hdfs :, http :, https :, ftp: estos archivos desplegables y JAR del URI como se esperaba
- local: un URI que comienza con local: / se espera que exista como un archivo local en cada nodo de trabajo. Esto significa que no se incurrirá en IO de red, y funciona bien para archivos / JAR grandes que se envían a cada trabajador o se comparten a través de NFS, GlusterFS, etc.
Tenga en cuenta que los archivos JAR y los archivos se copian en el directorio de trabajo para cada SparkContext en los nodos ejecutores.
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í:
drwxr-xr-x 3 spark spark 4096 May 15 06:16 app-20160515061614-0027
drwxr-xr-x 3 spark spark 4096 May 15 07:04 app-20160515070442-0028
drwxr-xr-x 3 spark spark 4096 May 15 07:18 app-20160515071819-0029
drwxr-xr-x 3 spark spark 4096 May 15 07:38 app-20160515073852-0030
drwxr-xr-x 3 spark spark 4096 May 15 08:13 app-20160515081350-0031
drwxr-xr-x 3 spark spark 4096 May 18 17:20 app-20160518172020-0032
drwxr-xr-x 3 spark spark 4096 May 18 17:20 app-20160518172045-0033
Y cuando mires dentro, verás todos los JAR que desplegaste:
[*@*]$ cd /var/run/spark/work/app-20160508173423-0014/1/
[*@*]$ ll
total 89988
-rwxr-xr-x 1 spark spark 801117 May 8 17:34 awscala_2.10-0.5.5.jar
-rwxr-xr-x 1 spark spark 29558264 May 8 17:34 aws-java-sdk-1.10.50.jar
-rwxr-xr-x 1 spark spark 59466931 May 8 17:34 com.mycode.code.jar
-rwxr-xr-x 1 spark spark 2308517 May 8 17:34 guava-19.0.jar
-rw-r--r-- 1 spark spark 457 May 8 17:34 stderr
-rw-r--r-- 1 spark spark 0 May 8 17:34 stdout
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:
Cualquier valor especificado como banderas o en el archivo de propiedades se pasará a la aplicación y se combinará con los especificados a través de SparkConf. Las propiedades configuradas directamente en SparkConf tienen mayor prioridad , luego las banderas pasan a spark-submit o spark-shell, luego las opciones en el archivo spark-defaults.conf
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
vs SparkContext.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 la extraClassPath
configuración en ambos.
SparkContext.addJar
vs SparkContext.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 la java.library.path
opción para la JVM. Use esto cuando necesite una ruta de biblioteca visible para la JVM.
¿Sería seguro asumir que, por simplicidad, puedo agregar archivos jar de aplicaciones adicionales usando las 3 opciones principales al mismo tiempo:
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árselos extraClassPath
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:
spark-submit --jars additional1.jar,additional2.jar \
--driver-class-path additional1.jar:additional2.jar \
--conf spark.executor.extraClassPath=additional1.jar:additional2.jar \
--class MyClass main-application.jar