在使用Hadoop HDFS时,几乎初学者都会遇到下面的权限问题,有的人草草搜索解决了,却不知道为什么,下次换一种场景依然解决不了。只有了解其本质原因,才能举一反三。
异常信息:
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): Permission denied: user=administrator, access=WRITE, inode="/user/hdfs/xxx":hdfs:supergroup:drwxr-xr-x
几乎人人都知道这个报错是权限问题,发生这个错误的场景:
场景
- 在windows上,我通过IDEA使用Hadoop Client读取HDFS上的文件
- 在linux上,我使用非hdfs用户上传文件:
hdfs dfs -put jimo.txt /usr/hdfs
显然,问题原因就是我们使用的用户对HDFS目录没有操作权限,我们使用的用户如果不指定,默认是系统用户:也就是当前登录用户,不论操作系统。
解决
那简单,切换成相应的hdfs用户吧。
linux完全ok,而windows要建一个用户就很麻烦了,所以,正确的方式Hadoop也考虑到了:手动指定用户!
通过设置 HADOOP_USER_NAME
这个环境变量来设置用户。
Java代码里
有的情况,你只需要设置一行代码即可,比如:
System.setProperty("HADOOP_USER_NAME", hdfsUser);
return FileSystem.get(new URI(hdfsPath), conf);
然后,有的情况是搞不定的。
当代码里设置不生效时
这种情况发生在Spark调用Hadoop上,当我们在本地(比如windows上)调试Spark程序时,设计到用spark读取hdfs,即便我们设置了HADOOP_USER_NAME
, 他也不会生效,这时候就需要设置外部环境变量,不是在spark内部设置,而是启动spark程序之前就得设置。
一种方式是:设置系统级环境变量:直接在windows环境变量里配,或者linux下profile里配。
如果使用IDEA开发工具,可以很方便配置:
之后在开发调试时,我不想再看见这个异常,也希望不再看见。
不优美的解决方式
网上有的人直接修改目录权限:这里指的是HDFS集群上的目录权限
hdfs dfs -chmod -R 777 /user
虽然可以达到目的,但权限控制就没意义了。