原文來自:https://examples.javacodegeeks.com/enterPRise-java/apache-hadoop/apache-hadoop-distributed-file-system-explained/
==========本文采用谷歌翻譯,請參照中英文學習===========
在本例中,我們將詳細討論Apache Hadoop分布式文件系統(HDFS),其組件和體系結構。HDFS是Apache Hadoop生態系統的核心組件之一。
Apache Hadoop提供了一個分布式文件系統和一個框架,用于使用MapReduce范例轉換大型數據集。HDFS旨在在商用硬件上運行時可靠地存儲非常大的數據集。它是容錯的,并且提供對存儲的數據的高吞吐量訪問。雖然HDFS的接口在Unix文件系統之后被圖案化,但它放松了一些POSIX要求以提高其目標解決的應用程序的性能,并提供對存儲在文件系統中的數據的流式訪問。
以下是HDFS的屬性,使其與其他文件系統不同,并使HDFS能夠可靠地處理大量的數據。
HDFS被設計為在一組商品硬件上工作。系統故障被認為是規范。由于存在大量HDFS依賴的組件,考慮到這些組件具有不平凡的故障概率也將導致一個組件或其他組件始終失敗。因此HDFS旨在檢測故障并執行自動恢復以提供所需的性能是HDFS的核心屬性之一。
HDFS設計用于依賴于大??量數據的應用程序。此數據也可以是千兆字節,太字節或PB。因此,HDFS被調整為支持這種大型數據集,并擴展到大型系統集群以存儲此數據,而不會影響數據吞吐量。
HDFS被調整以滿足需要寫入數據一次或最多只讀取幾次并且讀取數據更多的應用程序。由于這些應用程序被假設為依賴于“一次讀取多次讀取”模型,它簡化了數據一致性問題,并允許HDFS提供高吞吐量數據訪問。
HDFS旨在跨異構硬件和軟件平臺移植。這使得HDFS的適應變得非常容易,并且它成為依賴于分布式大數據集的應用的選擇的平臺。
HDFS NameNode和DataNode有兩個主要組件。
HDFS遵循主從架構,其中NameNode是充當主節點的節點。一個HDFS集群只包含一個NameNode。NameNode的主要功能是管理文件系統命名空間,并控制對存儲在HDFS集群中的文件的客戶端認證。它還處理存儲在不同DataNode中的數據的映射。
DataNode是名稱表示在集群中存儲實際數據的節點。集群中有多個DataNode,通常DataNodes的數量與集群中硬件節點的節點相同。DataNode服務于來自客戶端的讀取和寫入請求,并且還處理與塊的創建,塊的刪除和復制相關的數據塊的操作。
在本節中,我們將了解Hadoop分布式文件系統(HDFS)的基本架構。
HDFS是塊結構文件系統,這意味著所有單獨的文件被分成具有固定塊大小的小數據塊。然后,這些塊將存儲在DataNode中的機器集群中。NameNode處理諸如打開,關閉和重命名文件或目錄的功能。如上所述的NameNode還處理集群中的數據的映射,這意味著NameNode跟蹤哪個數據塊存儲在哪個DataNode上以及如何處理該數據的復制。
HDFS命名空間定義了如何在集群中存儲和訪問數據。HDFS支持文件和目錄的傳統分層組織。它還支持幾乎所有需要的函數來處理命名空間操作,如創建或刪除文件或目錄,將文件/目錄從一個地方移動到另一個地方等。正如我們在第3節討論的,NameNode是維護HDFS文件系統命名空間的組件。在NameNode中維護對數據的任何操作,如創建或刪除文件,移動文件或目錄。
由于HDFS旨在將大量數據可靠,安全地存儲在一組商品硬件上。由于這個硬件容易發生故障,HDFS需要以一種方式處理數據,以便在一個或多個系統發生硬件故障時可以輕松地檢索數據。HDFS使用數據復制作為提供容錯功能的策略。使用HDFS的應用程序可以根據要求配置復制因子以及數據的塊大小。現在問題出現如何確定復制,如果所有副本都在集群中的單個機架中,并且整個機架發生故障,該怎么辦。HDFS嘗試維護機架感知復制策略,這實際上需要大量的調整和體驗。一個簡單但非最佳的策略是將塊的每個副本放置在獨特的機架上,以便在整個機架故障的情況下。至少復制塊在另一個機架中是安全的。在大多數生產系統中,使用復制因子三。在這些情況下。HDFS使用略有不同版本的獨特機架策略。它通常將一個副本放置在本地機架中的節點上,另一個副本位于完全不同的遠程機架上的節點上,第三個副本位于遠程機架上的不同節點上。此策略通過在兩個不同的機架上寫入而不是三個機架來切換機架間傳送時間,從而提高寫入速度。這提供了在節點故障的情況下以及在機架故障的情況下的備份。此策略在不影響數據可靠性的情況下提高寫入性能。
Hadoop分布式文件系統(HDFS)的主要目標和目標是即使在出現故障時也能可靠地訪問數據。由于故障比商業硬件集群更常見,而HDFS需要一個策略來處理故障。三種常見類型的故障是:
NameNode故障 DataNode故障 網絡分區集群中的每個DataNode都向NameNode發送周期性消息,此消息稱為心跳。這個心跳向NameNode傳達了特定的DataNode工作正常,并且是活的。現在在DataNode失敗的情況下,從DataNode到NameNode不會有心跳。類似地,在網絡分區的情況下,DataNode的子集可以松開其到NameNode的連接并且停止發送心跳。一旦NameNode停止從特定的DataNode或一組DataNode中獲取心跳,就聲明這些節點已經死了,然后開始檢查損壞的過程,包括檢查死亡DataNode中的所有塊是否仍然有足夠的副本,如果不是,則它啟動進程以創建重復副本,以獲得在應用程序中配置的最小數量的副本。NameNode故障更嚴重,因為NameNode系統是完整HDFS集群的唯一單點故障。如果NameNode系統失敗,整個集群是無用的,需要手動干預,需要設置另一個NameNode。
現在為了允許應用程序訪問存儲在HDFS集群中的數據,它提供了一個Java API供應用程序使用。如果需要使用C語言,則還通過Java API提供C語言包裝器。除了Java和C API,HDFS還提供了一個選項,通過Web端口通過Web瀏覽器訪問HDFS數據,可以在HDFS的設置中配置。第三個輔助選項是使用文件系統shell。HDFS還提供了一個名為FS Shell的命令行界面,讓用戶與HDFS中的數據進行交互。此命令行界面的語法類似于linux shell命令。例如:
#To make a new directoryhadoop fs -mkdir /user1/project1#List the content of the filehadoop fs -ls /user1/project1#Upload a file from local system to HDFShadoop fs -put Desktop/textfile.txt /user1/project1有關FS Shell命令的更多示例和說明,您可以查看文章Apache Hadoop FS命令示例5.配置HDFS
HDFS的配置非常簡單,設置HDFS集群不需要太多時間。HDFS的所有配置文件默認都包含在Hadoop包中,可以直接配置。注意:我們假設Hadoop軟件包已經下載,解壓縮并放置在所需的目錄中。在本文中,我們將僅討論HDFS所需的配置。有關如何設置Hadoop和Hadoop集群的詳細文章。遵循以下教程:
如何在Ubuntu上安裝Apache Hadoop Apache Hadoop集群設置示例(帶虛擬機)5.1配置HDFS
HDFS使用一組默認存在于Hadoop配置目錄中的xml文件進行配置。此配置目錄存在于Hadoop文件夾的根目錄中,并命名為conf。首先,我們將修改conf / hadoop-sites.xml文件,我們需要在這個文件中設置三個屬性,即fs.default.name,dfs.data.dir,dfs.name.dir要修改文件,請在編輯器中打開該文件,并添加以下代碼行:
<configuration> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/usr/local/hadoop/hdfs/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/usr/local/hadoop/hdfs/datanode</value> </property></configuration>我們在這里設置的第一個配置是dfs.replication,它設置分布式文件系統要使用的復制因子。在這種情況下,我們將其設置為兩個。下一個配置是定義NameNode路徑,即dfs.namenode.name.dir,這里的值需要是存儲namenode信息的目錄。我們需要設置的第三個和最后一個配置是定義DataNode的路徑,即dfs.datanode.data.dir,它將定義到存儲datanode信息的目錄的路徑。
注意:確保將創建namenode和datanode目錄并且將存儲數據的目錄由將運行Hadoop的用戶擁有。使用戶在目錄中具有讀寫權限。
5.2格式化NameNode
現在下一步是格式化我們剛剛配置的NameNode。以下命令用于格式化NameNode:
hdfs namenode -format此命令應該在控制臺輸出上沒有任何錯誤的情況下執行。 如果它沒有任何錯誤執行,我們很好在我們的Ubuntu系統上啟動Apache Hadoop實例。5.3啟動HDFS
現在我們準備好啟動Hadoop文件系統。 要啟動HDFS,請使用以下命令運行start-dfs.sh文件:
/usr/local/hadoop/sbin/start-dfs.sh一旦這個腳本執行沒有任何錯誤,HDFS將啟動并運行。
6.使用Shell與HDFS交互
現在我們將看到一些需要使用shell與HDFS交互的命令。在本節中,我們將只看到基本的介紹命令,并將只使用命令行界面。 與集群通信的命令存在于腳本bin / hadoop中。此腳本使用Java虛擬機(JVM)加載Hadoop軟件包,然后執行user命令。
6.1創建目錄
用法:
hadoop fs -mkdir 示例:hadoop fs -mkdir /user/root/dir1第二行中的命令用于列出特定路徑的內容。 我們將在下一小節中看到此命令。我們可以在截圖中看到dir1被創建
6.2列出目錄的內容
用法:
hadoop fs -ls 示例:hadoop fs -ls /user/root/該命令類似于unix shell的ls命令。
6.3在HDFS中上傳文件
命令用于將一個或多個文件從本地系統復制到Hadoop文件系統。用法:
hadoop fs -put ... 示例:hadoop fs -put Desktop/testfile.txt /user/root/dir1/6.4從HDFS下載文件
將文件從HDFS下載到本地文件系統。用法:
hadoop fs -get 示例:hadoop fs -get /user/root/dir1/testfile.txt Downloads/與put命令一樣,get命令從Hadoop文件系統獲取或下載文件到Downloads文件夾中的本地文件系統。
注意:有關文件系統命令和其他重要命令的詳細信息,請參閱Apache Hadoop FS命令示例文章,或者您可以在Apache Hadoop網站上的文檔中檢查shell命令的完整文檔:文件系統命令和HDFS命令指南
7.使用MapReduce與HDFS交互
正如我們討論的,HDFS是Hadoop和MapReduce的基本組件。Hadoop MapReduce作業從HDFS獲取數據,并將最終結果數據存儲在HDFS中。Hadoop還提供了一個Java API,通過它我們可以在Java應用程序中執行HDFS功能。 在本節中,我們將看到如何在java代碼中使用Java API。
package com.javacodegeeks.examples.HDFSJavaApi;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.FSDataInputStream;import org.apache.hadoop.fs.FSDataOutputStream;import org.apache.hadoop.fs.Path;/** * Example application to show how the HDFS file system Java API works * * @Author Raman Jhajj */public class App { public static final String filename ="dummy.txt"; public static final String message = "This is the dummy text for test the write to file Operation of HDFS"; public static void main( String[] args ) throws IOException { //Get the file system instance Configuration configuration = new Configuration(); FileSystem fs = FileSystem.get(configuration); Path filenamePath = new Path(filename); try { if(fs.exists(filenamePath)) { //Delete Example fs.delete(filenamePath, true); } //Write example FSDataOutputStream out = fs.create(filenamePath); out.writeUTF(message); out.close(); //Read example FSDataInputStream in = fs.open(filenamePath); String messageIn = in.readUTF(); System.out.println(messageIn); in.close(); //Rename the file if(fs.exists(filenamePath)) { Path renameFilenamePath = new Path("renamed_" + filename); fs.rename(filenamePath, renameFilenamePath); } } catch(IOException ex) { System.out.println("Error: " + ex.getMessage()); } }}上面的代碼創建一個名為dummy.txt的文件,將虛擬消息寫入此文件。 行號24-25用Configuration對象創建一個抽象的FileSystem對象。在這種情況下配置對象使用默認參數,因為我們沒有定義任何參數。 行號30-33檢查文件是否已經存在于HDFS中,如果它存在,它嘗試刪除該文件。本示例向我們介紹了文件系統中可用的兩種方法exists()和delete() 行號35-38將文件寫入提供的路徑上的HDFS,然后在文件中寫入虛擬消息。這將介紹另一種如何在HDFS中寫入文件的方法。 行號40-44讀取我們剛才在前面代碼行中寫的文件,并將該文件的內容寫在控制臺上。這個代碼示例不提供很多有用的工作,它只是設計來獲得基本的了解如何讀取和寫入文件在HDFS使用Java API的工作原理。 行號47-50檢查文件是否存在于HDFS中,如果存在,將文件從dummy.txt重命名為renamed_dummy.txt要進一步閱讀,您可以檢查HDFS API JavaDoc on HDFS API JavaDoc
8.結論
這使我們得出這篇文章的結論。我們從設計開始討論了Hadoop分布式文件系統(HDFS)的基礎知識,然后了解了HDFS架構。然后我們看到了如何配置和啟動HDFS節點,最后我們討論了如何使用shell命令行和HDFS Java API與運行的HDFS集群交互。我希望這給出了關于HDFS及其構建塊的基本解釋。
9.下載代碼
在此示例中,下載包含用于了解HDFS Java API的代碼的Eclipse項目。
下載您可以在這里下載此示例的完整源代碼:HDFSJavaApi
新聞熱點
疑難解答