《Hadoop大數(shù)據(jù)原理與應(yīng)用》課件4.課件-第3章分布式文件系統(tǒng)HDFS(2020春)_第1頁(yè)
《Hadoop大數(shù)據(jù)原理與應(yīng)用》課件4.課件-第3章分布式文件系統(tǒng)HDFS(2020春)_第2頁(yè)
《Hadoop大數(shù)據(jù)原理與應(yīng)用》課件4.課件-第3章分布式文件系統(tǒng)HDFS(2020春)_第3頁(yè)
《Hadoop大數(shù)據(jù)原理與應(yīng)用》課件4.課件-第3章分布式文件系統(tǒng)HDFS(2020春)_第4頁(yè)
《Hadoop大數(shù)據(jù)原理與應(yīng)用》課件4.課件-第3章分布式文件系統(tǒng)HDFS(2020春)_第5頁(yè)
已閱讀5頁(yè),還剩91頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第3章分布式文件系統(tǒng)HDFS《Hadoop大數(shù)據(jù)原理與應(yīng)用》西安電子科技大學(xué)出版社【知識(shí)與能力要求】第3章分布式文件系統(tǒng)HDFS3.1HDFS簡(jiǎn)介3.2HDFS體系架構(gòu)3.3HDFS文件存儲(chǔ)機(jī)制3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.5實(shí)戰(zhàn)HDFS3.6HDFS高可靠機(jī)制3.1HDFS簡(jiǎn)介HDFS(HadoopDistributedFileSystem)是Hadoop分布式文件系統(tǒng),是Hadoop三大核心之一,是針對(duì)谷歌文件系統(tǒng)GFS(GoogleFileSystem)的開(kāi)源實(shí)現(xiàn)(TheGoogleFileSystem,2003)。HDFS是一個(gè)具有高容錯(cuò)性的文件系統(tǒng),適合部署在廉價(jià)的機(jī)器上,HDFS能提供高吞吐量的數(shù)據(jù)訪問(wèn),非常適合大規(guī)模數(shù)據(jù)集上的應(yīng)用。大數(shù)據(jù)處理框架如MapReduce、Spark等要處理的數(shù)據(jù)源大部分都存儲(chǔ)在HDFS上,Hive、HBase等框架的數(shù)據(jù)通常也存儲(chǔ)在HDFS上。簡(jiǎn)而言之,HDFS為大數(shù)據(jù)的存儲(chǔ)提供了保障。經(jīng)過(guò)多年的發(fā)展,HDFS自身已經(jīng)十分成熟和穩(wěn)定,且用戶群愈加廣泛,HDFS逐漸成為分布式存儲(chǔ)的事實(shí)標(biāo)準(zhǔn)。3.1HDFS簡(jiǎn)介HDFS文件系統(tǒng)的基本特征包括以下幾個(gè)方面。(1)高容錯(cuò)性:把硬件出錯(cuò)看做一種常態(tài),HDFS設(shè)計(jì)了相應(yīng)機(jī)制能夠快速自動(dòng)進(jìn)行錯(cuò)誤檢測(cè)和恢復(fù)。例如,一個(gè)節(jié)點(diǎn)出現(xiàn)故障,它上面的數(shù)據(jù)在其它節(jié)點(diǎn)存在備份,并且會(huì)被自動(dòng)補(bǔ)充。(2)數(shù)據(jù)容量大:HDFS每個(gè)集群可以支持?jǐn)?shù)百個(gè)節(jié)點(diǎn),以支持應(yīng)用程序的大數(shù)據(jù)需求。(3)可擴(kuò)展性:水平擴(kuò)展性強(qiáng),數(shù)據(jù)節(jié)點(diǎn)可以根據(jù)需要進(jìn)行增刪。(4)高吞吐量:數(shù)據(jù)傳輸速率高,支持高并發(fā)大數(shù)據(jù)應(yīng)用程序。(5)就近計(jì)算:客戶請(qǐng)求盡可能在數(shù)據(jù)節(jié)點(diǎn)上直接完成計(jì)算任務(wù),這樣在大數(shù)據(jù)的業(yè)務(wù)中可以降低網(wǎng)絡(luò)負(fù)擔(dān),增加吞吐量。3.2HDFS體系架構(gòu)HDFS采用Master/Slave架構(gòu)模型,一個(gè)HDFS集群包括一個(gè)NameNode和多個(gè)DataNode。名稱(chēng)節(jié)點(diǎn)NameNode為主節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn)DataNode為從節(jié)點(diǎn),文件被劃分為一系列的數(shù)據(jù)塊(Block)存儲(chǔ)在從節(jié)點(diǎn)DataNode上,NameNode是中心服務(wù)器,不存儲(chǔ)數(shù)據(jù),負(fù)責(zé)管理文件系統(tǒng)的命名空間(Namespace)以及客戶端對(duì)文件的訪問(wèn)。3.2HDFS體系架構(gòu)1.NameNodeNameNode運(yùn)行在日常硬件上,通常只有一個(gè),是整個(gè)文件系統(tǒng)的管理節(jié)點(diǎn)。它維護(hù)著整個(gè)文件系統(tǒng)的文件目錄樹(shù),包括文件/目錄的元數(shù)據(jù)和每個(gè)文件對(duì)應(yīng)的數(shù)據(jù)塊列表,它負(fù)責(zé)接收用戶的操作請(qǐng)求。作為HDFS主服務(wù)節(jié)點(diǎn)的核心,它主要完成下面任務(wù):(1)管理命名空間(Namespace)。(2)控制客戶端對(duì)文件的讀寫(xiě)。(3)執(zhí)行常見(jiàn)文件系統(tǒng)操作,比如文件的重命名、復(fù)制、移動(dòng)、打開(kāi)、關(guān)閉以及目錄操作。3.2HDFS體系架構(gòu)1.NameNodeHDFS命名空間(NameSpace)支持傳統(tǒng)的層次型文件組織結(jié)構(gòu),與大多數(shù)現(xiàn)有文件系統(tǒng)類(lèi)似,用戶可以創(chuàng)建、刪除、移動(dòng)或重命名文件。在HDFS中,NameNode負(fù)責(zé)管理分布式文件系統(tǒng)的命名空間,保存了兩個(gè)核心數(shù)據(jù)結(jié)構(gòu):FsImage和EditLog。其中,F(xiàn)sImage用于維護(hù)文件系統(tǒng)樹(shù)以及文件樹(shù)中所有文件和目錄的元數(shù)據(jù);操作日志文件EditLog記錄了所有針對(duì)文件的創(chuàng)建、刪除、重命名等操作。NameNode記錄了每個(gè)文件中各個(gè)塊所在的數(shù)據(jù)節(jié)點(diǎn)的位置信息,但是并不持久化存儲(chǔ)這些信息,而是在系統(tǒng)每次啟動(dòng)時(shí)掃描所有數(shù)據(jù)節(jié)點(diǎn)重構(gòu)得到這些信息。3.2HDFS體系架構(gòu)2.DataNodeDataNode也運(yùn)行在日常硬件上,通常有多個(gè),它為HDFS提供真實(shí)文件數(shù)據(jù)的存儲(chǔ)服務(wù)。HDFS數(shù)據(jù)存儲(chǔ)在DataNode上,數(shù)據(jù)塊的創(chuàng)建、復(fù)制和刪除都在DataNode上執(zhí)行。DataNode將HDFS數(shù)據(jù)以文件的形式存儲(chǔ)在本地的文件系統(tǒng)中,但并不知道有關(guān)HDFS文件的信息。DataNode把每個(gè)HDFS數(shù)據(jù)塊存儲(chǔ)在本地文件系統(tǒng)的一個(gè)單獨(dú)的文件中,并不在同一個(gè)目錄創(chuàng)建所有的文件,實(shí)際上,它用試探的方法來(lái)確定每個(gè)目錄的最佳文件數(shù)目,并且在適當(dāng)?shù)臅r(shí)候創(chuàng)建子目錄。在同一個(gè)目錄中創(chuàng)建所有的本地文件并不是最優(yōu)的選擇,這是因?yàn)楸镜匚募到y(tǒng)可能無(wú)法高效地在單個(gè)目錄中支持大量的文件。當(dāng)一個(gè)DataNode啟動(dòng)時(shí),它會(huì)掃描本地文件系統(tǒng),產(chǎn)生一個(gè)這些本地文件對(duì)應(yīng)的所有HDFS數(shù)據(jù)塊的列表,然后作為報(bào)告發(fā)送到NameNode,這個(gè)報(bào)告就是塊狀態(tài)報(bào)告。3.2HDFS體系架構(gòu)嚴(yán)格地說(shuō),客戶端并不算是HDFS的一部分??蛻舳丝梢灾С执蜷_(kāi)、讀取、寫(xiě)入等常見(jiàn)操作,并且提供了類(lèi)似Shell的命令行方式來(lái)訪問(wèn)HDFS中的數(shù)據(jù),也提供了API作為應(yīng)用程序訪問(wèn)文件系統(tǒng)的客戶端編程接口。3.3HDFS文件存儲(chǔ)機(jī)制1.BlockHDFS中的數(shù)據(jù)以文件塊Block的形式存儲(chǔ),Block是最基本的存儲(chǔ)單位,每次讀寫(xiě)的最小單元是一個(gè)Block。對(duì)于文件內(nèi)容而言,一個(gè)文件的長(zhǎng)度大小是N,那么從文件的0偏移開(kāi)始,按照固定的大小,順序?qū)ξ募M(jìn)行劃分并編號(hào),劃分好的每一個(gè)塊稱(chēng)一個(gè)Block。Hadoop2.0中默認(rèn)Block大小是128MB。不同于普通文件系統(tǒng),HDFS中如果一個(gè)文件小于一個(gè)數(shù)據(jù)塊的大小,并不占用整個(gè)數(shù)據(jù)塊存儲(chǔ)空間。Block的大小可以根據(jù)實(shí)際需求進(jìn)行配置,可以通過(guò)HDFS配置文件hdfs-site.xml中的參數(shù)dfs.blocksize來(lái)定義塊大小,但要注意,數(shù)字必須是2K,文件的大小可以不是Block大小的整數(shù)倍,這時(shí)最后一個(gè)塊可能存在剩余。3.3HDFS文件存儲(chǔ)機(jī)制1.Block為什么HDFS數(shù)據(jù)塊設(shè)置的這么大呢?原因是和普通的本地磁盤(pán)文件系統(tǒng)不同,HDFS存儲(chǔ)的是大數(shù)據(jù)文件,通常會(huì)有TB甚至PB的數(shù)據(jù)文件需要管理,所以數(shù)據(jù)的基本單元必須足夠大才能提高管理效率。而如果還使用像Linux本地文件系統(tǒng)EXT3的4KB單元來(lái)管理數(shù)據(jù),則會(huì)非常低效,同時(shí)會(huì)浪費(fèi)大量的元數(shù)據(jù)空間。3.3HDFS文件存儲(chǔ)機(jī)制2.Block副本管理策略HDFS采用多副本方式對(duì)數(shù)據(jù)進(jìn)行冗余存儲(chǔ),通常一個(gè)數(shù)據(jù)塊的多個(gè)副本會(huì)被分布到不同的DataNode上。HDFS提供可靠的算法實(shí)現(xiàn)在分布式環(huán)境中存儲(chǔ)大量數(shù)據(jù)。簡(jiǎn)單來(lái)說(shuō),每個(gè)數(shù)據(jù)塊Block都存在副本以提高容錯(cuò)性。默認(rèn)情況下每個(gè)塊存在3個(gè)副本。數(shù)據(jù)塊的信息會(huì)定期由DataNode報(bào)送給NameNode,任何時(shí)候,當(dāng)NameNode發(fā)現(xiàn)一個(gè)塊的副本個(gè)數(shù)少于3個(gè)或者多于3個(gè)時(shí)都會(huì)進(jìn)行補(bǔ)充或者刪除。副本放置的基本原則是保證并非所有的副本都在同一個(gè)機(jī)架(Rack)上。這樣放置的好處在于提供高容錯(cuò)性的同時(shí)降低延時(shí),注意一個(gè)Rack可能包含多個(gè)DataNode,而數(shù)據(jù)分布在不同DataNode可以提高數(shù)據(jù)讀寫(xiě)并發(fā)。對(duì)于多于3個(gè)副本的情況,其它副本將會(huì)隨機(jī)分布在不同DataNode,同時(shí)保證同一個(gè)機(jī)架中最多存在兩個(gè)副本??梢酝ㄟ^(guò)配置文件hdfs-site.xml中的參數(shù)dfs.replication來(lái)定義Block副本數(shù)。3.3HDFS文件存儲(chǔ)機(jī)制2.Block副本管理策略Block副本在機(jī)架中的放置策略Block:123機(jī)架1121機(jī)架2232機(jī)架33313.3HDFS文件存儲(chǔ)機(jī)制2.Block副本管理策略Hadoop集群中機(jī)架邏輯結(jié)構(gòu)Hadoop集群核心交換機(jī)1核心交換機(jī)k機(jī)架

