SparkSession.sql查询报Permission denied错误


发布于 2022-05-14 / 58 阅读 / 0 评论 /
通过SparkSession执行sparksql任务,报Permission denied错误

1.问题描述

在进行spark-sql查询时,以yarn client的模式提交spark任务,任务是创建SparkSession,并执行sql脚本,在执行sql的过程中报Permission Denied错误。如下图所示:

上面是最高层的报错堆栈,最底层的报错还在UnixFileSystem.createFileExeclusively报错。如下图所示:

创建文件时没有权限。

2.问题分析

根据错误堆栈信息,发现代码出错的地方在如下代码中,在创建sparksession时,需要创建临时文件,就是在创建临时文件时报错了

/**
 * @param conf
 * @return per-session temp file
 * @throws IOException
 */
private static File createTempFile(HiveConf conf) throws IOException {
	String lScratchDir = HiveConf.getVar(conf, HiveConf.ConfVars.LOCALSCRATCHDIR);
	String sessionID = conf.getVar(HiveConf.ConfVars.HIVESESSIONID);

	return FileUtils.createTempFile(lScratchDir, sessionID, ".pipeout");
}

对应的HiveConf参数定义如下

LOCALSCRATCHDIR("hive.exec.local.scratchdir", "${system:java.io.tmpdir}" + File.separator + "${system:user.name}", "Local scratch space for Hive jobs"),
HIVESESSIONID("hive.session.id", "", “"),

java.io.tmpdir的默认值为“/tmp/”,也就是说,文件一般在/tmp/目录下。

3.解决方案

这个报错根据场景的不同对应不同的解决方案。

如果设置了hive.exec.local.scratchdir参数,只要把对应的目录权限修改即可。当前环境对应的scratchdir为/data/emr/hive/tmp/目录,所以只需要把/data/emr/hive/tmp/目录权限修改为777即可。

如果没有设置hive.exec.local.scratchdir参数,scratchdir默认值与当前任务的启动用户相关,用户名也是一层子目录。理论上来说不会有这个问题,所以不设置hive.exec.local.scratchdir参数也是一种结局方案。