Hadoop Distributed File System,簡稱HDFS,是一個分佈式文件系統。
1. 特性:
1.1. 大數據集
運行在HDFS上的應用具有很大的數據集。可以是從GB到TB級的。
1.2. 高容錯性
在hadoop集羣環境下,每份數據都被保存在多個結點裏邊。一個結點的不可用不會導致該結點存儲的數據不可用。
1.3. 高吞吐量
跑在Hdoop上的應用,更多的是做批處理,HDFS的設計中更多的考慮到了數據批處理,而不是用戶交互處理。比之數據訪問的低延遲問題,更關鍵的在於數據訪問的高吞吐量。
1.4. 簡單一致的模型
採用了"一次寫入,多次讀取"的模型。這一假設簡化了數據一致性問題,並且使高吞吐量的數據訪問成爲可能。Map/Reduce應用或者網絡爬蟲應用都非常適合這個模型。目前還有計劃在將來擴充這個模型,使之支持文件的附加寫操作。
1.5. 可移植性
HDFS在設計的時候就考慮到平臺的可移植性。這種特性方便了HDFS作爲大規模數據應用平臺的推廣。 (可以這樣理解:基於java,並且在HDFS是在本地FileSystem之上抽象出來的文件系統)
1.6. 移動計算比移動數據更高效
一個應用請求的計算,離它操作的數據越近就越高效,在數據達到海量級別的時候更是如此。因爲這樣就能降低網絡阻塞的影響,提高系統數據的吞吐量。將計算移動到數據附近,比之將數據移動到應用所在顯然更好。HDFS爲應用提供了將它們自己移動到數據附近的接口。
一個簡單的例子:程序X在計算機A上,數據在計算機A,B和C上。普通的做法是在A上運行程序X,讀取A,B,C上的數據,然後進行計算(或者是邊讀取邊計算)。hadoop的做法是:將程序X同時也發送到B和C上,A,B,C同時讀取本地計算機上的數據進行計算。得出結果之後再進行彙總(當然這裏只是通俗的舉了個例子,實際上hadoop處理數據更爲複雜)。這樣就避免了在網絡上傳輸大量數據導致的等待和B,C計算能力的浪費。
2. 概念:
nameNode 和 dataNode
HDFS採用了master/slave架構。HDFS由一個nameNode和若干個dataNode組成。
2.1 nameNode
nameNode類似於一個倉庫管理員,負責記錄數據存儲在哪些倉庫(dataNode)的哪些地方,同時也負責和客戶端(Client)對文件的訪問。nameNode作爲一箇中心服務器。因此當nameNode出現故障時是比較致命的。爲了防止出現惡劣的後果,通常集羣環境下還有一個Secondary NameNode 作爲備份。
2.2 dataNode
dataNode負責文件的存儲(可以理解爲倉庫)。
一個文件被分爲多個文件塊存儲在一組dataNode裏邊。Namenode執行文件系統的名字空間操作,比如打開、關閉、重命名文件或目錄。它也負責確定數據塊到具體Datanode節點的映射。Datanode負責處理文件系統客戶端的讀寫請求。在Namenode的統一調度下進行數據塊的創建、刪除和複製。
3. 文件流
3.1 讀文件
客戶端(client)用FileSystem的open()函數打開文件,DistributedFileSystem用RPC調用元數據節點,得到文件的數據塊信息。對於每一個數據塊,元數據節點返回保存數據塊的數據節點的地址。DistributedFileSystem返回FSDataInputStream給客戶端,用來讀取數據。客戶端調用stream的read()函數開始讀取數據。DFSInputStream連接保存此文件第一個數據塊的最近的數據節點。Data從數據節點讀到客戶端(client),當此數據塊讀取完畢時,DFSInputStream關閉和此數據節點的連接,然後連接此文件下一個數據塊的最近的數據節點。當客戶端讀取完畢數據的時候,調用FSDataInputStream的close函數。
整個過程就是如圖所示
3.2 寫文件
客戶端調用create()來創建文件,DistributedFileSystem用RPC調用元數據節點,在文件系統的命名空間中創建一個新的文件。元數據節點首先確定文件原來不存在,並且客戶端有創建文件的權限,然後創建新文件。DistributedFileSystem返回DFSOutputStream,客戶端用於寫數據。客戶端開始寫入數據,DFSOutputStream將數據分成塊,寫入data queue。Data queue由Data Streamer讀取,並通知元數據節點分配數據節點,用來存儲數據塊(每塊默認複製3塊)。分配的數據節點放在一個pipeline裏。Data Streamer將數據塊寫入pipeline中的第一個數據節點。第一個數據節點將數據塊發送給第二個數據節點。第二個數據節點將數據發送給第三個數據節點。DFSOutputStream爲發出去的數據塊保存了ack queue,等待pipeline中的數據節點告知數據已經寫入成功。如果數據節點在寫入的過程中失敗:關閉pipeline,將ack queue中的數據塊放入data queue的開始。
整個過程如圖所示:
4. 使用命令行操作HDFS
1.添加目錄 hadoop fs -mkdir /abc
就在HDFS下創建了一個abc的目錄
2.列出HDFS根目錄下的文件 hadoop fs -ls /
列出根目錄下的所有文件 hadoop fs -ls
3.複製文件 hadoop fs -put /tianlong/test /abc
4.查看文件 hadoop fs -cat /abc/test
5.從HDFS上取文件 hadoop fs -get /abc/test ~/test.txt 把HDFS裏的test文件 取回 當前用戶目錄的test.txt
5. 編程操作HDFS
下邊簡單介紹幾個常用的API,具體的例子網上有很多,就不重複貼了。
FileSystem Hadoop文件系統通過Hadoop Path 對象來代表文件,是一個通用的文件系統API。
Hadoop中關於文件操作類基本上全部是在"org.apache.hadoop.fs"包中,這些API能夠支持的操作包含:打開文件,讀寫文件,刪除文件等。
Hadoop類庫中最終面向用戶提供的接口類是FileSystem,該類是個抽象類,只能通過來類的get方法得到具體類。get方法存在幾個重載版本,常用的是這個:
static FileSystem get(Configuration conf) throws IOException;
static FileSystem get(URI uri, Configuration conf) throws IOException;
或者從Path對象中獲得FileSystem實例
Path dst = new Path("hdfs://192.168.0.111:9000/home");
// 得到dst的FileSystem.
FileSystem hdfs = dst.getFileSystem(conf);
該類封裝了幾乎所有的文件操作,例如mkdir,delete等。綜上基本上可以得出操作文件的程序庫框架:
operator()
{
得到Configuration對象
得到FileSystem對象
進行文件操作
}