Hadoop實戰讀書筆記(5)

HDFS文件操做java

你能夠把一個大數據集(100TB)在HDFS中存儲爲單個文件,而大多數其餘的文件系統無力實現這一點。雖然該文件存在多個副本分佈在多臺機器上來支持並行處理,你也沒必要考慮這些細節。apache

 

HDFS Hadoop Distribution File System)文件系統究竟是一個怎樣的文件系統?編程

並非一個Unix文件系統,不支持像lscp這種標準的Unix文件命令,也不支持如fopen()fread()這樣的標準文件讀寫操做。可是Hadoop提供了一套與Linux文件命令相似的命令行工具。數組

 

一個典型的Hadoop工做流是指?服務器

1、在別的地方生成數據文件(如日誌文件)再將其複製到HDFS中。架構

2、由MapReduce程序處理這個數據,讀取HDFS文件並將之解析爲獨立的記錄(鍵/值對)分佈式

3、除非要定製數據的導入與導出,不然你幾乎沒必要編程來讀寫HDFS文件。工具

 

Hadoop文件命令採起的形式是?oop

hadoop fs -cmd <args>學習

cmd是具體的文件命令,而<args>是一組數目可變的參數。cmd的命名一般與UNIX對應的命令名相同。如,文件列表的命令爲:hadoop fs -ls

 

Hadoop最經常使用的文件管理任務包括?

1、添加文件和目錄

2、獲取文件

3、刪除文件

 

Hadoop文件命令能夠和本地文件系統交互嗎?

Hadoop的文件命令既能夠與HDFS文件系統交互,也能夠和本地文件系統交互。

 

URI定位是指?完整的URL格式是?

URL精確地定位一個特定文件或目錄的位置。

完整的URL格式爲scheme://authority/path. Scheme相似於一個協議它能夠是hdfsfile、來分別指定HDFS文件系統或本地文件系統。

 

對於HDFSauthorityNameNode的主機名,而path是文件或者目錄的路徑。

對於在本地機器的9000端口上,以標準僞分佈式模型運行的HDFS,訪問用戶目錄user/chuck中文件example.txtURI是什麼?

hdfs://localhost:9000/user/chuck/example.txt

hadoop fs -cat hdfs://localhost:9000/user/chuck/example.txt

 

可是一般咱們在使用Hadoop文件命令時沒有指定URI中的scheme://authority部分

是怎麼回事?

是的,大多數設置不須要指定URI中的scheme://authority部分

例如,當在本地文件系統和HDFS之間複製文件時

1put命令將本地文件複製到HDFS中,源是本地文件,目的是HDFS文件

2get命令將HDFS中文件複製到本地,源是HDFS文件,目的是本地文件。

若是未設置URI中的scheme://authority部分,就會採用Hadoop的默認配置fs.default.name屬性的配置。

例如:conf/core-site.xml文件配置是:

<property>

       <name>fs.default.name</name>

       <value>hdfs://localhost:9000</value>

</property>

在此配置下,URI hdfs://localhost:9000/user/chuck/example.txt縮短爲/user/chuck/example.txt

注:有些更早的文檔以hadoop dfs -cmd <args>的形式表示文件工具。dfsfs是等價的,但如今都是用fs

 

HDFS默認當前工做目錄是?

HDFS默認當前工做目錄爲/user/$USER,其中$USER是你的登陸用戶名。

例:若是你做爲chuck登陸,則URI hdfs://localhost:9000/user/chuck/example.txt就縮短爲example.txt。顯示文件內容的Hadoop cat命令可寫爲:

hadoop fs -cat example.txt

 

如何在HDFS上添加文件和目錄?

首先必須確保幾點:

1、必須先進行格式化

2、出於學習目的,建議使用僞分佈式

3、默認工做目錄是/user/$USER,但這個目錄不會自動建立,須要手動建立先

手動建立默認工做目錄

hadoop fs -mkdir /user/chuck

Hadoopmkdir命令會自動建立父目錄,相似於UNIX中使用-p選項的mkdir命令,所以上述命令還會建立/user目錄。

hadoop fs -ls / 該命令列出根目錄下的全部文件和目錄

hadoop fs -lsr / 該命令列出根目錄下全部文件和子目錄

hadoop fs -put example.txt . 將本地文件example.txt放入HDFS中。

後面的(.),意味着把文件放入默認的工做目錄,等價於

hadoop fs -put example.txt /user/chuck

hadoop fs -ls 列出工做目錄下的全部文件和目錄

 

使用hadoop fs -ls命令列出內容和複製因子

一般狀況下會列出以下面這樣的view

Found 1 items

