你知道嗎? 當(dāng)數(shù)據(jù)超過一個(gè)單個(gè)物理機(jī)器上存儲(chǔ)的容量,除以跨獨(dú)立機(jī)器數(shù)。管理跨越機(jī)器的網(wǎng)絡(luò)存儲(chǔ)特定操作被稱為分布式文件系統(tǒng)。
HDFS集群主要由 NameNode 管理文件系統(tǒng) Metadata 和 DataNodes 存儲(chǔ)的實(shí)際數(shù)據(jù)。
-
NameNode: NameNode可以被認(rèn)為是系統(tǒng)的主站。它維護(hù)所有系統(tǒng)中存在的文件和目錄的文件系統(tǒng)樹和元數(shù)據(jù) 。 兩個(gè)文件:“命名空間映像“和”編輯日志“是用來存儲(chǔ)元數(shù)據(jù)信息。Namenode 有所有包含數(shù)據(jù)塊為一個(gè)給定的文件中的數(shù)據(jù)節(jié)點(diǎn)的知識(shí),但是不存儲(chǔ)塊的位置持續(xù)。從數(shù)據(jù)節(jié)點(diǎn)在系統(tǒng)每次啟動(dòng)時(shí)信息重構(gòu)一次。
-
DataNode : DataNodes作為從機(jī),每臺(tái)機(jī)器位于一個(gè)集群中,并提供實(shí)際的存儲(chǔ). 它負(fù)責(zé)為客戶讀寫請(qǐng)求服務(wù)。
HDFS中的讀/寫操作運(yùn)行在塊級(jí)。HDFS數(shù)據(jù)文件被分成塊大小的塊,這是作為獨(dú)立的單元存儲(chǔ)。默認(rèn)塊大小為64 MB。
HDFS操作上是數(shù)據(jù)復(fù)制的概念,其中在數(shù)據(jù)塊的多個(gè)副本被創(chuàng)建,分布在整個(gè)節(jié)點(diǎn)的群集以使在節(jié)點(diǎn)故障的情況下數(shù)據(jù)的高可用性。
注: 在HDFS的文件,比單個(gè)塊小,不占用塊的全部存儲(chǔ)。
在HDFS讀操作
數(shù)據(jù)讀取請(qǐng)求將由 HDFS,NameNode和DataNode來服務(wù)。讓我們把讀取器叫 “客戶”。下圖描繪了文件的讀取操作在 Hadoop 中。

-
客戶端啟動(dòng)通過調(diào)用文件系統(tǒng)對(duì)象的 open() 方法讀取請(qǐng)求; 它是 DistributedFileSystem 類型的對(duì)象。
-
此對(duì)象使用 RPC 連接到 namenode 并獲取的元數(shù)據(jù)信息,如該文件的塊的位置。 請(qǐng)注意,這些地址是文件的前幾個(gè)塊。
-
響應(yīng)該元數(shù)據(jù)請(qǐng)求,具有該塊副本的 DataNodes 地址被返回。
-
一旦接收到 DataNodes 的地址,F(xiàn)SDataInputStream 類型的一個(gè)對(duì)象被返回到客戶端。 FSDataInputStream 包含 DFSInputStream 這需要處理交互 DataNode 和 NameNode。在上圖所示的步驟4,客戶端調(diào)用 read() 方法,這將導(dǎo)致 DFSInputStream 建立與第一個(gè) DataNode 文件的第一個(gè)塊連接。
-
以數(shù)據(jù)流的形式讀取數(shù)據(jù),其中客戶端多次調(diào)用 “read() ” 方法。 read() 操作這個(gè)過程一直持續(xù),直到它到達(dá)塊結(jié)束位置。
-
一旦到模塊的結(jié)尾,DFSInputStream 關(guān)閉連接,移動(dòng)定位到下一個(gè) DataNode 的下一個(gè)塊
-
一旦客戶端已讀取完成后,它會(huì)調(diào)用 close()方法。
HDFS寫操作
在本節(jié)中,我們將了解如何通過的文件將數(shù)據(jù)寫入到 HDFS。

