Hadoop HDFS入門
Hadoop 附帶了一個名爲 HDFS(Hadoop分佈式文件系統)的分佈式文件系統,基於 Hadoop 的應用程序使用 HDFS 。HDFS 是專爲存儲超大數據文件,運行在集羣的商品硬件上。它是容錯的,可伸縮的,並且非常易於擴展。
你知道嗎? 當數據超過一個單個物理機器上存儲的容量,除以跨獨立機器數。管理跨越機器的網絡存儲特定操作被稱爲分佈式文件系統。
HDFS集羣主要由 NameNode 管理文件系統 Metadata 和 DataNodes 存儲的實際數據。
NameNode: NameNode可以被認爲是系統的主站。它維護所有系統中存在的文件和目錄的文件系統樹和元數據 。 兩個文件:「命名空間映像「和」編輯日誌「是用來存儲元數據信息。Namenode 有所有包含數據塊爲一個給定的文件中的數據節點的知識,但是不存儲塊的位置持續。從數據節點在系統每次啓動時信息重構一次。
DataNode : DataNodes作爲從機,每臺機器位於一個集羣中,並提供實際的存儲. 它負責爲客戶讀寫請求服務。
HDFS中的讀/寫操作運行在塊級。HDFS數據文件被分成塊大小的塊,這是作爲獨立的單元存儲。默認塊大小爲64 MB。
HDFS操作上是數據複製的概念,其中在數據塊的多個副本被創建,分佈在整個節點的羣集以使在節點故障的情況下數據的高可用性。
注: 在HDFS的文件,比單個塊小,不佔用塊的全部存儲。
在HDFS讀操作
數據讀取請求將由 HDFS,NameNode和DataNode來服務。讓我們把讀取器叫 「客戶」。下圖描繪了文件的讀取操作在 Hadoop 中。
客戶端啓動通過調用文件系統對象的 open() 方法讀取請求; 它是 DistributedFileSystem 類型的對象。
此對象使用 RPC 連接到 namenode 並獲取的元數據信息,如該文件的塊的位置。 請注意,這些地址是文件的前幾個塊。
響應該元數據請求,具有該塊副本的 DataNodes 地址被返回。
一旦接收到 DataNodes 的地址,FSDataInputStream 類型的一個對象被返回到客戶端。 FSDataInputStream 包含 DFSInputStream 這需要處理交互 DataNode 和 NameNode。在上圖所示的步驟4,客戶端調用 read() 方法,這將導致 DFSInputStream 建立與第一個 DataNode 文件的第一個塊連接。
以數據流的形式讀取數據,其中客戶端多次調用 「read() 」 方法。 read() 操作這個過程一直持續,直到它到達塊結束位置。
一旦到模塊的結尾,DFSInputStream 關閉連接,移動定位到下一個 DataNode 的下一個塊
一旦客戶端已讀取完成後,它會調用 close()方法。
HDFS寫操作
在本節中,我們將瞭解如何通過的文件將數據寫入到 HDFS。
- 客戶端通過調用 DistributedFileSystem對象的 create() 方法創建一個新的文件,並開始寫操作 - 在上面的圖中的步驟1
- DistributedFileSystem對象使用 RPC 調用連接到 NameNode,並啓動新的文件創建。但是,此文件創建操作不與文件任何塊相關聯。NameNode 的責任是驗證文件(其正被創建的)不存在,並且客戶端具有正確權限來創建新文件。如果文件已經存在,或者客戶端不具有足夠的權限來創建一個新的文件,則拋出 IOException 到客戶端。否則操作成功,並且該文件新的記錄是由 NameNode 創建。
- 一旦 NameNode 創建一條新的記錄,返回FSDataOutputStream 類型的一個對象到客戶端。客戶端使用它來寫入數據到 HDFS。數據寫入方法被調用(圖中的步驟3)。
- FSDataOutputStream包含DFSOutputStream對象,它使用 DataNodes 和 NameNode 通信後查找。當客戶機繼續寫入數據,DFSOutputStream 繼續創建這個數據包。這些數據包連接排隊到一個隊列被稱爲 DataQueue
- 還有一個名爲 DataStreamer 組件,用於消耗DataQueue。DataStreamer 也要求 NameNode 分配新的塊,揀選 DataNodes 用於複製。
- 現在,複製過程始於使用 DataNodes 創建一個管道。 在我們的例子中,選擇了複製水平3,因此有 3 個 DataNodes 管道。
- 所述 DataStreamer 注入包分成到第一個 DataNode 的管道中。
- 在每個 DataNode 的管道中存儲數據包接收並同樣轉發在第二個 DataNode 的管道中。
- 另一個隊列,「Ack Queue」是由 DFSOutputStream 保持存儲,它們是 DataNodes 等待確認的數據包。
- 一旦確認在隊列中的分組從所有 DataNodes 已接收在管道,它從 'Ack Queue' 刪除。在任何 DataNode 發生故障時,從隊列中的包重新用於操作。
- 在客戶端的數據寫入完成後,它會調用close()方法(第9步圖中),調用close()結果進入到清理緩存剩餘數據包到管道之後等待確認。
- 一旦收到最終確認,NameNode 連接告訴它該文件的寫操作完成。
使用JAVA API訪問HDFS
在本節中,我們來了解 Java 接口並用它們來訪問Hadoop的文件系統。
爲了使用編程方式與 Hadoop 文件系統進行交互,Hadoop 提供多種 Java 類。**org.apache.hadoop.fs** 包中包含操縱 Hadoop 文件系統中的文件類工具。這些操作包括,打開,讀取,寫入,和關閉。實際上,對於 Hadoop 文件 API 是通用的,可以擴展到 HDFS 的其他文件系統交互。
編程從 HDFS 讀取文件
java.net.URL 對象是用於讀取文件的內容。首先,我們需要讓 Java 識別 Hadoop 的 HDFS URL架構。這是通過調用 URL 對象的 setURLStreamHandlerFactory方法和 FsUrlStreamHandlerFactory 的一個實例琮傳遞給它。此方法只需要執行一次在每個JVM,因此,它被封閉在一個靜態塊中。
示例代碼
publicclassURLCat {
static{
URL.setURLStreamHandlerFactory(newFsUrlStreamHandlerFactory());
}
publicstaticvoidmain(String[] args) throwsException {
InputStream in = null;
try{
in = newURL(args[0]).openStream();
IOUtils.copyBytes(in, System.out, 4096, false);
} finally{
IOUtils.closeStream(in);
}
}
}
這段代碼用於打開和讀取文件的內容。HDFS文件的路徑作爲命令行參數傳遞給該程序。
使用命令行界面訪問HDFS
這是與 HDFS 交互的最簡單的方法之一。 命令行接口支持對文件系統操作,例如:如讀取文件,創建目錄,移動文件,刪除數據,並列出目錄。
可以執行 '$HADOOP_HOME/bin/hdfs dfs -help' 來獲得每一個命令的詳細幫助。這裏, 'dfs' HDFS是一個shell命令,它支持多個子命令。首先要啓動 Haddop 服務(使用 hduser_用戶),執行命令如下:
hduser_@ubuntu:$ su hduser_$ $HADOOP_HOME/sbin/start-dfs.sh
hduser_@ubuntu:
hduser_@ubuntu:~$ $HADOOP_HOME/sbin/start-yarn.sh
一些廣泛使用的命令的列表如下
1. 從本地文件系統複製文件到 HDFS
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -copyFromLocal temp.txt /
此命令將文件從本地文件系統拷貝 temp.txt 文件到 HDFS。
2. 我們可以通過以下命令列出一個目錄下存在的文件 -ls
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -ls /
我們可以看到一個文件 'temp.txt「(之前複製)被列在」/「目錄。
3. 以下命令將文件從 HDFS 拷貝到本地文件系統
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt
我們可以看到 temp.txt 已經複製到本地文件系統。
4. 以下命令用來創建新的目錄
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory