1. 程式人生 > >HDFS(三)——用 Java 建立一個 HDFS 目錄,HDFS 的許可權的問題

HDFS(三)——用 Java 建立一個 HDFS 目錄,HDFS 的許可權的問題

一、匯入 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 就不會執行許可權檢查了。