1機(jī)架

2單層交換機(jī)單層交換機(jī)計(jì)算機(jī)1計(jì)算機(jī)2計(jì)算機(jī)1計(jì)算機(jī)2…………機(jī)架

N單層交換機(jī)計(jì)算機(jī)1計(jì)算機(jī)2…3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.1數(shù)據(jù)讀取過(guò)程客戶端JVM1352數(shù)據(jù)節(jié)點(diǎn)DataNode235

5312客戶端DistributedFileSytemFSDataInputStreamDFSInputStream名稱(chēng)節(jié)點(diǎn)NameNode2:獲取數(shù)據(jù)塊信息4:讀取請(qǐng)求7:關(guān)閉文件3:生成對(duì)象實(shí)例5:讀取數(shù)據(jù)6:讀取數(shù)據(jù)元數(shù)據(jù)(名稱(chēng),塊個(gè)數(shù),地址,……)1:打開(kāi)文件6:讀取數(shù)據(jù)…數(shù)據(jù)節(jié)點(diǎn)DataNode數(shù)據(jù)節(jié)點(diǎn)DataNode3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.1數(shù)據(jù)讀取過(guò)程客戶端讀取HDFS上的文件時(shí),需要調(diào)用HDFSJavaAPI一些類(lèi)的方法,從編程角度來(lái)看,主要經(jīng)過(guò)以下幾個(gè)步驟。(1)客戶端生成一個(gè)FileSystem實(shí)例(DistributedFileSystem對(duì)象),并使用此實(shí)例的open()方法打開(kāi)HDFS上的一個(gè)文件。(2)DistributedFileSystem通過(guò)RPC調(diào)用向NameNode發(fā)出請(qǐng)求,得到文件的位置信息,即數(shù)據(jù)塊編號(hào)和所在DataNode地址,對(duì)于每一個(gè)數(shù)據(jù)塊,元數(shù)據(jù)節(jié)點(diǎn)返回保存數(shù)據(jù)塊的數(shù)據(jù)節(jié)點(diǎn)的地址,通常按照DataNode地址與客戶端的距離從近到遠(yuǎn)排序。(3)FileSystem實(shí)例獲得地址信息后,生成一個(gè)FSDataInputStream對(duì)象實(shí)例返回給客戶端,此實(shí)例封裝了一個(gè)DFSInputStream對(duì)象,負(fù)責(zé)存儲(chǔ)數(shù)據(jù)塊信息和DataNode地址信息,并負(fù)責(zé)后續(xù)的文件內(nèi)容讀取工作。(4)客戶端向FSDataInputStream發(fā)出讀取數(shù)據(jù)的read()調(diào)用。(5)FSDataInputStream收到read()調(diào)用請(qǐng)求后,F(xiàn)SDataInputStream封裝的DFSInputStream選擇與第一個(gè)數(shù)據(jù)塊最近的DataNode,并讀取相應(yīng)的數(shù)據(jù)信息返回給客戶端,在數(shù)據(jù)塊讀取完成后,DFSInputStream負(fù)責(zé)關(guān)閉到相應(yīng)DataNode的鏈接。(6)DFSInputStream依次選擇后續(xù)數(shù)據(jù)塊的最近DataNode節(jié)點(diǎn),并讀取數(shù)據(jù)返回給客戶端,直到最后一個(gè)數(shù)據(jù)塊讀取完畢。DFSInputStream從DataNode讀取數(shù)據(jù)時(shí),可能會(huì)碰上某個(gè)DataNode失效的情況,則會(huì)自動(dòng)選擇下一個(gè)包含此數(shù)據(jù)塊的最近的DataNode去讀取。(7)客戶端讀取完所有數(shù)據(jù)塊,然后調(diào)用FSDataInputStream的close()方法關(guān)閉文件。3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.2數(shù)據(jù)寫(xiě)入過(guò)程HDFS的設(shè)計(jì)遵循“一次寫(xiě)入,多次讀取”的原則,所有數(shù)據(jù)只能添加不能更新。數(shù)據(jù)會(huì)被劃分為等尺寸的塊寫(xiě)入不同的DataNode中。每個(gè)塊通常保存指定數(shù)量的副本(默認(rèn)3個(gè))。HDFS數(shù)據(jù)寫(xiě)入基本過(guò)程為:客戶端向NameNode發(fā)送文件寫(xiě)請(qǐng)求,NameNode給客戶分配寫(xiě)權(quán)限,并隨機(jī)分配塊的寫(xiě)入地址——DataNode的IP,兼顧副本數(shù)量和塊Rack自適應(yīng)算法,例如副本因子是3,則每個(gè)塊會(huì)分配到三個(gè)不同的DataNode,為了提高傳輸效率,客戶端只會(huì)向其中一個(gè)DataNode復(fù)制一個(gè)副本,另外兩個(gè)副本則由DataNode傳輸?shù)较噜廌ataNode。3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.2數(shù)據(jù)寫(xiě)入過(guò)程客戶端JVM1352數(shù)據(jù)節(jié)點(diǎn)DataNode235