-rw-r--r-- 1 chuck supergroup 264 2009-01-14 11:02 /user/chuck/example.txt

顯示屬性信息,其餘的不解釋和UNIX的概念相似。主要說一下"1"列出文件的複製因子。僞分佈式下它永遠爲1,對於生產環境中的集羣,複製因子一般爲3,也能夠是任何正整數,複製因子不適用於目錄,因此該列會顯示一個(-)

 

如何檢索文件?

Hadoopget命令與put命令相反,從HDFS中複製文件到本地文件系統。

好比hadoop fs -get example.txt 將它複製帶本地的當前工做目錄中。

hadoop fs -cat example.txt 也可使用cat命令顯示數據。

也可使用管道命令 hadoop fs -cat example.txt | head

可使用tail命令來查看最後的一千字節:

hadoop fs -tail example.txt

 

如何刪除文件?

刪除文件和空目錄使用rm命令

hadoop fs -rm example.txt

 

如何查閱幫助?

hadoop fs (無參數) 來獲取所用版本Hadoop的一個完整命令列表。

hadoop fs -help ls 顯示每一個命令的用法及簡短描述。

 

HDFSJava API

雖然,命令行工具足以知足大多數與HDFS文件系統交互的需求,可是有些需求只能用Java API去訪問,好比開發一個PutMerge程序,用於合併文件後放入HDFS中,命令行工具並不支持這個操做。

 

合併文件後放入HDFS中,何時會這樣作呢?

考慮這樣一個場景,須要分析來自許多Web服務器的Apache日誌文件時,就有了創建這個例程的動機,雖然咱們能夠把每一個日誌文件都複製到HDFS中,但一般而言,Hadoop處理單個大文件會比處理許多個小文件更有效率。

 

爲何會日誌數據會分散在多個文件?

這是因爲Web服務器採用分佈式架構所形成的。

 

一種解決辦法是?爲何不直接合並?

一種解決辦法是先將全部的文件合併,而後再複製到HDFS。但是,文件合併須要佔用本地計算機的大量磁盤空間。若是咱們可以在向HDFS複製的過程當中合併它們就行了。

 

Hadoop命令行工具getmerge命令。

getmerge命令,用於把一組HDFS文件在複製到本地計算機以前進行合併,但咱們想要的截然相反。咱們是要putmerge命令。

 

Hadoop文件操做API是?

Hadoop中用做文件操做的主類位於org.apache.hadoop.fs軟件包中,Hadoop的基本文件操做包括openreadwritecloseHadoop的文件API也能夠用於HDFS之外的其餘文件系統。

Hadoop文件API的起點是FileSystem類,這是一個與文件系統交互的抽象類,存在不一樣的具體實現子類用於處理HDFS和本地文件系統。你能夠經過調用factory方法FileSystem.get(Configuration conf)來獲得所需的FileSystem實例。Configuration類是用於保留鍵/值配置參數的特殊類。它的默認實例化方法是以HDFS系統的資源配置爲基礎的。

 

如何獲得一個FileSystem對象?

Configuration conf = new Configuration();

FileSystem hdfs = FileSystem.get(conf);

要獲得一個專用於本地文件系統的FileSystem對象,可使用factory方法的FileSystem.getLocal(Configuration conf);

FileSystem local = FileSystem.getLocal(conf);

其餘說明:

Hadoop文件API使用Path對象來編制文件和目錄名,使用FileStatus對象來存儲文件和目錄的元數據。PutMerge程序將合併一個本地目錄中的全部文件。咱們使用FileSystemlistStatus()方法來獲得一個目錄中的文件列表:

Path inputDir = new Path(args[0]);

FileStatus[] inputFiles = local.listStatus(inputDir);

數組inputFiles的長度等於指定目錄中的文件個數。在inputFiles中每個FileStatus對象均有元數據信息,如文件長度、權限、修改時間等。PutMerge程序所關心的是每一個文件的Path,即inputFiles[i].getPath()。咱們能夠經過FSDataInputStream對象訪問這個Path來讀取文件。

FSDataInputStream in = local.open(inputFiles[i].getPath());

byte buffer[] = new byte[256];

int bytesRead = 0;

while ( (bytesRead = in.read(buffer)) > 0) {

       ...

}

in.close();

FSDataInputStreamJava標準類java.io.DataInputStream的一個子類,增長了對隨機訪問的支持。相似地有一個FSDataOutputStream對象用於將數據寫入HDFS文件:

Path hdfsFile = new Path(args[1]);

FSDataOutputStream out = hdfs.create(hdfsFile);

out.write(buffer, 0, bytesRead);

out.close();

相關文章
相關標籤/搜索