Spark/Hadoop无法读取仅root及本人有权限的目录文件问题求助
根据你的描述,核心矛盾是YARN的hadoop进程用户没有权限访问仅你和root拥有权限的/mount/bases目录,同时你不能开放该目录权限给其他用户。下面提供几个可行的解决方案,按推荐程度排序:
方案1:以你的用户身份提交Spark任务(用户模拟)
这个方案让Spark任务在YARN上以你的身份运行,直接继承你对/mount/bases的访问权限,完全不需要修改目录原有权限。
步骤如下:
先确认集群是否配置了代理用户权限(需要管理员协助,若已配置可跳过):
- 修改Hadoop的
core-site.xml,添加以下配置:<property> <name>hadoop.proxyuser.hadoop.groups</name> <value>你的用户组名称</value> </property> <property> <name>hadoop.proxyuser.hadoop.hosts</name> <value>*</value> <!-- 可根据集群安全需求限制为特定主机 --> </property> - 重启HDFS和YARN服务使配置生效。
- 修改Hadoop的
启动Spark Shell时指定以你的身份运行:
spark-shell \ --conf spark.yarn.principal=你的用户名@集群Kerberos域 \ --conf spark.yarn.keytab=/path/to/你的密钥文件.keytab \ --conf spark.yarn.submit.waitAppCompletion=true(如果集群未启用Kerberos,可简化为
spark-shell --conf spark.yarn.user=你的用户名,具体取决于集群配置)此时Spark任务的执行进程会以你的用户身份运行,就能正常读取
/mount/bases下的文件了。
方案2:将私有数据复制到HDFS的私有目录
如果方案1需要管理员配置比较麻烦,可以先把目标文件复制到HDFS中属于你的私有目录,再让Spark读取HDFS路径,既保证数据安全又绕开本地目录权限问题:
在HDFS创建你的私有目录并设置严格权限:
hadoop fs -mkdir -p /user/你的用户名/private_data hadoop fs -chmod 700 /user/你的用户名/private_data将CIFS挂载目录下的文件复制到HDFS私有目录:
hadoop fs -put /mount/bases/目标文件名 /user/你的用户名/private_data/在Spark Shell中读取HDFS路径:
val df = spark.read.csv("hdfs:///user/你的用户名/private_data/目标文件名")使用完毕后可以删除HDFS上的临时文件,避免占用存储:
hadoop fs -rm /user/你的用户名/private_data/目标文件名
方案3:使用本地Spark模式而非YARN
如果你的任务不需要分布式计算能力,直接以你的用户身份启动本地模式的Spark Shell,绕开YARN的hadoop用户限制:
spark-shell --master local[*]
此时Spark进程完全以你的身份运行,直接就能访问/mount/bases目录,无需任何额外配置。这个方案最简单,但只适用于本地计算场景。
方案4:调整CIFS挂载的权限映射(谨慎使用)
如果你信任hadoop用户,且集群管理员允许,可以在挂载CIFS共享时将目录的UID/GID映射为hadoop用户的UID/GID,让hadoop用户获得访问权限的同时,保留目录的私有性:
先查看
hadoop用户的UID和GID:id hadoop输出类似
uid=1001(hadoop) gid=1001(hadoop),记录下UID和GID数值。重新挂载CIFS共享(需要root权限):
umount /mount/bases mount -t cifs //你的CIFS服务器/共享路径 /mount/bases \ -o username=CIFS用户名,password=CIFS密码,uid=1001,gid=1001,file_mode=0600,dir_mode=0700其中
file_mode=0600和dir_mode=0700保证只有所有者(此时是hadoop用户)和root能访问,符合你对私有数据的权限要求。注意:此方案会让hadoop用户拥有该目录的读写权限,需确保该用户是可信的。
内容的提问来源于stack exchange,提问作者Jader Martins