5312客戶端DistributedFileSytemFSDataOutputStreamDFSOutputStream2:創(chuàng)建文件元數(shù)據(jù)3:寫(xiě)入數(shù)據(jù)6:關(guān)閉文件4:寫(xiě)入數(shù)據(jù)包1:創(chuàng)建文件請(qǐng)求5:接收確認(rèn)包44557:寫(xiě)操作完成元數(shù)據(jù)(名稱(chēng),塊個(gè)數(shù),地址,……)名稱(chēng)節(jié)點(diǎn)NameNode數(shù)據(jù)節(jié)點(diǎn)DataNode數(shù)據(jù)節(jié)點(diǎn)DataNode3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.2數(shù)據(jù)寫(xiě)入過(guò)程從編程角度來(lái)說(shuō),將數(shù)據(jù)寫(xiě)入HDFS主要經(jīng)過(guò)以下幾個(gè)步驟。(1)創(chuàng)建和初始化FileSystem,客戶端調(diào)用create()來(lái)創(chuàng)建文件(2)FileSystem用RPC調(diào)用元數(shù)據(jù)節(jié)點(diǎn),在文件系統(tǒng)的命名空間中創(chuàng)建一個(gè)新的文件,元數(shù)據(jù)節(jié)點(diǎn)首先確定文件原來(lái)不存在,并且客戶端有創(chuàng)建文件的權(quán)限,然后創(chuàng)建新文件。(3)FileSystem返回DFSOutputStream,客戶端開(kāi)始寫(xiě)入數(shù)據(jù)。(4)DFSOutputStream將數(shù)據(jù)分成塊,寫(xiě)入dataqueue。dataqueue由DataStreamer讀取,并通知名稱(chēng)節(jié)點(diǎn)分配數(shù)據(jù)節(jié)點(diǎn),用來(lái)存儲(chǔ)數(shù)據(jù)塊(每塊默認(rèn)復(fù)制3塊)。分配的數(shù)據(jù)節(jié)點(diǎn)放在一個(gè)數(shù)據(jù)流管道(pipeline)里。DataStreamer將數(shù)據(jù)塊寫(xiě)入pipeline中的第一個(gè)數(shù)據(jù)節(jié)點(diǎn),一個(gè)數(shù)據(jù)節(jié)點(diǎn)將數(shù)據(jù)塊發(fā)送給第二個(gè)數(shù)據(jù)節(jié)點(diǎn),第二個(gè)數(shù)據(jù)節(jié)點(diǎn)將數(shù)據(jù)發(fā)送給第三個(gè)數(shù)據(jù)節(jié)點(diǎn)。(5)DFSOutputStream為發(fā)出去的數(shù)據(jù)塊保存了ackqueue,等待pipeline中的數(shù)據(jù)節(jié)點(diǎn)告知數(shù)據(jù)已經(jīng)寫(xiě)入成功。(6)當(dāng)客戶端結(jié)束寫(xiě)入數(shù)據(jù),則調(diào)用stream的close函數(shù)。此操作將所有的數(shù)據(jù)塊寫(xiě)入pipeline中的數(shù)據(jù)節(jié)點(diǎn),并等待ackqueue返回成功。(7)通知名稱(chēng)節(jié)點(diǎn)寫(xiě)入完畢。3.4HDFS數(shù)據(jù)讀寫(xiě)過(guò)程3.4.2數(shù)據(jù)寫(xiě)入過(guò)程數(shù)據(jù)寫(xiě)入可以看作是一個(gè)流水線pipeline過(guò)程,具體來(lái)說(shuō),客戶端收到NameNode發(fā)送的塊存儲(chǔ)位置DataNode列表后,將做如下工作。(1)選擇DataNode列表中的第一個(gè)DataNode1,通過(guò)IP地址建立TCP連接。(2)客戶端通知DataNode1準(zhǔn)備接收塊數(shù)據(jù),同時(shí)發(fā)送后續(xù)DataNode的IP地址給DataNode1,副本隨后會(huì)拷貝到這些DataNode。(3)DataNode1連接DataNode2,并通知DataNode2連接DataNode3,前一個(gè)DataNode發(fā)送副本數(shù)據(jù)給后一個(gè)DataNode,依次類(lèi)推。(4)ack確認(rèn)消息遵從相反的順序,即DataNode3收到完整塊副本后返回確認(rèn)給DataNode2,DataNode2收到完整塊副本后返回確認(rèn)給DataNode1。而DataNode1最后通知客戶端所有數(shù)據(jù)塊已經(jīng)成功復(fù)制。對(duì)于3個(gè)副本,DataNode1會(huì)發(fā)送3個(gè)ack給客戶端表示3個(gè)DataNode都成功接收。隨后,客戶端通知NameNode,完整文件寫(xiě)入成功,NameNode更新元數(shù)據(jù)。(5)當(dāng)客戶端接到通知流水線已經(jīng)建立完成后,將會(huì)準(zhǔn)備發(fā)送數(shù)據(jù)塊到流水線中,然后逐個(gè)數(shù)據(jù)塊按序在流水線中傳輸。這樣以來(lái),客戶端只需要發(fā)送一次,所有備份將在不同DataNode之間自動(dòng)完成,提高了傳輸效率。3.5實(shí)戰(zhàn)HDFS為了方便用戶使用HDFS,HDFS提供三種類(lèi)型接口:HDFSWebUIHDFSShellHDFSAPI3.5.1HDFSWebUIHDFSWebUI主要面向管理員,提供服務(wù)器基礎(chǔ)統(tǒng)計(jì)信息和文件系統(tǒng)運(yùn)行狀態(tài)的查看功能,不支持配置更改操作。從該頁(yè)面上,管理員可以查看當(dāng)前文件系統(tǒng)中各個(gè)節(jié)點(diǎn)的分布信息,瀏覽名稱(chēng)節(jié)點(diǎn)上的存儲(chǔ)、登錄等日志,以及下載某個(gè)數(shù)據(jù)節(jié)點(diǎn)上某個(gè)文件的內(nèi)容。HDFSWebUI地址為http://NameNodeIP:50070,進(jìn)入后可以看到當(dāng)前HDFS文件系統(tǒng)的Overview、Summary、NameNodeJournalStatus、NameNodeStorage等信息。3.5.1HDFSWebUI可以通過(guò)首頁(yè)頂端菜單項(xiàng)『Utilities』→『Browsethefilesystem』查看HDFS文件。3.5.2HDFSShell在Linux命令行終端,使用Shell命令對(duì)HDFS進(jìn)行操作,可以完成HDFS中文件的上傳、下載、復(fù)制、查看、格式化名稱(chēng)節(jié)點(diǎn)等操作。Usage:hadoop[--configconfdir][COMMAND|CLASSNAME]CLASSNAMEruntheclassnamedCLASSNAMEorwhereCOMMANDisoneof:fsrunagenericfilesystemuserclientversionprinttheversionjar<jar>runajarfile,note:pleaseuse"yarnjar"tolaunchYARNapplications,notthiscommand.checknative[-a|-h]checknativehadoopandcompressionlibrariesavailabilitydistcp<srcurl><desturl>copyfileordirectoriesrecursivelyarchive-archiveNameNAME-p<parentpath><src>*<dest>createahadooparchiveclasspathprintstheclasspathneededtogettheHadoopjarandtherequiredlibrariescredentialinteractwithcredentialprovidersdaemonlogget/settheloglevelforeachdaemontraceviewandmodifyHadooptracingsettings3.5.2HDFSShell1.文件系統(tǒng)命令hadoopfs[genericoptions]使用面最廣,可以操作任何文件系統(tǒng),比如本地文件、HDFS文件、HFTP文件、S3文件系統(tǒng)等。hdfsdfs[genericoptions]則是專(zhuān)門(mén)針對(duì)HDFS文件系統(tǒng)的操作。hadoopfsUsage:hadoopfs[genericoptions] [-appendToFile<localsrc>...<dst>] [-cat[-ignoreCrc]<src>...] [-checksum<src>...] [-chgrp[-R]GROUPPATH...] [-chmod[-R]<MODE[,MODE]...|OCTALMODE>PATH...] [-chown[-R][OWNER][:[GROUP]]PATH...] [-copyFromLocal[-f][-p][-l][-d]<localsrc>...<dst>] [-copyToLocal[-f][-p][-ignoreCrc][-crc]<src>...<localdst>] [-count[-q][-h][-v][-t[<storagetype>]][-u][-x]<path>...] [-cp[-f][-p|-p[topax]][-d]<src>...<dst>] [-createSnapshot<snapshotDir>[<snapshotName>]] [-deleteSnapshot<snapshotDir><snapshotName>] [-df[-h][<path>...]] [-du[-s][-h][-x]<path>...] [-expunge] [-find<path>...<expression>...] [-get[-f][-p][-ignoreCrc][-crc]<src>...<localdst>] [-getfacl[-R]<path>] [-getfattr[-R]{-nname|-d}[-een]<path>] [-getmerge[-nl][-skip-empty-file]<src><localdst>] [-help[cmd...]] [-ls[-C][-d][-h][-q][-R][-t][-S][-r][-u][<path>...]] [-mkdir[-p]<path>...] [-moveFromLocal<localsrc>...<dst>] [-moveToLocal<src><localdst>] [-mv<src>...<dst>] [-put[-f][-p][-l][-d]<localsrc>...<dst>] [-renameSnapshot<snapshotDir><oldName><newName>] [-rm[-f][-r|-R][-skipTrash][-safely]<src>...] [-rmdir[--ignore-fail-on-non-empty]<dir>...] [-setfacl[-R][{-b|-k}{-m|-x<acl_spec>}<path>]|[--set<acl_spec><path>]] [-setfattr{-nname[-vvalue]|-xname}<path>] [-setrep[-R][-w]<rep><path>...] [-stat[format]<path>...] [-tail[-f]<file>] [-test-[defsz]<path>] [-text[-ignoreCrc]<src>...] [-touchz<path>...] [-truncate[-w]<length><path>...] [-usage[cmd...]]hadoopfs1)ls功能:顯示文件的元數(shù)據(jù)信息或者目錄包含的文件列表信息。其中目錄信息包括修改日期,權(quán)限,用戶ID,組ID等,文件信息包括文件大小,修改日期,權(quán)限,所屬用戶ID和組ID。格式:hadoopfs-ls<path>示例:顯示文件/log/text1.txt的基本信息。hadoopfs-ls/log/text1.txt示例:顯示目錄/log/hbase包含的文件列表信息。hadoopfs-ls/log/hbasehadoopfs2)ls-R功能:ls命令的遞歸版本,類(lèi)似Unix中的ls-R。格式:hadoopfs-ls-R<path>示例:顯示根目錄/下的所有文件夾和文件。hadoopfs-lsr/3)du功能:顯示文件的大小或者目錄中包含的所有文件的大小。格式:hadoopfs-du<path>示例:顯示目錄/test/data1中每個(gè)文件的大小。hadoopfs-du/test/data1/hadoopfs4)dus功能:顯示目錄下所有文件大小之和,單位是字節(jié)。格式:hadoopfs-dus<path>示例:顯示test目錄下所有文件大小之和。hadoopfs-dus/test5)count功能:統(tǒng)計(jì)文件(夾)數(shù)量和文件總大小信息。格式:hadoopfs-count<path>示例:顯示test目錄下包含的文件數(shù)量。hadoopfs-count/testhadoopfs6)mv功能:移動(dòng)hdfs的文件到指定位置,第一個(gè)參數(shù)表示被移動(dòng)文件位置,第二個(gè)參數(shù)表示移動(dòng)的目標(biāo)位置(通常為目錄)。格式:hadoopfs-mv<src><dst>示例:將/test目錄下文件text1.txt移動(dòng)到/txt目錄。hadoopfs-mv/test/text1.txt/txt7)cp功能:將文件從源路徑復(fù)制到目標(biāo)路徑。源路徑可以是多個(gè)文件,此時(shí)目標(biāo)路徑必須是文件夾。格式:hadoopfs-cp<src><dst>示例:將文件/test/file1復(fù)制到/test/file2目錄下。hadoopfs-cp/test/file1/test/file2hadoopfs8)rm功能:刪除文件或者空文件夾,注意如果文件夾非空,則刪除失敗。格式:hadoopfs-rm<path>示例:刪除文件/test/file1.txt。hadoopfs-rm/test/file1.txt9)rm-r功能:遞歸刪除文件或者文件夾,文件夾可以包含子目錄。格式:hadoopfs-rm-r<path>示例:遞歸刪除test目錄下所有文件和文件夾。hadoopfs-rm-r/testhadoopfs10)put功能:從本地文件系統(tǒng)復(fù)制單個(gè)或多個(gè)源路徑到目標(biāo)文件系統(tǒng)。同時(shí)支持從標(biāo)準(zhǔn)輸入讀取源文件內(nèi)容后寫(xiě)入目標(biāo)位置。格式:hadoopfs-put<localsrc>…<dst>示例:將Linux本地文件/home/xuluhui/text1.txt復(fù)制到HDFS目錄/user/xuluhui下面,并重命名為text2.txt。hadoopfs-put/home/xuluhui/text1.txt/user/xuluhui/text2.txt11)copyFromLocal功能:和put一致。hadoopfs12)moveFromLocal功能:將文件或目錄從本地文件系統(tǒng)移動(dòng)到HDFS。格式:hadoopfs-moveFromLocal<src><dst>示例:將本地文件系統(tǒng)當(dāng)前路徑的test.txt移動(dòng)到HDFS目錄/user/xuluhui下。hadoopfs-moveFromLocaltest.txt/user/xuluhui13)getmerge功能:接受一個(gè)源目錄和一個(gè)目標(biāo)文件,將HDFS源目錄中所有文件連接成本地Linux目標(biāo)文件,可以在每個(gè)文件結(jié)束添加換行,參數(shù)-nl表示是否在文件結(jié)束添加換行。格式:hadoopfs-getmerge[-nl]<src><localdst>示例:將HDFS目錄/user/xuluhui下的文件合并,輸出到本地文件系統(tǒng),保存為/home/xuluhui/test.txt。hadoopfs-getmerge/user/xuluhui/home/xuluhui/test.txthadoopfs14)cat功能:將指定文件內(nèi)容輸出到標(biāo)準(zhǔn)輸出stdout。格式:hadoopfs-cat<path>示例:輸出HDFS目錄/user/xuluhui下文件test.txt到標(biāo)準(zhǔn)輸出。hadoopfs-cat/user/xuluhui/test.txt15)text功能:輸出源文件文本到標(biāo)準(zhǔn)輸出。格式可以是zip和TextRecordInputStream,類(lèi)似Linux中的cat命令。格式:hadoopfs-text<path>示例:輸出HDFS目錄/user/xuluhui下文件test.txt到標(biāo)準(zhǔn)輸出。hadoopfs-text/user/xuluhui/test.txthadoopfs16)mkdir功能:創(chuàng)建指定的一個(gè)或多個(gè)目錄,-p選項(xiàng)用于遞歸創(chuàng)建子目錄。類(lèi)似于Linux的mkdir-p。格式:hadoopfs-mkdir[-p]<paths>示例:在HDFS目錄/user下創(chuàng)建目錄data1和data2。hadoopfs-mkdir/user/data1/user/data217)touchz功能:在HDFS中創(chuàng)建零字節(jié)的空白文件。格式:hadoopfs-touchz<path>示例:創(chuàng)建空白文件empty。hadoopfs-touchz/user/data1/emptyhadoopfs18)stat功能:以指定格式返回指定文件的相關(guān)信息。當(dāng)不指定format時(shí),返回文件的創(chuàng)建日期。命令選項(xiàng)后面可以有格式format,使用引號(hào)表示,格式“%b%n%o%r%Y”依次表示文件大小、文件名稱(chēng)、塊大小、副本數(shù)、訪問(wèn)時(shí)間。格式:hadoopfs-stat[format]<path>示例:顯示目錄/user/data1的統(tǒng)計(jì)信息。hadoopfs-stat/user/data119)tail功能:顯示文件最后1K字節(jié)的內(nèi)容到stdout,一般用于查看日志。如果帶有選項(xiàng)-f,那么當(dāng)文件內(nèi)容變化時(shí),也會(huì)自動(dòng)顯示。其用法與Linux一致。格式:hadoopfs-tail[-f]<path>示例:顯示文件input.txt尾部?jī)?nèi)容。hadoopfs-tail/user/input.txthadoopfs20)chmod功能:修改文件權(quán)限。使用選項(xiàng)-R可以在目錄結(jié)構(gòu)下遞歸更改,命令的使用者必須是文件的所有者或者超級(jí)用戶。格式:hadoopfs-chmod[-R]<MODE[,MODE]…|OCTALMODE><path>示例:更改/user/data1的權(quán)限為766。hadoopfs-chmod766/user/data1HDFS文件擁有和Linux文件類(lèi)似的權(quán)限:讀(r)、寫(xiě)(w)和執(zhí)行(x)。這里執(zhí)行僅表示目錄的訪問(wèn)控制。所有文件和目錄都有所屬用戶、所屬用戶組權(quán)限屬性,權(quán)限值由文件和目錄所屬用戶、所屬用戶組和其他用戶的權(quán)限構(gòu)成的一個(gè)9位二進(jìn)制數(shù)字。hadoopfs21)chown功能:更改文件的所有者。選項(xiàng)R表示遞歸更改所有子目錄,命令的使用者必須是超級(jí)用戶。格式:hadoopfs-chown[-R][OWNER][:[GROUP]]<path>示例:更改/user/data1的所有者為user1。hadoopfs-chownuser1/user/data122)chgrp功能:更改文件所屬的組。選項(xiàng)R表示遞歸處理子目錄,命令使用者必須是文件所有者或者超級(jí)用戶。格式:hadoopfs-chgrp[-R]GROUP<path>示例:更改/user/data1的組為group1。hadoopfs-chgrpgroup1/user/data1hadoopfs23)setrep功能:改變文件的副本系數(shù)。選項(xiàng)R用于遞歸改變目錄下所有文件的副本系數(shù)。此后,HDFS會(huì)根據(jù)系數(shù)自動(dòng)進(jìn)行復(fù)制或清除工作。參數(shù)w表示等待副本操作結(jié)束才退出命令。格式:hadoopfs-setrep[-R][-w]<rep><path>示例:設(shè)置目錄/user/data1下所有文件的副本系數(shù)為3。hadoopfs-setrep-w3-R/user/data1/24)expunge命令功能:清空回收站。注意,清空后數(shù)據(jù)將不可恢復(fù)。格式:hadoopfs-expunge3.5.2HDFSShell2.系統(tǒng)管理命令Usage:hdfsdfsadminNote:AdministrativecommandscanonlyberunastheHDFSsuperuser. [-report[-live][-dead][-decommissioning][-enteringmaintenance][-inmaintenance]] [-safemode<enter|leave|get|wait>] [-saveNamespace] [-rollEdits] [-restoreFailedStoragetrue|false|check] [-refreshNodes] [-setQuota<quota><dirname>...<dirname>] [-clrQuota<dirname>...<dirname>] [-setSpaceQuota<quota>[-storageType<storagetype>]<dirname>...<dirname>] [-clrSpaceQuota[-storageType<storagetype>]<dirname>...<dirname>] [-finalizeUpgrade] [-rollingUpgrade[<query|prepare|finalize>]] [-refreshServiceAcl] [-refreshUserToGroupsMappings] [-refreshSuperUserGroupsConfiguration] [-refreshCallQueue] [-refresh<host:ipc_port><key>[arg1..argn] [-reconfig<namenode|datanode><host:ipc_port><start|status|properties>] [-printTopology] [-refreshNamenodesdatanode_host:ipc_port] [-getVolumeReportdatanode_host:ipc_port] [-deleteBlockPooldatanode_host:ipc_portblockpoolId[force]] [-setBalancerBandwidth<bandwidthinbytespersecond>] [-getBalancerBandwidth<datanode_host:ipc_port>] [-fetchImage<localdirectory>] [-allowSnapshot<snapshotDir>] [-disallowSnapshot<snapshotDir>] [-shutdownDatanode<datanode_host:ipc_port>[upgrade]] [-evictWriters<datanode_host:ipc_port>] [-getDatanodeInfo<datanode_host:ipc_port>] [-metasavefilename] [-triggerBlockReport[-incremental]<datanode_host:ipc_port>] [-listOpenFiles] [-help[cmd]]3.5.3HDFSJavaAPI編程HDFS使用Java語(yǔ)言編寫(xiě),所以提供了豐富了Java編程接口供開(kāi)發(fā)人員調(diào)用,當(dāng)然HDFS同時(shí)支持其它語(yǔ)言如C++、Python等編程接口,但它們都沒(méi)有Java接口方便。凡是使用Shell命令可以完成的功能,都可以使用相應(yīng)JavaAPI來(lái)實(shí)現(xiàn),甚至使用API可以完成Shell命令不支持的功能。HDFSJavaAPI常用類(lèi)類(lèi)名說(shuō)明org.apache.hadoop.fs.FileSystem通用文件系統(tǒng)基類(lèi),用于與HDFS文件系統(tǒng)交互,編寫(xiě)的HDFS程序都需要重寫(xiě)FileSystem類(lèi),通過(guò)該類(lèi),可以方便地像操作本地文件系統(tǒng)一樣操作HDFS集群文件org.apache.hadoop.fs.FSDataInputStream文件輸入流,用于讀取HDFS文件org.apache.hadoop.fs.FSDataOutputStream文件輸出流,向HDFS順序?qū)懭霐?shù)據(jù)流org.apache.hadoop.fs.Path文件與目錄定位類(lèi),用于定義HDFS集群中指定的目錄與文件絕對(duì)或相對(duì)路徑org.apache.hadoop.fs.FileStatus文件狀態(tài)顯示類(lèi),可以獲取文件與目錄的元數(shù)據(jù)、長(zhǎng)度、塊大小、所屬用戶、編輯時(shí)間等信息;同時(shí)可以設(shè)置文件用戶、權(quán)限等內(nèi)容3.5.3HDFSJavaAPI編程1.URL類(lèi).URL類(lèi)可以很方便地打開(kāi)HDFS文件系統(tǒng)中文件,數(shù)據(jù)以流的形式從遠(yuǎn)程服務(wù)器傳輸?shù)奖镜?。使用URL類(lèi)的靜態(tài)方法setURLStreamHandlerFactory設(shè)置Hadoop文件系統(tǒng)的URLStreamHandlerFactory實(shí)現(xiàn)類(lèi)FsUrlStreamHandlerFactory,此方法只在程序啟動(dòng)時(shí)調(diào)用一次,所以放在靜態(tài)語(yǔ)句塊中。所以,如果其他程序已經(jīng)設(shè)置了URLStreamHandlerFactory,則不能再使用上述方法從Hadoop讀取數(shù)據(jù)?!緦?shí)例3-1】【實(shí)例3-1】使用URL讀取HDFS文件。packagecom.xijing.hdfs;

