1. 程式人生 > >讀Hadoop3.2原始碼,深入瞭解java呼叫HDFS的常用操作和HDFS原理

讀Hadoop3.2原始碼,深入瞭解java呼叫HDFS的常用操作和HDFS原理

> 本文將通過一個演示工程來快速上手java呼叫HDFS的常見操作。接下來以建立檔案為例,通過閱讀HDFS的原始碼,一步步展開HDFS相關原理、理論知識的說明。 > 說明:本文件基於最新版本Hadoop3.2.1 # 目錄 ### 一、java呼叫HDFS的常見操作 #### 1.1、演示環境搭建 #### 1.2、操作HDFS #### 1.3、java檔案操作常用方法 ### 二、深入瞭解HDFS寫檔案的流程和HDFS原理 #### 2.1、Hadoop3.2.1 原始碼下載及介紹 #### 2.2、檔案系統:FileSystem #### 2.3、HDFS體系結構:namenode、datanode、資料塊 #### 2.4、如何訪問阿里雲OSS等檔案系統 #### 2.5、檔案租約機制 #### 2.6、RPC機制 #### 2.7、HDFS客戶端寫流程總結 #### 2.8、Hadoop3.x新特性:糾刪碼 #### 2.9 檔案透明加密處理和目錄樹 #### 2.10、HDFS客戶端寫流程總結 --- # 一、java呼叫HDFS的常見操作 首先我們搭建一個簡單的演示工程(演示工程使用的gradle,Maven專案也同樣新增以下依賴),本次使用的是Hadoop最新的3.2.1。 ## 1.1、演示環境搭建 新增一個普通的java工程即可,過程略,新增hdfs相關依賴jar包 ```java implementation ('org.apache.hadoop:hadoop-common:3.2.1') implementation ('org.apache.hadoop:hadoop-hdfs:3.2.1') implementation ('org.apache.hadoop:hadoop-mapreduce-client-core:3.2.1') implementation ('org.apache.hadoop:hadoop-client:3.2.1') ``` 在實際執行過程中,可能會發現日誌Jar包衝突問題,排除掉即可 ```java exclude group:'org.slf4j',module: 'slf4j-log4j12' ``` ## 1.2、操作HDFS 以建立檔案為例,程式碼如下。可以看到java操作hdfs就是這麼簡單、絲滑,so easy! ```java public static void main(String[] args) throws IOException { // 配置物件 Configuration configuration = new Configuration(); configuration.set("fs.defaultFS", "hdfs://172.22.28.202:9000"); // HDFS檔案系統的操作物件 FileSystem fileSystem = FileSystem.get(configuration); // 建立檔案。 FSDataOutputStream outputStream = fileSystem.create(new Path("/hdfs/madashu/test")); // 寫入檔案內容 outputStream.write("你好Hadoop,我是碼大叔".getBytes()); outputStream.flush(); IOUtils.closeStream(outputStream); } ``` ## 1.3、java檔案操作常用方法 參照第2步檔案建立的操作,我們可以預定義好Configuration和FileSystem,然後提取出HDFSUtil的工具類出來。涉及到檔案方面的操作基本只需要hadoop-common包下的`FileSystem`就足夠了,一些常用方法的說明: ```java //檔案是否存在 fileSystem.exists(new Path(fileName)); //建立目錄 fileSystem.mkdirs(new Path(directorName)); //刪除目錄或檔案,第二個引數表示是否要遞迴刪除 fileSystem.delete(new Path(name), true); //獲取當前登入使用者在HDFS檔案系統中的Home目錄 fileSystem.getHomeDirectory(); //檔案重新命名 fileSystem.rename(new Path(oldName), new Path(newName)); //讀取檔案,返回的是FSDataInputStream fileSystem.open(new Path(fileName)); //建立檔案,第二個引數表示檔案存在時是否覆蓋 fileSystem.create(new Path(fileName), false); //從本地目錄上傳檔案到HDFS fileSystem.copyFromLocalFile(localPath, hdfsPath); //獲取目錄下的檔案資訊,包含path,length,group,blocksize,permission等等 fileSystem.listStatus(new Path(directorName)); //釋放資源 fileSystem.close(); //設定HDFS資源許可權,其中FsPermission可以設定user、group等 fileSystem.setPermission(new Path(resourceName), fsPermission); //設定HDFS資源的Owner和group fileSystem.setOwner(new Path(resourceName), ownerName, groupName); //設定檔案的副本 fileSystem.setReplication(new Path(resourceName), count); ``` # 二、深入瞭解HDFS寫檔案的流程和HDFS原理 檔案操作的方法比較多,本期我們以create方法為例,來通過閱讀原始碼深入瞭解下hdfs寫檔案的流程和原理,程式碼參見1.2 。 ## 2.1、Hadoop3.2.1 原始碼下載及介紹 **hadoop原始碼地址**:https://github.com/apache/hadoop,。 正常途徑下訪問比較慢的同學(每次寫到這句話,都滿臉的憂傷和xx)也可以通過國內的**清華大學開源軟體映象站**來下載,地址是https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.1/hadoop-3.2.1-src.tar.gz 下載後我們可以看到這是一個maven工程,匯入到idea等我們熟悉開發工具中即可。如果是使用VS需要編譯的小夥伴注意下, ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200329175011478.png) 目錄下有一個BUILDINDG.txt檔案,針對比較關鍵的幾個modules做了說明。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020032918141152.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phNW9u,size_16,color_FFFFFF,t_70) 這裡面很多工程都是和打包相關的,有一個沒提到的“hadoop-cloud-storage-project”是和雲端儲存相關的,比如我們熟悉的阿里雲,AWS等。這次我們需要關注的是hadoop-hdfs-project,hadoop-hdfs-common-project。 ## 2.2、檔案系統:FileSystem 程式碼參見1.2,我們看到在操作hdfs之前首先需要根據配置檔案獲取檔案系統。 **問題**: 1、為什麼傳入的地址是“hdfs:”開頭的 2、為什麼要獲取檔案作業系統 我們直接進入get方法 ```java public static FileSystem get(URI uri, Configuration conf) throws IOException { //獲取檔案的字首,即我們傳入的 hdfs: String scheme = uri.getScheme(); // 為了便於閱讀,刪除掉很多程式碼 // 從快取中獲取 return CACHE.get(uri, conf); } ``` 那麼快取中存放了什麼呢?一層層深入程式碼,首先會檢查檔案系統是否存在,不存在則建立檔案系統,最終將檔案系統存放在map中。 ```java private static f