启动Spark时遇到的HDFS user的读写权限问题:ERROR spark.SparkContext: Error initializing SparkContext. org.apache...

之前在为客户做数据湖产品调试Spark程序的时候,遇到过一个报错:

ERROR spark.SparkContext: Error initializing SparkContext.
org.apache.hadoop.security.AccessControlException: Permission denied:user=datalake, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x
at
org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:400)

一、原因分析

从日志中大致可以看出,是因为Spark在启动阶段初始化SparkContext时遇到了write权限问题,其中当前用户为datalake,要执行write操作的目录是HDFS的/user目录。想要figure out这个问题,首先需要了解HDFS的/user目录是干嘛用的。

1.1 HDFS的home目录

注意,Hadoop 的 home 目录和 HDFS 的 home目录是两回事:

  • Hadoop 的 home 目录:Hadoop的安装目录,通常会配置在环境变量PATH中;
  • HDFS 的 home 目录:是指每个访问HDFS的用户目录,定义在:/user/{user_id},比如上面的/user/datalake
    比如,在列出我的mac上HDFS的所有{user_id}:
datalake$ hdfs dfs -ls /user

Found 1 items
drwxr-xr-x   - ycaha supergroup          0 2019-08-05 13:05 /user/hive

很显然,HDFS中的home目录只有/user/hive,其中hive为user_id。从权限描述可以看出,/user/hive是个目录(首字母如果是d表示目录,如果是-表示文件),owner为ycaha,所属用户组为supergroup,ycaha、supergroup、以及其他用户对/user/hive的权限分别为:可读可写可执行、可读不可写可执行、可读不可写可执行(rwxr-xr-x,每三个字符一组表示用户或者用户组的权限)。关于linux用户权限可以参考:https://www.cnblogs.com/garfieldcgf/p/8323489.html

1.2 创建新的user_id

比如以datalake用户去执行Spark程序,Spark在启动阶段初始化SparkContext时需要访问工作目录/user/datalake,此时必须保证两个条件都成立:

    1. HDFS存在目录/user/datalake;
    1. datalake用户对于目录/user/datalake具有write权限;

可以通过如下命令来创建新的user_id:

# 首先使用具有write权限的用户,比如上面的ycaha
# 然后创建新user_id目录
hdfs dfs -mkdir /user/datalake

可以看到新的user_id:

drwxr-xr-x   - ycaha supergroup          0 2019-10-17 20:53 /user/datalake
drwxr-xr-x   - ycaha supergroup          0 2019-08-05 13:05 /user/hive

但是datalake用户的权限是-xr,即不具备write权限,因此接下来需要修改用户权限或者目录权限,比如下面修改目录/user/datalake的权限为775(datalake具有可读可写可执行权限):

hdfs dfs -chmod 775 /user/datalake 

得到:

ycaha$ hdfs dfs -ls /user/

Found 2 items
drwxrwxr-x   - ycaha supergroup          0 2019-10-17 20:53 /user/datalake
drwxr-xr-x   - ycaha supergroup          0 2019-08-05 13:05 /user/hive


二、解决方案

2.1 方案1

直接像1.2中一样,创建一个新的user_id(即datalake)并赋予用户write权限即可。

2.2 方案2:修改默认的spark.yarn.stagingDir配置

spark.yarn.stagingDir是Spark的一个配置项,用于指定Spark在提交应用程序时使用的暂存目录,该配置项配置在spark-defaults.conf中,其默认值是当前用户在文件系统中的主目录,比如/user/datalake。
因此可以通过修改spark.yarn.stagingDir的值,将其指向一个“提交Spark job用户”具有write权限的目录即可,比如/usr/sparkjob/tmp/。
也可以在提交Spark job的时候,显式地指定配置项spark.yarn.stagingDir的值,比如:

--conf spark.yarn.stagingDir=hdfs:///

注意:hdfs:///不可省略。


如有错误之处,敬请指正!

参考:
https://www.cloudera.com/documentation/enterprise/latest/PDF/cloudera-spark.pdf
https://stackoverflow.com/questions/42723604/how-to-set-spark-job-staging-location
https://www.jianshu.com/p/e7838e9e5c44

你可能感兴趣的:(启动Spark时遇到的HDFS user的读写权限问题:ERROR spark.SparkContext: Error initializing SparkContext. org.apache...)