importjava.io.IOException;importjava.io.InputStream;import.URL;importorg.apache.hadoop.fs.FsUrlStreamHandlerFactory;importorg.apche.hadoop.io.IOUtils;

//從URL讀取HDFS文件publicclassHDFSURLReader{ static{//此行設(shè)置文件系統(tǒng)配置為URL流,僅執(zhí)行一次URL.setURLStreamHandlerFactory(newFsUrlStreamHandlerFactory());}publicstaticvoidmain(String[]args){InputStreamstream=null;Stringhdfsurl=“hdfs://30:9000/data/input.txt”);try{//打開(kāi)遠(yuǎn)程HDFS文件系統(tǒng)的文件stream=newURL(hdfsurl).openStream();//輸出文件內(nèi)容到標(biāo)準(zhǔn)輸出(默認(rèn)為屏幕)IOUtils.copyBytes(stream,System.out,1024,false);}catch(IOExceptione){IOUtils.closeStream(stream);//關(guān)閉文件}}}以上程序執(zhí)行后,會(huì)在標(biāo)準(zhǔn)輸出設(shè)備(屏幕)上打印遠(yuǎn)程HDFS文件input.txt的內(nèi)容。方法copyBytes()將流stream復(fù)制到System.out。注意,程序結(jié)束前需要調(diào)用IOUtils關(guān)閉打開(kāi)的文件流。3.5.3HDFSJavaAPI編程2.FileSystem類(lèi)HDFSJavaAPI中最常用的類(lèi)是org.apache.hadoop.fs.FileSystem,作為抽象類(lèi),它定義了存取和管理HDFS文件和目錄的基本方法。FileSystem類(lèi)的常見(jiàn)方法如下:publicstaticFileSystemget(Configurationconf)throwsIOException:根據(jù)配置信息返回文件系統(tǒng)的實(shí)例。publicstaticFileSystemget(URIuri,Configurationconf)throwsIOException:根據(jù)URI的scheme和authority信息返回文件系統(tǒng)實(shí)例。publicstaticFileSystemget(URIuri,Configurationconf,Stringuser)throwsIOException,InterruptedException:根據(jù)URI,配置信息和用戶返回文件系統(tǒng)實(shí)例。publicFSDataOutputStreamcreate(Pathf,booleanoverwrite)throwsIOException:創(chuàng)建文件,path指定完整文件路徑,overwirte指定是否覆蓋現(xiàn)有文件,注意此方法有多個(gè)重載版本,具體可以查看Hadoop的API文件。publicabstractFSDataInputStreamopen(Pathf,intbufferSize)throwsIOException:打開(kāi)文件,返回FSDataInputStream類(lèi)的實(shí)例,bufferSize指定緩沖區(qū)大小。publicabstractbooleandelete(Pathf,booleanrecursive)throwsIOException:刪除文件或目錄,如果要同時(shí)刪除子目錄(非空目錄),則需要設(shè)置參數(shù)recursive為true。如果刪除失?。ū热缥募淮嬖冢﹦t會(huì)拋出I/O異常。publicbooleanmkdirs(Pathf)throwsIOException:創(chuàng)建目錄和子目錄。創(chuàng)建成功時(shí)返回true,否則返回false。publicabstractFileStatus[]listStatus(Pathf)throwsFileNotFoundException,IOException:列出指定文件或目錄的狀態(tài)信息,參數(shù)Path可以是目錄或文件,返回一個(gè)數(shù)組。publicabstractFileStatusgetFileStatus(Pathf)throwsIOException:顯示文件系統(tǒng)的目錄和文件的元數(shù)據(jù)信息。3.5.3HDFSJavaAPI編程2.FileSystem類(lèi)FileSystem類(lèi)通過(guò)NameNode獲取文件塊的地址信息,然后逐塊進(jìn)行訪問(wèn)。FileSystem類(lèi)使用FSDataOutputStream進(jìn)行寫(xiě)文件,使用FSDataInputStream進(jìn)行讀文件。Hadoop提供多種抽象類(lèi)FileSystem的具體實(shí)現(xiàn),例如:DistributedFileSystem:在分布式環(huán)境中存取HDFS文件。LocalFileSystem:在本地系統(tǒng)存取HDFS文件。FTPFileSystem:從FTP存取HDFS文件。WebHdfsFileSystem:從網(wǎng)絡(luò)文件系統(tǒng)存取HDFS文件。3.5.3HDFSJavaAPI編程3.URI和Path類(lèi)通常使用URI和Path兩個(gè)類(lèi)來(lái)表示文件和資源路徑。URI格式為:hdfs://host:port/location,其中Host和Port在Hadoop配置文件conf/core-site.xml中配置。例如,創(chuàng)建URI的Java代碼如下:URIuri=URI.create("hdfs://30:9000/user/xuluhui/TestFile.txt");Path由URI組成,同時(shí)解析操作系統(tǒng)路徑表示方法。例如Windows使用反斜杠“\”分隔父目錄和子目錄,而Linux使用斜杠“/”分隔父目錄和子目錄。3.5.3HDFSJavaAPI編程4.Configuration類(lèi)Configuration類(lèi)將HDFS的客戶端或服務(wù)器端的配置信息傳遞給FileSystem。具體來(lái)講,它會(huì)加載core-site.xml和core-default.xml文件中的具體配置和參數(shù)信息,例如fs.defaultFS、等,同時(shí),它可以更新配置信息。Configuration類(lèi)的使用方法示例如下:Configurationconf=newConfiguration();conf.set("","hdfs://30:9000");3.5.3HDFSJavaAPI編程5.FSDataInputStream類(lèi)FileSystem類(lèi)使用NameNode來(lái)定位DataNode的位置,然后直接存取其上面的數(shù)據(jù)塊以訪問(wèn)文件。文件讀寫(xiě)仍然主要使用Java常見(jiàn)的I/O接口:DataInputStream和DataOutputStream。FSDataInputStream類(lèi)封裝了類(lèi)DataInputStream,其使用方法如下所示。URIuri=URI.create("hdfs://host:port/filepath");Configurationconf=newConfiguration();FileSystemfile=FileSystem.get(uri,conf);FSDataInputStreamin=file.open(newPath(uri));以上方法獲得的FSDataInputStream對(duì)象具有默認(rèn)的緩沖區(qū)大小4096字節(jié),也可以在調(diào)用open()方法時(shí)指定緩沖區(qū)大小。3.5.3HDFSJavaAPI編程5.FSDataInputStream類(lèi)FSDataInputStream類(lèi)實(shí)現(xiàn)了Seekable接口和PositonedReadable接口,用于隨機(jī)跳躍式讀取HDFS文件內(nèi)容,Seekable接口和PositionedReadable接口的定義如下所示。publicinterfaceSeekable{voidseek(longpos)throwsIOException;//跳到指定偏移量(字節(jié))位置longgetPos()throwsIOException;//返回InputStream當(dāng)前位置booleanseekToNewSource(longtargetPos)throwsIOException;//跳到指定新位置}

