HDFS(三)——用 Java 创建一个 HDFS 目录,HDFS 的权限的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a909301740/article/details/84350245

一、导入 HDFS 所需 jar 包

把解压后的 hadoop 文件夹下的 common 目录中的 jar,和里面的 lib 包中所有的 jar,以及 hdfs 目录下的 jar,和里面的 lib 包中所有的 jar 都添加到项目的环境变量中。

hdfs

二、编写测试代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

/**
 * @author 曲健磊
 * @date 2018-11-24 23:20:45
 */
public class TestMkDir {

    @Test
    public void test1() throws Exception {
        // 指定NameNode的地址
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://192.168.220.111:9000");

        // 获取一个HDFS 客户端
        FileSystem client = FileSystem.get(conf);
        client.mkdirs(new Path("/folder1"));
        // 关闭
        client.close();
    }
}
  1. 创建一个 Configuration 对象,并设置 NameNode 的地址。
  2. 根据 Configuration 对象获取一个 HDFS 客户端。
  3. 调用 mkdirs 方法,传入一个 Path 对象,参数为 “/folder1” 。
  4. 关闭客户端。
  5. 然后我们开启装有 hadoop 的虚拟机,执行 start-all.sh启动 HDFS 和 YARN,执行上面的单元测试。

然后我们就会发现,在控制台爆出了如下异常信息:

org.apache.hadoop.security.AccessControlException: 
Permission denied: user=dell, access=WRITE, 
inode="/folder1":root:supergroup:drwxr-xr-x

...

Caused by: org.apache.hadoop.ipc.RemoteException
(org.apache.hadoop.security.AccessControlException): 
Permission denied: user=dell, access=WRITE, 
inode="/folder1":root:supergroup:drwxr-xr-x

...

分析:可以看出是没有权限,我们要创建 /folder1目录,需要 WRITE()权限,只有 root 用户有写权限,组内成员和其他人只有执行这两个权限,而我们当前的用户又是 dell,所以就没有权限创建目录。

解决方案:

1. 通过代码的方式来设置当前用户名为 root

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

/**
 * @author 曲健磊
 * @date 2018-11-24 23:20:45
 */
public class TestMkDir {

    @Test
    public void test1() throws Exception {
        System.setProperty("HADOOP_USER_NAME", "root");

        // 指定NameNode的地址
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://192.168.220.111:9000");

        // 获取一个HDFS 客户端
        FileSystem client = FileSystem.get(conf);
        client.mkdirs(new Path("/folder1"));
        // 关闭
        client.close();
    }
}

Hadoop 对权限的检查比较弱,你告诉它你叫啥,它就认为你叫啥,你告诉它你叫 root,它就认为你叫 root。

2. 通过-D参数来设置当前操作的用户名

这种方式的操作的本质和前一种方式是一样的,都是通过修改参数来实现。

代码还是原来的代码:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Test;

/**
 * @author 曲健磊
 * @date 2018-11-24 23:20:45
 */
public class TestMkDir {

    @Test
    public void test1() throws Exception {
        // 指定NameNode的地址
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://192.168.220.111:9000");

        // 获取一个HDFS 客户端
        FileSystem client = FileSystem.get(conf);
        client.mkdirs(new Path("/folder1"));
        // 关闭
        client.close();
    }
}

在执行代码的时候通过 -D 参数来指定 HADOOP_USER_NAME 为 root:
java -DHADOOP_USER_NAME root TestMkDir,这样在执行程序的时候,程序获取到的系统中的变量 HADOOP_USER_NAME 的值就是 root,当前用户 root,就可以拥有创建目录的权限。

3. 改变目录的权限

比方说我们要在 /folder1目录下创建 /folder1/folder2只需要把 /folder1的目录权限设置为所有人可读,可写,可执行即可:chmod /folder1 777

缺点是:针对根目录就没有办法。

4. 在 hdfs-site.xml 文件中配置禁用权限检查

一般使用这种方式,在 hdfs-site.xml 配置文件中加入如下配置:

<!--是否开启HDFS的权限检查,默认true,先不设置-->
<property>
   <name>dfs.permissions</name>
   <value>false</value>
</property>

参见:Hadoop的三种配置模式以及免密登录

再执行测试代码,hadoop 就不会执行权限检查了。

猜你喜欢

转载自blog.csdn.net/a909301740/article/details/84350245