HDFS文件操作
HDFS是一種文件系統(tǒng),專為MapReduce這類框架下的大規(guī)模分布式數(shù)據(jù)處理而設(shè)計。你可以把一個大數(shù)據(jù)集(比如說100TB)在HDFS中存儲為單個文件,而大多數(shù)其他的文件系統(tǒng)無力實現(xiàn)這一點。HDFS使你不必考慮這些細節(jié),讓你感覺就像在處理單個文件一樣。
因為HDFS并不是一個天生的Unix文件系統(tǒng),不支持像ls和cp這種標(biāo)準(zhǔn)的Unix文件命令,也不支持如fopen()和fread()這樣的標(biāo)準(zhǔn)文件讀寫操作。另一方面,Hadoop確也提供了一套與linux文件命令類似的命令行工具。
注意 一個典型的Hadoop工作流會在別的地方生成數(shù)據(jù)庫文件(如日志文件)再將其復(fù)制到HDFS中。接著由MapReduce程序處理這個數(shù)據(jù),但它們通常不會直接讀任何一個HDFS文件。相反,它們依靠MapReduce框架來讀取HDFS文件,并將之解析為獨立的記錄(鍵值對),這些記錄才是MapReduce程序所處理的數(shù)據(jù)單元。除非需要定制數(shù)據(jù)的導(dǎo)入與導(dǎo)出,否則你幾乎不必編程來讀寫HDFS文件。
基本文件命令
Hadoop的文件命令采取的形式為
hadoop fs -cmd <args>其中cmd是具體的文件命令,而是一組數(shù)目可變的命令參數(shù)cmd命令通常與UNIX對應(yīng)的命令名相同。例如,文件列表命令為
hadoop fs -ls讓我們來看看在Hadoop中最常用文件管理任務(wù),其中包括
添加文件和目錄
獲取文件
刪除文件
指定文件盒目錄確切位置的URI
Hadoop的文件命令既可以與HDFS文件系統(tǒng)交互,也可以和本地文件系統(tǒng)交互。URI精確地定位到一個特定文件或目錄的位置。完整的URI格式為scheme://authority/path。Scheme類似于一個協(xié)議。它可以是hdfs或file,來分別指定HDFS文件系統(tǒng)或本地文件系統(tǒng)。對于HDFS,authority是NameNode的主機名,而path是文件或目錄的路徑。例如,對于在本地機器的9000端口號上,以標(biāo)準(zhǔn)偽分布式模型運行的HDFS,訪問用戶目錄user/chuck中文件example.txt的URI大致為hdfs://localhost:9000/user/chuck/example.txt.
你可以使用hadoop的cat命令來顯示該文件的內(nèi)容:
hadoop fs -cat hdfs://localhost:9000/usr/chuck/example.txt
正如我們馬上就會看到的,大多數(shù)設(shè)置不需要指定URI中的scheme://authority部分。對于本地文件系統(tǒng),你可能會更喜歡用標(biāo)準(zhǔn)的Unix命令,而不是hadoop文件命令。當(dāng)在本地文件系統(tǒng)和HDFS之間復(fù)制文件時,hadoop中的命令(如put和get)會分別把本地文件系統(tǒng)作為源和目的,而不需要制定scheme為file。對于其他命令,如果未設(shè)置URI中scheme://authority,就會采用Hadoop的默認配置。例如,假如conf/core-site.xml文件已經(jīng)更改為偽分布式配置,則文件中fs.default.name屬性應(yīng)為
在此配置下,URIhdfs://localhost:9000/user/chuck/example.txt縮短為/user/chuck/example.txt。顯示文件內(nèi)容的hadoo cat命令可以寫為hadoop fs -cat example.txt
添加文件和目錄
在運行hadoop程序處理存儲在HDFS上的數(shù)據(jù)之前,你需要首先把數(shù)據(jù)放在HDFS上。讓我們假設(shè)你已經(jīng)完成了格式化,并啟動了一個HDFS文件系統(tǒng)(出于學(xué)習(xí)目的,我們建議使用偽分布式模式的配置。)讓我們創(chuàng)建一個目錄并放入一個文件。
HDFS有一個默認的工作目錄/usr/USER,其中USER是你的登錄用戶名。你需要用你的用戶名來替換。
hadoop的mkdir命令會自動創(chuàng)建父目錄(如果此前不存在的話),類似于UNIX中使用-p選項的mkdir命令,因此上述命令還會創(chuàng)建/user目錄,讓我們用ls命令對目錄進行檢查:
hadoop fs -ls/該命令返回根目錄下目錄/user的信息
Found 1 items drwxr-xr-x -chuck supergroup 0 2009-01-14 10:23 /user如果你想看到所有的子目錄,則可以使用Hadoop的lsr命令,它類似于Unix中打開-r選項的ls:hadoop fs -lsr /
你會看到所有文件和子目錄:
既然有了一個工作目錄,我們可以放一個文件進去。在本地文件系統(tǒng)中創(chuàng)建一個名為example.txt的文本文件,用hadoop的命令put將它從本地文件系統(tǒng)復(fù)制到HDFS中去。
hadoop fs -put example.txt.注意上面的這個命令最后一個參數(shù)是句點(.)。這意味著我們把文件放入了默認的工作目錄。該命令等價于:
hadoop fs -put example.txt /user/chuck我們重新執(zhí)行遞歸列出文件的命令,可以看到新的文件被添加到HDFS中。
$hadoop fs -lsr / drwxr-xr-x -chuck supergroup 0 2009-01-14 10:23 /user drwxr-xr-x -chuck supergroup 0 2009-01-14 11:02 /user/chuck -rw-r--r-- 1 chuck supergroup 264 2009-01-14 11:02 /user/chuck/example.txt實際上,我們并不需要遞歸地檢查所有文件,而僅限于在我們自己工作目錄中的文件。我們可以通過最簡單的形式來使用Hadoop的ls命令:
$ hadoop fs -ls Found 1 items -rw-r--r-- 1 chuck supergroup 264 2009-01-14 11:02 /user/chuck/exampe.txt輸出結(jié)果顯示出屬性信息,比如權(quán)限、所有者、組、文件大小,以及最后修改日期,所有這些都類似于Unix的概念。顯示“1”的列給出文件的復(fù)制因子。偽分布式配置下它永遠為1。對于生產(chǎn)環(huán)境中的集群,復(fù)制因子通常為3,但也可以是任何正整數(shù)。因為復(fù)制因子不適用于目錄,故屆時該列會顯示一個破折號(-)。
當(dāng)你把數(shù)據(jù)放到HDFS上之后,你可以運行Hadoop程序來處理它。處理過程將輸出一組新的HDFS文件,然后你可以讀取或檢索這些結(jié)果。
檢索文件
hadoop的get命令與put截然相反。它從HDFS中復(fù)制文件到本地文件系統(tǒng)。比方說,我們在本地不再擁有文件example.txt,而想從HDFS中將它取回,我們就可以運行命令:
hadoop fs -get example.txt.
將它復(fù)制到我們在本地的當(dāng)前工作目錄中。
另一種訪問數(shù)據(jù)的方式是顯示。由hadoop的cat命令來支持:
hadoop fs -cat example.txt
我們可以在Hadoop的文件命令中使用Unix的管道,將其結(jié)果發(fā)送給其他的Unix命令做進一步處理。例如,如果該文件非常大(正如典型的Hadoop文件那樣),并且你希望快速地檢查其內(nèi)容,就可以把hadoop中cat命令的輸出用管道傳遞給Unix命令head:
hadoop fs -cat example.txt|head
hadoop內(nèi)在支持tail命令來查看最后一千字節(jié):
hadoop fs -tail example.txt
文件在HDFS上的任務(wù)完成之后,可以考慮刪除它們以釋放空間。
刪除文件
hadoop刪除文件的命令為rm,現(xiàn)在你也許不會感到太驚訝了:
hadoop fs -rm example.txt
rm命令還可以用于刪除空目錄。
編程讀寫HDFS
為了體驗HDFS的Java API,我們將開發(fā)一個PutMerge程序,用于合并文件后放入HDFS。命令行工具并不支持這個操作,我們將使用API來實現(xiàn)。
需要分析來自許多Web服務(wù)器的Apache日志文件時,就有了建立這個歷程的動機。雖然我們可以把每個日志文件都復(fù)制到HDFS中,但通常而言,Hadoop處理單個大文件會比處理許多個小文件更有效率(這里“小”是相對的,因為它仍會達到幾十或幾百GB)。此外,從分析目的來看,我們把日志數(shù)據(jù)視為一個大文件。日志數(shù)據(jù)被分散在多個文件是由于Web服務(wù)器采用分布式架構(gòu)所帶來的副作用。一種解決辦法是先將所有的文件合并,然后再復(fù)制到HDFS。可是,文件合并需要占用本地計算機的大量磁盤空間。如果我們能夠在向HDFS復(fù)制的過程中合并它們,事情就會簡單很多。
因此,我們需要一個PutMerge類型的操作。hadoo命令行中有一個getmerge命令,用于一組HDFS文件在復(fù)制到本地以前進行合并。但我們想要的截然相反,故無法再Hadoop的文件管理工具中獲得。我們用HDFS API來自己編程實現(xiàn)它。
在Hadoop中用作文件操作的主流位于org.apache.hadoop.fs軟件包中。Hadoop的基本文件操作包括常見的open、read、write和close。實際上,hadoop的文件API是通用的,可以用于HDFS以外的其他文件系統(tǒng)。對于我們的PutMerge程序,它讀取本地文件系統(tǒng)和寫入HDFS都會使用Hadoop的文件api。
不多說,直接上代碼:
import java.io.IOException;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.eclipse.jdt.internal.compiler.ConfigurableOption;public class PutMerge {public static void main(String[] args) throws IOException{Configuration conf = new Configuration();FileSystem hdfs = FileSystem.get(conf);FileSystem local = FileSystem.getLocal(conf);Path inputDir = new Path(args[0]);//1.設(shè)定輸入目錄與輸出文件Path hdfsFile = new Path(args[1]);try{FileStatus[] inputFiles = local.listStatus(inputDir);//2.得到本地文件列表FSDataOutputStream out = hdfs.create(hdfsFile);//3.生成HDFS文件流for (int i = 0; i < inputFiles.length; i++){System.out.println(inputFiles[i].getPath().getName());FSDataInputStream in = local.open(inputFiles[i].getPath());//4.打開本地輸入流byte buffer[] = new byte[256];int bytesRead = 0;while ((bytesRead = in.read(buffer)) > 0){out.write(buffer, 0, bytesRead);}in.close();}out.close();}catch (Exception e){e.printStackTrace();}} }我們已經(jīng)討論了如何處理HDFS中的文件,你現(xiàn)在知道一些方法來讀寫HDFS中的數(shù)據(jù),但是僅僅有數(shù)據(jù)還不夠,還要對它進行處理分析以及其他的操作。在后續(xù)學(xué)習(xí)過程中,我們將介紹Hadoop的另一個主要組件——MapReduce框架,看看如何基于它來編程。
轉(zhuǎn)載于:https://www.cnblogs.com/ainima/p/6331862.html
總結(jié)
- 上一篇: 【News】SpagoBI中国官方微信对
- 下一篇: angularJS--多个控制器之间的数