Apache Hadoop分散式檔案系統說明
==========本文采用谷歌翻譯,請參照中英文學習===========
在本例中,我們將詳細討論Apache Hadoop分散式檔案系統(HDFS),其元件和體系結構。 HDFS是Apache Hadoop生態系統的核心元件之一。
1.介紹
Apache Hadoop提供了一個分散式檔案系統和一個框架,用於使用MapReduce範例轉換大型資料集。
HDFS旨在在商用硬體上執行時可靠地儲存非常大的資料集。它是容錯的,並且提供對儲存的資料的高吞吐量訪問。雖然HDFS的介面在Unix檔案系統之後被圖案化,但它放鬆了一些POSIX要求以提高其目標解決的應用程式的效能,並提供對儲存在檔案系統中的資料的流式訪問。
2. HDFS設計
以下是HDFS的屬性,使其與其他檔案系統不同,並使HDFS能夠可靠地處理大量的資料。
2.1系統故障
HDFS被設計為在一組商品硬體上工作。系統故障被認為是規範。由於存在大量HDFS依賴的元件,考慮到這些元件具有不平凡的故障概率也將導致一個元件或其他元件始終失敗。因此HDFS旨在檢測故障並執行自動恢復以提供所需的效能是HDFS的核心屬性之一。
2.2可以處理大量的資料
HDFS設計用於依賴於大量資料的應用程式。此資料也可以是千兆位元組,太位元組或PB。因此,HDFS被調整為支援這種大型資料集,並擴充套件到大型系統叢集以儲存此資料,而不會影響資料吞吐量。
2.3一致性模型
HDFS被調整以滿足需要寫入資料一次或最多隻讀取幾次並且讀取資料更多的應用程式。由於這些應用程式被假設為依賴於“一次讀取多次讀取”模型,它簡化了資料一致性問題,並允許HDFS提供高吞吐量資料訪問。
2.4可移植性
HDFS旨在跨異構硬體和軟體平臺移植。這使得HDFS的適應變得非常容易,並且它成為依賴於分散式大資料集的應用的選擇的平臺。
3.HDFS節點
HDFS NameNode和DataNode有兩個主要元件。
3.1 NameNode
HDFS遵循主從架構,其中NameNode是充當主節點的節點。一個HDFS叢集只包含一個NameNode。
NameNode的主要功能是管理檔案系統名稱空間,並控制對儲存在HDFS叢集中的檔案的客戶端認證。
3.2 DataNode
DataNode是名稱表示在叢集中儲存實際資料的節點。叢集中有多個DataNode,通常DataNodes的數量與叢集中硬體節點的節點相同。
DataNode服務於來自客戶端的讀取和寫入請求,並且還處理與塊的建立,塊的刪除和複製相關的資料塊的操作。
4.HDFS架構
在本節中,我們將瞭解Hadoop分散式檔案系統(HDFS)的基本架構。
4.1 NameNode和DataNode的工作
HDFS是塊結構檔案系統,這意味著所有單獨的檔案被分成具有固定塊大小的小資料塊。然後,這些塊將儲存在DataNode中的機器叢集中。
NameNode處理諸如開啟,關閉和重新命名檔案或目錄的功能。如上所述的NameNode還處理叢集中的資料的對映,這意味著NameNode跟蹤哪個資料塊儲存在哪個DataNode上以及如何處理該資料的複製。
4.2 HDFS名稱空間
HDFS名稱空間定義瞭如何在叢集中儲存和訪問資料。
HDFS支援檔案和目錄的傳統分層組織。它還支援幾乎所有需要的函式來處理名稱空間操作,如建立或刪除檔案或目錄,將檔案/目錄從一個地方移動到另一個地方等。
正如我們在第3節討論的,NameNode是維護HDFS檔案系統名稱空間的元件。在NameNode中維護對資料的任何操作,如建立或刪除檔案,移動檔案或目錄。
4.3資料複製
由於HDFS旨在將大量資料可靠,安全地儲存在一組商品硬體上。由於這個硬體容易發生故障,HDFS需要以一種方式處理資料,以便在一個或多個系統發生硬體故障時可以輕鬆地檢索資料。
HDFS使用資料複製作為提供容錯功能的策略。使用HDFS的應用程式可以根據要求配置複製因子以及資料的塊大小。
現在問題出現如何確定複製,如果所有副本都在叢集中的單個機架中,並且整個機架發生故障,該怎麼辦。
HDFS嘗試維護機架感知複製策略,這實際上需要大量的調整和體驗。一個簡單但非最佳的策略是將塊的每個副本放置在獨特的機架上,以便在整個機架故障的情況下。至少複製塊在另一個機架中是安全的。
在大多數生產系統中,使用複製因子三。在這些情況下。
HDFS使用略有不同版本的獨特機架策略。它通常將一個副本放置在本地機架中的節點上,另一個副本位於完全不同的遠端機架上的節點上,第三個副本位於遠端機架上的不同節點上。此策略通過在兩個不同的機架上寫入而不是三個機架來切換機架間傳送時間,從而提高寫入速度。這提供了在節點故障的情況下以及在機架故障的情況下的備份。此策略在不影響資料可靠性的情況下提高寫入效能。
4.4故障
Hadoop分散式檔案系統(HDFS)的主要目標和目標是即使在出現故障時也能可靠地訪問資料。由於故障比商業硬體叢集更常見,而HDFS需要一個策略來處理故障。三種常見型別的故障是:
- NameNode故障
- DataNode故障
- 網路分割槽
叢集中的每個DataNode都向NameNode傳送週期性訊息,此訊息稱為心跳。這個心跳向NameNode傳達了特定的DataNode工作正常,並且是活的。現在在DataNode失敗的情況下,從DataNode到NameNode不會有心跳。類似地,在網路分割槽的情況下,DataNode的子集可以鬆開其到NameNode的連線並且停止傳送心跳。一旦NameNode停止從特定的DataNode或一組DataNode中獲取心跳,就宣告這些節點已經死了,然後開始檢查損壞的過程,包括檢查死亡DataNode中的所有塊是否仍然有足夠的副本,如果不是,則它啟動程序以建立重複副本,以獲得在應用程式中配置的最小數量的副本。
NameNode故障更嚴重,因為NameNode系統是完整HDFS叢集的唯一單點故障。如果NameNode系統失敗,整個叢集是無用的,需要手動干預,需要設定另一個NameNode。
4.5資料可訪問性
現在為了允許應用程式訪問儲存在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 directory
hadoop fs -mkdir /user1/project1
#List the content of the file
hadoop fs -ls /user1/project1
#Upload a file from local system to HDFS
hadoop fs -put Desktop/textfile.txt /user1/project1
有關FS Shell命令的更多示例和說明,您可以檢視文章Apache Hadoop FS命令示例
5.配置HDFS
HDFS的配置非常簡單,設定HDFS叢集不需要太多時間。
HDFS的所有配置檔案預設都包含在Hadoop包中,可以直接配置。
注意:我們假設Hadoop軟體包已經下載,解壓縮並放置在所需的目錄中。在本文中,我們將僅討論HDFS所需的配置。有關如何設定Hadoop和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命令的完整文件:檔案系統命令
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