Spark:提交yarn任务时的配置文件分发
使用spark-submit往yarn集群提交任务,deploy-mode可以采用client和cluster两种模式。
若想使用hive功能,需要满足以下条件:
- 初始化
sparkSession
对象的时候,指定enableHiveSupport
选项; - 指定hive配置,可以有两种方式
- 配置了hive-site.xml,若是client模式可以将其放入client端SPARK_HOME/conf目录下,若是cluster模式需要打包到jar包中(不会去找SPARK_HOME/conf目录)。
- 程序中指定,如下:
val spark = SparkSession .builder() .appName("Test") .config("spark.sql.parquet.writeLegacyFormat", true) .config("hive.metastore.uris", "thrift://10.18.2.3:9083") .enableHiveSupport() .getOrCreate()
可以通过用spark.catalog.listDatabases.show(false)
获取来判断是否正确取得hive元数据信息。
另外若要指定配置文件(如数据库的配置文件),配置文件要随jar包一起发送到yarn集群,否则会报找不到文件异常,可以采用以下方式:
- 使用spark-submit的
--files
参数指定文件,程序中使用org.apache.spark.SparkFiles.get("filename")
获取; - 程序中使用
spark.sparkContext.addFile("/path/filename")
添加,获取方法同上。
实际上以上两种方法等效,--files
参数就会转换为addFile。
此方法的原理是:addFile
方法会将指定的文件分发到yarn集群的每一个计算节点上,保存到程序运行时的临时目录。
SparkFiles.get
方法会获取到临时文件的绝对路径,程序就能用这个路径访问文件了。
addFile
能够添加目录,添加目录时会按照目录结构分发到yarn节点。
用SparkFiles.get
获取的时候可以填入路径,否则获取的时候不指定路径,只指定文件名:
object Test {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("Test")
.enableHiveSupport
.getOrCreate()
val df = spark.table("testtable")
spark.sparkContext.addFile("hdfs:///prop/test.properties")
// spark-submit --master yarn --class Test --files hdfs:///prop/test.properties test.jar
df.foreachPartition {
par =>
val file_absolute_path = SparkFiles.get("test.properties") //这里只指定文件名,没有路径
...
}
}
}
不要手动分发配置文件,可能会报错,例如yarn集群运行的时候可能没有权限访问手动分发的文件等。