hadoop權威指南學習二

Hadoop分佈式文件系統

HDFS的設計

HDFS以流式數據訪問模式來存儲超大文件。

流式數據訪問

HDFS的構建思路是這樣的:一次寫入,多次讀取是最高效的。數據集通常是由數據源生成或複製而來,接着長時間在此數據集上進行分析,每次分析都設計數據集的大部分或全部數據。


不適合使用HDFS的場景

1.低時間延遲的訪問

HDFS是爲高數據吞吐量應用優化的,這可能以高延遲作爲代價,對於低延遲訪問需求可以使用HBase

2.大量的小文件

由於namenode將文件系統的元數據存儲在內存中,因此該文件系統所能存儲的文件綜述受限於內存大小

3.多用戶寫入,任意修改


HDFS中可能只有一個writer,而且每次寫入數據都是追加在文件末尾,不支持多用戶寫入,也不支持在文件任意文職的修改。


HDFS的概念

數據塊

默認64MB,HDFS上的文件被劃分爲塊大小的多個分塊,與普通文件系統不同的是,小於一個塊大小的文件不會佔據整個塊空間。

namenode和datanode

HDFS集羣有兩類節點,並以管理者-工作者模式運行,即一個管理者(namenode)和多個工作者(datanode),namenode管理文件系統的命名空間,它維護這個文件系統樹以及整個樹內的文件以及目錄,這些信息以兩種文件形式永久保存在本地磁盤上,命名空間鏡像文件和編輯日誌文件。

Client代表用戶通過namenode和datanode來訪問文件系統,客戶端通過接口提供訪問文件系統的功能。

datanode是文件系統的工作節點,根據需要存儲或檢索數據塊(受client或namenode調度)。

沒有namenode文件系統將無法使用,因此需要對其實現容錯,hadoop提供兩種機制:

1.備份組成文件系統元數據持久狀態的文件。

2.輔助namenode


命令行接口

可以使用命令執行常用的文件系統操作

hadoop fs -help可以查看幫助


Hadoop文件系統

hadoop有一個抽象的文件系統概念,HDFS只是其中一種實現。

Java的抽象類org.apache.hadoop.fs.FileSystem定義了Hadoop的一個文件系統接口,並且該類有幾個具體實現。

見下圖:


Hadoop對文件系統提供了很多接口,一般使用URI選擇不同的文件系統進行交互,比如要想列出本地文件系統根目錄下的文件,可使用如下命令:

hadoop fs -ls file:///

接口

Hadoop是用Java寫的,通過Java API可以調用所有Hadoop文件系統的交互操作。

Java 接口

通過FileSystem API讀取數據

hadoop中使用Path代表一個文件,FileSytem是一個通用的文件系統API,所以第一步是檢索需要使用的文件系統實例,如HDFS。獲取FileSystem實例有兩個方法:

public static FileSystem get(Configuraion conf) throws IOException;

public static FileSystem get(URI uri,Configuraion conf) throws IOException;

Configuration對象封裝了客戶端或服務器的配置。

通過設置配置文件來加載類路徑,第一個方法返回的是默認文件系統(在core-site.xml中設置的),如果沒有設置則返回本地文件系統。

第二個方法返回通過URI和權限指定的文件系統。如果給定URI中沒有猴子腚方案則返回默認文件系統。

有了FileSystem實例後,就可以調用open方法獲取文件輸入流:

public FSDataInputStream open(Path path)throws IOEXception;

public abstract FSDataInputStream open(Path path,int bufferSize)throws IOException;

第一個方法使用默認緩衝區大小4KB


數據流

文件讀取數據流


客戶端通過調用FileSystem對象的open方法來打開需要讀取的文件,對於HDFS而言,這是一個分佈式文件系統對象的一個實例。DistributedFileSystem

通過RPC與namenode通信,以確認文件起始塊的位置。對於每一個塊,namenode返回擁有該塊副本的datanode的地址,datanode根據距離客戶端的

位置遠近進行排序。DistributedFileSystem類給客戶端返回一個FSDataInputStream對象,客戶端使用它讀取數據。FSDataInputStream封裝DFSInputStream

對象,管理datanode和namenode的I/O.接着客戶端通過輸入流的read方法,從距離客戶端最近的datanode處獲取數據,到達塊的末尾後,DFSInputStream

會斷開datanode的連接,並尋找下一個最佳datanode。一旦讀取完成則調用close方法。


寫入文件數據流


客戶端通過調用DistributedFileSystem對象的create()方法創建一個文件,DistributedFileSystem通過RPC通知namenode在namespace中

創建一個新文件,此時該文件還沒有相應的數據塊。namenode會做一系列的檢查確保這個文件還不存在,以及客戶端有權限創建。如果通過,

namenode會創建一個新文件,否則拋出IOException.DistributedFileSystem返回一個FSDataOutputStream對象讓客戶端開始寫入數據。與讀文件類似,

FSDataOutputStream封裝了DFSOuputStream對象,處理與datanode和namenode通信。

寫入數據時,DFSOutputStream將數據分成若干packet,寫入內部隊列。DataStreamer處理內部隊列,它負責請求namenode通過列舉合適的datanode分配新塊

以存儲數據副本。列出的datanode構成一個管線,這裏假設副本爲3個,所以管線包括三個datanode。DataStreamer將packets送至管線中第一個datanode,

該datanode存儲packet並將其送至第二個,以此類推。

DFSOutputStream也維護者一個確認隊列,以等待datanode的確認迴應,當收到所有datanode的確認後,packet纔會被從隊列中移除。

客戶端完成數據寫入後調用close()方法。





發佈了55 篇原創文章 · 獲贊 9 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章