Spark submit命令中有一个比较方便的功能是将本地的文件传到集群中Spark Application的Driver进程和Executor进程工作目录中,让我们通过和本地执行中相同的代码就能够访问到这些文件。
但是在使用过程中需要注意文件的路径。Spark使用的Deploy Mode是client或者cluster对路径的使用是有影响的(当然使用client的时候就不需要--files上传文件了,但是会影响我们在client和cluster执行模式之间进行切换时候引入文件的路径)。使用--files上传文件,如果没有更改上传后的目录和文件名的话,默认是放在Driver进程和Executor进程工作的同一级目录,下面画个图会更直观些:
这里本地的三个文件,分别在conf目录下的A.properties、props目录下的B.properties、还有同级目录下的C.properties,他们在上传后都在同一级目录下了,因此在使用的时候,无论是Driver端的代码还是Executor端的代码,都是读同级目录文件的形式就可以了,如下所示:
Spark submit命令中有一个比较方便的功能是将本地的文件传到集群中Spark Application的Driver进程和Executor进程工作目录中,让我们通过和本地执行中相同的代码就能够访问到这些文件。
但是在使用过程中需要注意文件的路径。Spark使用的Deploy Mode是client或者cluster对路径的使用是有影响的(当然使用client的时候就不需要--files上传文件了,但是会影响我们在client和cluster执行模式之间进行切换时候引入文件的路径)。使用--files上传文件,如果没有更改上传后的目录和文件名的话,默认是放在Driver进程和Executor进程工作的同一级目录,下面画个图会更直观些:
这里本地的三个文件,分别在conf目录下的A.properties、props目录下的B.properties、还有同级目录下的C.properties,他们在上传后都在同一级目录下了,因此在使用的时候,无论是Driver端的代码还是Executor端的代码,都是读同级目录文件的形式就可以了,如下所示:
// spark submit上传了三个文件,这三个文件都是传到程序执行的根目录下
#!/bin/bash
nohup spark-submit \
--master yarn \
--class FileTest \
--deploy-mode client \
--queue default \
--driver-memory 1g \
--num-executors 2 \
--executor-memory 1g \
--executor-cores 1 \
--files conf/A.properties,props/B.properties,C.properties \
sparkTest-1.0-SNAPSHOT.jar > data.log 2>&1 &
// 无论Driver端还是Executor端读取这些文件,如下直接读取,这个cluster的
File aFile = new File("A.properties");
File bFile = new File("B.properties");
File cFile = new File("C.properties");
// 注意如果切换到client模式的,Driver端的读取代码要变的,这是个容易被
// 忽略的坑,如果老是读取不到文件就要注意发布时候的deployMode了
File aFile = new File("conf/A.properties");
File bFile = new File("props/B.properties");
File cFile = new File("C.properties");
因此其实我们还需要注意上传的文件不要重名了,毕竟上传到同一级目录。但是这其实可以解决,就是我们其实可以控制上传后文件所在的目录位置和他的名字。让client模式下读取文件的目录和cluster模式下读取文件的目录一样,这样就可以避免遇到改变deploy mode就要改文件读取路径的情况发生。这里也画个图:
那么要怎么做到这种方式的文件上传呢,其实就是通过#来实现的:
#!/bin/bash
nohup spark-submit \
--master yarn \
--class FileTest \
--deploy-mode client\
--queue default \
--driver-memory 1g \
--num-executors 2 \
--executor-memory 1g \
--executor-cores 1 \
--files conf/A.properties#conf/A.properties,\
props/B.properties#prop/B.properties,\
C.properties#C.properties \
sparkTest-1.0-SNAPSHOT.jar > data.log 2>&1 &
可以看到上传的--files的文件名后又通过#定义了一遍,其实#后面指的是文件上传后的相对路径以及文件名,通过定义和本地一样的相对路径和文件名,就能做到上传后在Driver端和Executor端的文件路径和本地的一样。那么我们的读取方式就不需要改变了。
当然我们也可以通过这种方式给上传后的文件定义不一样的名字啥的,方便我们在对功能和业务逻辑的适应上更好。