publicinterfacePositionedReadable{longread(longposition,byte[]buffer,intoffset,intlength);//從指定位置讀取指定長(zhǎng)度}3.5.3HDFSJavaAPI編程5.FSDataInputStream類(lèi)下面代碼使用seek()方法讀取指定偏移量的文件內(nèi)容。FileSystemfile=FileSystem.get(uri,conf);FSDataInputStreamin=file.open(newPath(uri));byte[]btbuffer=newbyte[5];in.seek(5);//讀指針偏移到第5個(gè)字節(jié)Assert.assertEquals(5,in.getPos());in.read(btbuffer,0,5);//讀取5個(gè)字節(jié)到btbufferSystem.out.println(newString(btbuffer));in.read(10,btbuffer,0,5);//從第10個(gè)字節(jié)開(kāi)始讀5個(gè)字節(jié)到btbuffer3.5.3HDFSJavaAPI編程6.FSDataOutputStream類(lèi)FileSystem類(lèi)create()方法返回一個(gè)FSDataOutputStream對(duì)象,用于創(chuàng)建一個(gè)輸出文件或者寫(xiě)內(nèi)容到HDFS文件的結(jié)尾(EOF)。注意FSDataOutputStream不提供seek()方法,因?yàn)镠DFS只支持在文件結(jié)尾添加內(nèi)容,而不支持在中間位置寫(xiě)入。FSDataOutputStream封裝了DataOutputStream類(lèi)的size()、write()等方法。3.5.3HDFSJavaAPI編程7.FileStatus類(lèi)FileStatus類(lèi)主要包含HDFS文件的元信息,包括存取時(shí)間、文件大小、文件屬主、存放路徑等。例如,下面代碼使用類(lèi)FileStatus獲取文件strURI的元信息并輸出。如果strURI是一個(gè)目錄而不是文件,則getFileStatus()方法返回一個(gè)數(shù)組FileStatus[],其包含每個(gè)文件的元信息。URIuri=URI.create(strURI);FileSystemfileSystem=FileSystem.get(uri,conf);FileStatusfileStatus=fileSystem.getFileStatus(newPath(uri));System.out.println("存取時(shí)間:"+fileStatus.getAccessTime());System.out.println("長(zhǎng)度:"+fileStatus.getLen());System.out.println("修改時(shí)間:"+fileStatus.getModificationTime());System.out.println("路徑:"+fileStatus.getPath());【實(shí)例3-2】【實(shí)例3-2】使用HDFSJavaAPI讀寫(xiě)HDFS文件系統(tǒng)上的文件。主要演示了如何獲取FileSystem、上傳和下載文件、創(chuàng)建和刪除目錄等功能。packagecom.xijing.hdfs;

importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;import.URI;import.URISyntaxException;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.fs.FSDataInputStream;importorg.apache.hadoop.fs.FSDataOutputStream;importorg.apache.hadoop.fs.FileSystem;importorg.apache.hadoop.fs.Path;importorg.apache.hadoop.io.IOUtils;importorg.junit.Before;importorg.junit.Test;publicclassHdfsApi{FileSystemfileSystem=null;//定義一個(gè)fileSystem變量

publicvoidgetfileSystem()throwsIOException,InterruptedException,URISyntaxException{//獲取具體文件系統(tǒng)對(duì)象

fileSystem=FileSystem.get(//創(chuàng)建HDFS文件系統(tǒng)的訪問(wèn)路徑,就是Hadoop配置文件core-site.xml中的HDFS文件系統(tǒng)所在機(jī)器

newURI("hdfs://30:9000"),//創(chuàng)建Hadoop配置文件的類(lèi)

newConfiguration(),//Linux啟動(dòng)用戶名

"xuluhui");}//下載HDFS文件到本地publicvoidtestDownload()throwsIllegalArgumentException,IOException{//構(gòu)建一個(gè)輸入流,將需要下載的文件寫(xiě)入到客戶端的內(nèi)存中FSDataInputStreamin=fileSystem.open(newPath("/user/xuluhui/mapreduce/wordcount/input/wc.input"));//構(gòu)建一個(gè)輸出流,將需要下載的文件從內(nèi)存中寫(xiě)入到本地磁盤(pán)FileOutputStreamout=newFileOutputStream("/home/xuluhui/testData/test1.txt");/***參數(shù)說(shuō)明:*in代表輸入流,讀取HDFS文件系統(tǒng)的文件到本機(jī)內(nèi)存中*out代表輸出流,將本機(jī)內(nèi)存中的文件寫(xiě)入到本地磁盤(pán)中*4096緩沖區(qū)大小*true自動(dòng)關(guān)閉流,如果不使用自動(dòng)關(guān)閉的話需要手動(dòng)關(guān)閉輸入輸出流*手動(dòng)關(guān)閉輸入輸出流:*IOUtils.closeStream(in);*IOUtils.closeStream(out);*/IOUtils.copyBytes(in,out,4096,true);}

//上傳文件到HDFSpublicvoidtestUpload()throwsIllegalArgumentException,IOException{//構(gòu)建一個(gè)輸入流,將本機(jī)需要上傳的文件寫(xiě)入到內(nèi)存中FileInputStreamin=newFileInputStream("/home/xuluhui/testData/test2.txt");//構(gòu)建一個(gè)輸出流,將客戶端內(nèi)存的數(shù)據(jù)寫(xiě)入到HDFS文件系統(tǒng)指定的路徑中FSDataOutputStreamout=fileSystem.create(newPath("/input/test2.txt"),true);//true表示自動(dòng)關(guān)閉輸出流IOUtils.copyBytes(in,out,4096,true);}

//創(chuàng)建HDFS目錄publicvoidtestMakeDir()throwsIllegalArgumentException,IOException{booleanisSuccess=fileSystem.mkdirs(newPath("/testdir"));System.out.println(isSuccess);}

//刪除HDFS目錄/文件:publicvoidtestDel()throwsIllegalArgumentException,IOException{System.out.println(//返回的是一個(gè)boolean類(lèi)型的值fileSystem.delete(//指定要?jiǎng)h除的目錄newPath("/testMK"),//是否使用遞歸刪除true));}}3.6HDFS高可靠性機(jī)制作為分布式存儲(chǔ)系統(tǒng),HDFS設(shè)計(jì)和實(shí)現(xiàn)了多種機(jī)制來(lái)保證高可靠性。高可靠性的主要目標(biāo)之一就是即使在系統(tǒng)出錯(cuò)的情況下也要保證數(shù)據(jù)存儲(chǔ)的正常。常見(jiàn)的三種出錯(cuò)情況是:NameNode出錯(cuò)、DataNode出錯(cuò)和數(shù)據(jù)出錯(cuò)。NameNode是HDFS集群中的單點(diǎn)故障所在。如果Namenode節(jié)點(diǎn)出現(xiàn)故障,是需要手工干預(yù)的。HDFS通過(guò)心跳(heartbeat)來(lái)檢測(cè)發(fā)現(xiàn)DataNode是否出錯(cuò)。網(wǎng)絡(luò)傳輸和磁盤(pán)錯(cuò)誤等因素都會(huì)造成數(shù)據(jù)錯(cuò)誤。3.6.1元數(shù)據(jù)備份在服務(wù)器系統(tǒng)中,發(fā)生硬件故障或者軟件錯(cuò)誤是難以避免的,所以需要對(duì)重要數(shù)據(jù)進(jìn)行備份。元數(shù)據(jù)是HDFS的核心數(shù)據(jù),通過(guò)它對(duì)整個(gè)HDFS進(jìn)行管理,F(xiàn)sImage和EditLog是最重要的元數(shù)據(jù)文件。所以,NameNode通常會(huì)配置支持維護(hù)多個(gè)FsImage和EditLog的副本。任何對(duì)FsImage或EditLog的修改,都將同步到它們的副本上。這種多副本的同步操作可能會(huì)降低NameNode每秒處理的名字空間事務(wù)數(shù)量,然而這個(gè)代價(jià)是可以接受的,因?yàn)榧词笻DFS的應(yīng)用是數(shù)據(jù)密集的,它們不一定是元數(shù)據(jù)密集的。當(dāng)NameNode重啟時(shí),它會(huì)選取最近的完整的FsImage和EditLog來(lái)使用。3.6.2SecondaryNameNodeHDFS中除了名稱(chēng)節(jié)點(diǎn)NameNode外,還有一個(gè)輔助NameNode,稱(chēng)為第二名稱(chēng)節(jié)點(diǎn)SecondaryNameNode。從名稱(chēng)上看,SecondaryNameNode似乎是作為NameNode的備份而存在的,事實(shí)上并非如此。SecondaryNameNode有它自身的獨(dú)立的角色和功能,通常認(rèn)為它和NameNode是協(xié)同工作的。SecondaryNameNode主要有如下特征和功能:是HDFS高可用性的一個(gè)解決方案,但不支持熱備,使用前配置即可;定期對(duì)NameNode中內(nèi)存元數(shù)據(jù)進(jìn)行更新和備份;默認(rèn)安裝在與NameNode相同的節(jié)點(diǎn),但是建議安裝在不同節(jié)點(diǎn)以提高可靠性。3.6.2SecondaryNameNode當(dāng)NameNode運(yùn)行很長(zhǎng)時(shí)間后,EditLog文件會(huì)變得很大。在這種情況下就會(huì)出現(xiàn)以下問(wèn)題:(1)EditLog文件會(huì)變的很大,如何去管理這個(gè)文件?(2)NameNode的重啟會(huì)花費(fèi)很長(zhǎng)時(shí)間,因?yàn)橛泻芏喔膭?dòng)要合并到FsImage文件上;(3)如果NameNode宕機(jī),那就丟失了很多改動(dòng),因?yàn)榇藭r(shí)的FsImage文件時(shí)間戳比較舊。為了克服這些問(wèn)題,我們需要一個(gè)易于管理的機(jī)制來(lái)幫助減小EditLog文件的大小和得到一個(gè)最新的FsImage文件,這樣也會(huì)減小NameNode的計(jì)算壓力。而SecondaryNameNode就是為了幫助解決上述問(wèn)題提出的,它的主要職責(zé)是合并NameNode的EditLog到FsImage文件中,即對(duì)元數(shù)據(jù)進(jìn)行定期更新和備份。3.6.3BackupNode備份Hadoop2.0以后版本新提供了一個(gè)真正意義上的備用節(jié)點(diǎn),即BackupNode。BackupNode在內(nèi)存中維護(hù)了一份從NameNode同步過(guò)來(lái)的FsImage,同時(shí)它還從NameNode接收EditLog文件的日志流,并把它們持久化到硬盤(pán)。BackupNode在內(nèi)存中維護(hù)與NameNode一樣的元數(shù)據(jù)。BackupNode的啟動(dòng)命令是“hdfsnamenode-backup”。在配置文件hdfs-site.xml中進(jìn)行設(shè)置,主要包括兩個(gè)參數(shù):dfs.backup.address、dfs.backup.http.address。3.6.4HDFSNameNodeHA高可用機(jī)制1.HDFSNameNodeHA概述在HDFS中,NameNode管理整個(gè)HDFS文件系統(tǒng)的元數(shù)據(jù)信息,具有舉足輕重的作用,NameNode的可用性直接決定了整個(gè)Hadoop的可用性,因此,NameNode絕對(duì)不允許出現(xiàn)故障。在Hadoop1.0時(shí)代,NameNode存在單點(diǎn)故障問(wèn)題,一旦NameNode進(jìn)程不能正常工作,就會(huì)造成整個(gè)HDFS也無(wú)法使用,而Hive或HBase等的數(shù)據(jù)也都存放在HDFS上,因此Hive或HBase等框架也將無(wú)法使用,這可能導(dǎo)致生產(chǎn)集群上的很多框架都無(wú)法正常使用,而通過(guò)重啟NameNode來(lái)進(jìn)行數(shù)據(jù)恢復(fù)十分耗時(shí)。在Hadoop2.0中,HDFSNameNode的單點(diǎn)故障問(wèn)題得到了解決,這就是HDFSNameNodeHighAvailability(HDFSNameNode高可用機(jī)制,簡(jiǎn)稱(chēng)HDFSNameNodeHA)。3.6.4HDFSNameNodeHA高可用機(jī)制2.HDFSNameNodeHA體系架構(gòu)心跳心跳監(jiān)視名稱(chēng)節(jié)點(diǎn)健康狀態(tài)提交EditLog通過(guò)共享存儲(chǔ)系統(tǒng)(NFS、QJM或ZooKeeper)同步狀態(tài)向主、備名稱(chēng)節(jié)點(diǎn)上報(bào)數(shù)據(jù)塊的位置信息主備切換控制器主備切換控制器

ZooKeeper集群ZooKeeperZooKeeperZooKeeper主名稱(chēng)節(jié)點(diǎn)(活躍)備名

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論