-
客戶端通過調(diào)用 DistributedFileSystem對(duì)象的 create() 方法創(chuàng)建一個(gè)新的文件,并開始寫操作 - 在上面的圖中的步驟1
-
DistributedFileSystem對(duì)象使用 RPC 調(diào)用連接到 NameNode,并啟動(dòng)新的文件創(chuàng)建。但是,此文件創(chuàng)建操作不與文件任何塊相關(guān)聯(lián)。NameNode 的責(zé)任是驗(yàn)證文件(其正被創(chuàng)建的)不存在,并且客戶端具有正確權(quán)限來創(chuàng)建新文件。如果文件已經(jīng)存在,或者客戶端不具有足夠的權(quán)限來創(chuàng)建一個(gè)新的文件,則拋出 IOException 到客戶端。否則操作成功,并且該文件新的記錄是由 NameNode 創(chuàng)建。
-
一旦 NameNode 創(chuàng)建一條新的記錄,返回FSDataOutputStream 類型的一個(gè)對(duì)象到客戶端??蛻舳耸褂盟鼇韺懭霐?shù)據(jù)到 HDFS。數(shù)據(jù)寫入方法被調(diào)用(圖中的步驟3)。
-
FSDataOutputStream包含DFSOutputStream對(duì)象,它使用 DataNodes 和 NameNode 通信后查找。當(dāng)客戶機(jī)繼續(xù)寫入數(shù)據(jù),DFSOutputStream 繼續(xù)創(chuàng)建這個(gè)數(shù)據(jù)包。這些數(shù)據(jù)包連接排隊(duì)到一個(gè)隊(duì)列被稱為 DataQueue
-
還有一個(gè)名為 DataStreamer 組件,用于消耗DataQueue。DataStreamer 也要求 NameNode 分配新的塊,揀選 DataNodes 用于復(fù)制。
-
現(xiàn)在,復(fù)制過程始于使用 DataNodes 創(chuàng)建一個(gè)管道。 在我們的例子中,選擇了復(fù)制水平3,因此有 3 個(gè) DataNodes 管道。
-
所述 DataStreamer 注入包分成到第一個(gè) DataNode 的管道中。
-
在每個(gè) DataNode 的管道中存儲(chǔ)數(shù)據(jù)包接收并同樣轉(zhuǎn)發(fā)在第二個(gè) DataNode 的管道中。
-
另一個(gè)隊(duì)列,“Ack Queue”是由 DFSOutputStream 保持存儲(chǔ),它們是 DataNodes 等待確認(rèn)的數(shù)據(jù)包。
-
一旦確認(rèn)在隊(duì)列中的分組從所有 DataNodes 已接收在管道,它從 'Ack Queue' 刪除。在任何 DataNode 發(fā)生故障時(shí),從隊(duì)列中的包重新用于操作。
-
在客戶端的數(shù)據(jù)寫入完成后,它會(huì)調(diào)用close()方法(第9步圖中),調(diào)用close()結(jié)果進(jìn)入到清理緩存剩余數(shù)據(jù)包到管道之后等待確認(rèn)。
-
一旦收到最終確認(rèn),NameNode 連接告訴它該文件的寫操作完成。
使用JAVA API訪問HDFS
在本節(jié)中,我們來了解 Java 接口并用它們來訪問Hadoop的文件系統(tǒng)。
為了使用編程方式與 Hadoop 文件系統(tǒng)進(jìn)行交互,Hadoop 提供多種 Java 類。org.apache.hadoop.fs 包中包含操縱 Hadoop 文件系統(tǒng)中的文件類工具。這些操作包括,打開,讀取,寫入,和關(guān)閉。實(shí)際上,對(duì)于 Hadoop 文件 API 是通用的,可以擴(kuò)展到 HDFS 的其他文件系統(tǒng)交互。
編程從 HDFS 讀取文件
java.net.URL 對(duì)象是用于讀取文件的內(nèi)容。首先,我們需要讓 Java 識(shí)別 Hadoop 的 HDFS URL架構(gòu)。這是通過調(diào)用 URL 對(duì)象的 setURLStreamHandlerFactory方法和 FsUrlStreamHandlerFactory 的一個(gè)實(shí)例琮傳遞給它。此方法只需要執(zhí)行一次在每個(gè)JVM,因此,它被封閉在一個(gè)靜態(tài)塊中。
示例代碼
| | 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); } } } |
這段代碼用于打開和讀取文件的內(nèi)容。HDFS文件的路徑作為命令行參數(shù)傳遞給該程序。
使用命令行界面訪問HDFS
這是與 HDFS 交互的最簡單的方法之一。 命令行接口支持對(duì)文件系統(tǒng)操作,例如:如讀取文件,創(chuàng)建目錄,移動(dòng)文件,刪除數(shù)據(jù),并列出目錄。
可以執(zhí)行 '$HADOOP_HOME/bin/hdfs dfs -help' 來獲得每一個(gè)命令的詳細(xì)幫助。這里, 'dfs' HDFS是一個(gè)shell命令,它支持多個(gè)子命令。首先要啟動(dòng) Haddop 服務(wù)(使用 hduser_用戶),執(zhí)行命令如下:
hduser_@ubuntu:~$ su hduser_
hduser_@ubuntu:~$ $HADOOP_HOME/sbin/start-dfs.sh
hduser_@ubuntu:~$ $HADOOP_HOME/sbin/start-yarn.sh
一些廣泛使用的命令的列表如下
1. 從本地文件系統(tǒng)復(fù)制文件到 HDFS
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -copyFromLocal temp.txt /
此命令將文件從本地文件系統(tǒng)拷貝 temp.txt 文件到 HDFS。
2. 我們可以通過以下命令列出一個(gè)目錄下存在的文件 -ls
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -ls /


我們可以看到一個(gè)文件 'temp.txt“(之前復(fù)制)被列在”/“目錄。
3. 以下命令將文件從 HDFS 拷貝到本地文件系統(tǒng)
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt
我們可以看到 temp.txt 已經(jīng)復(fù)制到本地文件系統(tǒng)。
4. 以下命令用來創(chuàng)建新的目錄
hduser_@ubuntu:~$ $HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory
接下來檢查是否已經(jīng)建立了目錄?,F(xiàn)在,應(yīng)該知道怎么做了吧?