讀Hadoop3.2原始碼,深入瞭解java呼叫HDFS的常用操作和HDFS原理
阿新 • • 發佈:2020-03-30
> 本文將通過一個演示工程來快速上手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