Spark集群提交作业报错:/tmp/hive/文件未找到问题求助
咱们先聚焦报错的核心:com.datastax.bdp.fs.model.NoSuchFileException: File not found: /tmp/hive/。这个错误说明你的Spark作业在DSE集群模式下尝试访问Hive临时目录时,找不到对应的路径——毕竟本地运行环境和集群的分布式文件系统、权限配置差异很大。
先梳理下代码里的小问题(避免额外踩坑)
你的代码里同时用SparkConf和SparkSession.builder做配置,存在重复设置(比如spark.submit.deployMode写了两次),而且master("local[*]")在集群提交时会被spark submit的参数直接覆盖,建议统一用SparkSession管理配置,代码更简洁也不容易冲突:
def main(args: Array[String]) { val spark = SparkSession .builder .appName("Fleet") .config("spark.executor.memory", "1g") .config("spark.driver.memory", "2g") .config("spark.submit.deployMode", "cluster") .config("spark.executor.instances", "4") .config("spark.executor.cores", "3") .config("spark.cores.max", "12") .config("spark.driver.cores", "4") .config("spark.ui.port", "4040") .config("spark.streaming.backpressure.enabled", "true") .config("spark.streaming.kafka.maxRatePerPartition", "30") .config("spark.cassandra.connection.host", "192.168.0.40") .config("spark.cassandra.connection.port", "9042") .getOrCreate() val sc = spark.sparkContext val ssc = new StreamingContext(sc, Seconds(10)) val topics = Map("historyfleet" -> 1) val kafkaStream = KafkaUtils.createStream(ssc, "192.168.0.40:2181", "fleetgroup", topics) kafkaStream.foreachRDD(rdd => { val dfs = rdd.toDF() dfs.show() // 这里不需要套println,show()本身就会打印内容到控制台 dfs.write.format("org.apache.spark.sql.cassandra") .options(Map("table" -> "test", "keyspace" -> "test_db")) .mode(SaveMode.Append) .save() }) ssc.start() ssc.awaitTermination() }
针对集群提交报错的具体解决方案
接下来解决Hive临时目录的问题,按以下步骤操作:
在分布式文件系统上创建并授权Hive临时目录
因为是DSE集群,大概率用的是BDFS(DSE分布式文件系统),如果是HDFS也类似,在集群任意节点执行命令:# 针对BDFS的命令 dfs -mkdir /tmp/hive/ dfs -chmod 777 /tmp/hive/ # 如果是HDFS,用这个命令 hdfs dfs -mkdir /tmp/hive/ hdfs dfs -chmod 777 /tmp/hive/注意:必须在分布式文件系统上创建,不能只在某个节点的本地磁盘创建——集群模式下,Spark的executor会在各个节点运行,需要共享这个目录。
在Spark配置中显式指定Hive相关目录
你可以在代码的SparkSession配置里添加这两项,或者在spark submit命令中指定:- 代码里添加:
.config("spark.sql.warehouse.dir", "/user/hive/warehouse") .config("hive.exec.scratchdir", "/tmp/hive") - 或者在spark submit时通过参数传递:
spark-submit --class your.package.MainClass \ --master dse://your-dse-master-ip \ --deploy-mode cluster \ --conf spark.sql.warehouse.dir=/user/hive/warehouse \ --conf hive.exec.scratchdir=/tmp/hive \ your-application.jar
- 代码里添加:
检查DSE集群的Hive配置文件
登录DSE集群节点,找到hive-site.xml(通常在/etc/dse/hive/目录下),确认hive.exec.scratchdir的配置值是/tmp/hive,并且所有节点配置一致:<property> <name>hive.exec.scratchdir</name> <value>/tmp/hive</value> <description>Temporary scratch space for Hive queries</description> </property>如果配置不对,修改后重启DSE Hive服务。
避免Jar包携带本地Hive配置
检查你的应用Jar包,不要把本地开发环境的hive-site.xml打包进去——否则集群运行时会加载本地配置,导致路径不匹配。
另外,从错误栈能看到你用的是Spark 2.0.2.16(DSE定制版本),这个版本比较旧,如果有条件升级到较新的DSE Spark版本,也能减少这类兼容性问题。
内容的提问来源于stack exchange,提问作者Pinnacle

