認(rèn)識(shí)HDFS
HDFS的特點(diǎn):
高容錯(cuò)性
高吞吐量
故障的檢測和自動(dòng)快速恢復(fù)
流式的數(shù)據(jù)訪問
大數(shù)據(jù)集
一次寫入,多次讀寫
HDFS不適用的場景
不支持大量小文件的存儲(chǔ)
不適合隨機(jī)讀寫
不適合隨意修改
HDFS的組成
hdfs是一個(gè)主從結(jié)構(gòu)的體系,一個(gè)HDFS的集群由以下部分組成:
NameNode(名字節(jié)點(diǎn)):一個(gè)用來管理文件的名字空間和調(diào)節(jié)客戶端訪問文件的主服務(wù)器
DataNode(數(shù)據(jù)節(jié)點(diǎn)):一個(gè)或多個(gè),用來管理存儲(chǔ)
HDFS的數(shù)據(jù)復(fù)制
HDFS能可靠的在大量集群中存儲(chǔ)非常大量的文件,它以塊序列的形式存儲(chǔ)每一個(gè)文件,文件中除了最后一個(gè)塊的其他塊都是相同的大小.屬于文件的塊為了故障容錯(cuò)而被復(fù)制.塊的大小和復(fù)制數(shù)可以為每個(gè)文件配置.HDFS中的文件都是嚴(yán)格地要求任何時(shí)候只有一個(gè)寫操作.
名字節(jié)點(diǎn)(NameNode)來做所有的塊復(fù)制,它周期性地接收來自集群中數(shù)據(jù)節(jié)點(diǎn)(DataNode)的心跳和塊報(bào)告.一個(gè)心跳的收條表示這個(gè)數(shù)據(jù)節(jié)點(diǎn)是健康的,是渴望服務(wù)數(shù)據(jù)的.一個(gè)塊報(bào)告包括該數(shù)據(jù)節(jié)點(diǎn)上的所有塊列表.復(fù)制塊放置位置的選擇嚴(yán)重影響HDFS的可靠性和性能,因此機(jī)架的復(fù)制布局目的就是提高數(shù)據(jù)的可靠性、可用性和網(wǎng)絡(luò)帶寬的利用率
默認(rèn)復(fù)制數(shù)為3的情況下,HDFS放置方式是將第一個(gè)放在本地節(jié)點(diǎn),將第二個(gè)復(fù)制放到本地機(jī)架上的另一個(gè)節(jié)點(diǎn)上,而將第三個(gè)復(fù)制到不同機(jī)架上的節(jié)點(diǎn)。這種方式減少了機(jī)架內(nèi)的寫流量,提高了寫的性能.機(jī)架的失效機(jī)會(huì)遠(yuǎn)小于機(jī)器失效的機(jī)會(huì)
在復(fù)制數(shù)為3的情況下,是備份在不同的機(jī)架上,而不是三個(gè)機(jī)架.文件的復(fù)制不是均勻地分布在機(jī)架上.1/3在同一個(gè)節(jié)點(diǎn)上,第二個(gè)1/3復(fù)制在同一個(gè)機(jī)架上,另外1/3是均勻地分布在其他機(jī)架上.
可在hdfs-site.xml中修改dfs.replication的個(gè)數(shù)即修改復(fù)制個(gè)數(shù),這種方案參數(shù)其實(shí)只在文件被寫入dfs時(shí)起作用,雖然更改了配置文件,但是不會(huì)改變之前寫入的文件的備份數(shù),而且需要重啟HDFS系統(tǒng)才能生效
hadoop fs -setrep -R 1 /:這種方式可以改變整個(gè)HDFS里面的備份數(shù),不需要重啟HDFS系統(tǒng)
數(shù)據(jù)塊的復(fù)制是以pipeline的方式進(jìn)行的
HDFS復(fù)制的選擇
HDFS嘗試滿足一個(gè)讀操作來自離它最近的復(fù)制。如果在讀節(jié)點(diǎn)的同一個(gè)機(jī)架上有這個(gè)復(fù)制,則直接讀.如果HDFS集群是跨越多個(gè)數(shù)據(jù)的中心,那么本地?cái)?shù)據(jù)中心的復(fù)制優(yōu)先于遠(yuǎn)程的復(fù)制
HDFS的安全模式
在啟動(dòng)的時(shí)候,NameNode會(huì)進(jìn)入一個(gè)特殊的狀態(tài)叫做安全模式。
安全模式是不發(fā)生文件塊的復(fù)制的
NameNode接受DataNode的心跳和數(shù)據(jù)塊報(bào)告,一個(gè)塊報(bào)告包括數(shù)據(jù)節(jié)點(diǎn)向名字節(jié)點(diǎn)報(bào)告數(shù)據(jù)塊的列表
每一個(gè)塊有一個(gè)特定的最小復(fù)制數(shù),當(dāng)NameNode檢查這個(gè)塊已經(jīng)大于最小的復(fù)制數(shù),就被認(rèn)為是安全的復(fù)制了.當(dāng)達(dá)到配置的塊安全復(fù)制比例時(shí),NameNode就退出安全模式.它將檢測數(shù)據(jù)塊的列表,將小于特定的復(fù)制數(shù)的塊復(fù)制到其他的數(shù)據(jù)節(jié)點(diǎn)
HDFS的元數(shù)據(jù)持久化
HDFS的名字空間是由NameNode來存儲(chǔ)的。
NameNode用事務(wù)日志(EditsLog)來持久化每一個(gè)對(duì)文件系統(tǒng)的元數(shù)據(jù)的改變,即對(duì)元數(shù)據(jù)的每一步操作都會(huì)被記錄到EditsLog中.NameNode在本地文件系統(tǒng)中用一個(gè)文件來存儲(chǔ)這個(gè)EditsLog
完整的文件系統(tǒng)名字空間、文件塊的映射和文件系統(tǒng)的配置都存在一個(gè)叫Fsimage的文件中,Fsimage也是在NameNode的本地文件系統(tǒng)中
CheckPoint(檢查點(diǎn)):當(dāng)NameNode啟動(dòng)的時(shí)候,它會(huì)從磁盤中讀取Fsimage和EditsLog文件,然后將新的元數(shù)據(jù)刷新到本地磁盤中,生成一個(gè)新的Fsimage文件,至此EditsLog文件已經(jīng)被處理并持久化的Fsimage中
任何對(duì)Fsimage和EditsLog的更新都會(huì)同步地更新每一個(gè)副本
HDFS架構(gòu)
HDFS架構(gòu)是一個(gè)典型的主從架構(gòu),包括一個(gè)NameNode(主節(jié)點(diǎn))和多個(gè)DataNode(從節(jié)點(diǎn))
架構(gòu)圖如下圖所示:

NameNode是整個(gè)文件系統(tǒng)的管理節(jié)點(diǎn),它負(fù)責(zé)文件系統(tǒng)名字空間(NameSpace)的管理與維護(hù),同時(shí)負(fù)責(zé)客戶端文件操作的控制以及具體存儲(chǔ)任務(wù)的管理與分配
DataNode提供了真實(shí)文件數(shù)據(jù)的存儲(chǔ)服務(wù)
數(shù)據(jù)塊
Hadoop1.X默認(rèn)的數(shù)據(jù)塊大小是64MB
Hadoop2.X默認(rèn)的數(shù)據(jù)塊大小是128MB
HDFS上的文件系統(tǒng)也被劃分為塊大小的多個(gè)分塊(Chunk)作為獨(dú)立的存儲(chǔ)單元.但與其他文件系統(tǒng)不同的是,HDFS中小于一個(gè)塊大小的文件不會(huì)占據(jù)整個(gè)塊的空間
為什么HDFS默認(rèn)的Block為128MB(64MB)?
HDFS的塊之所以這么大,主要是為了把尋道(Seek)時(shí)間最小化.如果一個(gè)塊足夠大,從硬盤傳輸數(shù)據(jù)的時(shí)間將遠(yuǎn)遠(yuǎn)大于尋找塊的起始位置的時(shí)間,這樣就使HDFS的數(shù)據(jù)傳輸速度和硬盤的傳輸速度更加接近.
分布式文件系統(tǒng)中的塊進(jìn)行抽象帶來的好處:
一個(gè)文件系統(tǒng)的大小可以大于網(wǎng)絡(luò)中任意一個(gè)磁盤的容量
使用塊抽象而非整個(gè)文件作為存儲(chǔ)單元,大大簡化了存儲(chǔ)子系統(tǒng)的設(shè)計(jì).
NameNode
NameNode是管理者,一個(gè)Hadoop集群有一個(gè)NameNode節(jié)點(diǎn),是一個(gè)通常在HDFS實(shí)例中的單獨(dú)機(jī)器上運(yùn)行的軟件.它負(fù)責(zé)管理文件系統(tǒng)名字空間和控制外部客戶機(jī)的訪問
NameNode決定是否將文件映射到DataNode的復(fù)制塊上.
實(shí)際的I/O事務(wù)并沒有經(jīng)過NameNode,只有表示DataNode和塊的文件映射的元數(shù)據(jù)經(jīng)過NameNode。當(dāng)外部客戶機(jī)發(fā)送請(qǐng)求要求創(chuàng)建文件時(shí),NameNode會(huì)以塊標(biāo)識(shí)和該塊的第一個(gè)副本的DataNode IP地址作為響應(yīng).這個(gè)NameNode還會(huì)通知其他將要接收該塊的副本的DataNode
NameNode主要功能如下:
1:NameNode提供名稱查詢服務(wù),它是一個(gè)Jetty服務(wù)器
2:NameNode保存metadata信息.具體包括:文件owership和permissons;文件包含哪些塊,Block保存在哪個(gè)DataNode(由DataNode啟動(dòng)時(shí)上報(bào))
3:NameNode的metadata信息在啟動(dòng)后會(huì)加載在內(nèi)存
DataNode
Hadoop集群中包含一個(gè)NameNode和大量的DataNode,DataNode通常以機(jī)架的形式組織,機(jī)架通過一個(gè)交換機(jī)將所有系統(tǒng)連接起來
DataNode響應(yīng)來自HDFS客戶機(jī)的讀寫請(qǐng)求,它們還響應(yīng)來自NameNode的創(chuàng)建、刪除和復(fù)制塊的命令
DataNode的功能如下:
1:保存Block,每一個(gè)塊對(duì)應(yīng)一個(gè)元數(shù)據(jù)信息文件。這個(gè)文件主要描述這個(gè)塊屬于哪個(gè)文件,第幾個(gè)塊等信息
2:啟動(dòng)DataNode線程的時(shí)候會(huì)向NameNode匯報(bào)Block信息
3:通過向NameNode發(fā)送心跳保持其聯(lián)系(3秒一次),如果NameNode10分鐘沒有收到DataNode的心跳,則認(rèn)為其已經(jīng)lost,并將其上的Block復(fù)制到其他DataNode
SecondaryNameNode
SecondaryNameNode(輔助元數(shù)據(jù)節(jié)點(diǎn)),會(huì)周期性地將EditsLog文件中記錄對(duì)HDFS的操作合并到一個(gè)Fsimage中文件中,然后清空EditsLog文件.NameNode的重啟會(huì)加載最新的一個(gè)Fsimage文件,并重新創(chuàng)建一個(gè)EditsLog文件來記錄HDFS操作,由于EditsLog中記錄的是從上一次Fsimage以后到現(xiàn)在的操作列表,所以會(huì)比較小
如果沒有SecondaryNameNode這個(gè)周期性的合并過程,當(dāng)每次重啟NameNode的時(shí)候,就會(huì)花費(fèi)很長的時(shí)間,而這樣周期性地合并就能減少重啟的時(shí)間,同時(shí)也能保證HDFS系統(tǒng)的完整性

SecondaryNameNode合并Fsimage和EditsLog文件過程如下:
1:文件系統(tǒng)客戶端進(jìn)行寫操作時(shí),首先會(huì)把它記錄在EditsLog中
2:NameNode在內(nèi)存中保存了文件系統(tǒng)的元數(shù)據(jù)信息.在記錄修改日志后,NameNode修改內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)
3:每次的寫操作成功之前,修改日志都會(huì)同步(Sync)到文件系統(tǒng)中
4:Fsimage文件即名字空間映像文件,是內(nèi)存中的元數(shù)據(jù)在硬盤上的CheckPoint,它是一種序列化的格式,并不能夠在硬盤上直接修改
5:當(dāng)NameNode失敗時(shí),最新CheckPoint的元數(shù)據(jù)信息從Fsimage加載到內(nèi)存中,然后逐一重新執(zhí)行修改日志后的操作
6:SecondaryNameNode就是用來幫助NameNode將內(nèi)存中的元數(shù)據(jù)信息CheckPoint到硬盤上的.
CheckPoint過程如下:
1:SecondaryNameNode通知NameNode生成新的EditsLog,以后的日志都寫到新的日志文件中
2:SecondaryNameNode用Http Get從NameNode獲得Fsimage文件以及舊的日志文件
3:SecondaryNameNode將Fsimage文件加載到內(nèi)存中,并執(zhí)行日志文件中的操作,然后生成新的Fsimage文件
4:SecondaryNameNode將新的Fsimage文件用Http Post傳回NameNode
5:NameNode可以將舊的Fsimage以及舊的EditLog,換成新的Fsimage文件和新的EditLog(第一步生成的),然后更新fstime文件,寫入此次CheckPoint的時(shí)間
6:這樣NameNode中的Fsimage文件保存了最新的CheckPoint的元數(shù)據(jù)信息,日志文件也重新開始,不會(huì)變得很大了.
SecondaryNameNode會(huì)周期性地將EditsLog文件進(jìn)行合并,合并前提條件如下:
EditsLog文件到達(dá)某一閥值時(shí)對(duì)其進(jìn)行合并(默認(rèn)為64MB,當(dāng)文件大小超過64MB,就會(huì)觸發(fā)EditsLog與Fsimage文件的合并,修改core-site.xml配置文件中的fs.checkpoint.period選項(xiàng))
每隔一段時(shí)間對(duì)其合并(默認(rèn)為1小時(shí)合并一次,修改core-site.xml配置文件中的fs.checkpoint.size)
機(jī)架感知
默認(rèn)情況下,Hadoop的機(jī)架感知是沒有啟用的.所以,通常情況下,Hadoop集群的HDFS在選擇機(jī)器的時(shí)候是隨機(jī)選擇的.
啟用Hadoop機(jī)架感知功能,配置非常簡單,在NameNode所在機(jī)器 的hadoop-site.xml文件中配置一個(gè)選項(xiàng)
<property>
<name>topology.script.file.name</name>
<value>/path/to/script</value>
</property>
HDFS的RPC機(jī)制
一般我們所了解的RPC(Remote Procedure Call,遠(yuǎn)程過程調(diào)用)機(jī)制都要面對(duì)兩個(gè)問題:
1對(duì)象調(diào)用方式;
2序列/反序列化機(jī)制
但Hadoop實(shí)現(xiàn)了自己簡單的RPC組件,依賴Hadoop Writable類型的支持
Hadoop Writable接口要求每個(gè)實(shí)現(xiàn)類都要確保將本類的對(duì)象正確序列化(writeObject)與反序列化(readObject)。因此,Hadoop RPC使用java動(dòng)態(tài)代理與反射實(shí)現(xiàn)對(duì)象調(diào)用方式

RPC的實(shí)現(xiàn)流程
簡單的說,Hadoop RPC = 動(dòng)態(tài)代理+定制的二進(jìn)制流
實(shí)現(xiàn)流程如下:
遠(yuǎn)程的對(duì)象擁有固定的接口,這個(gè)接口用戶也是可見的,只是真正的實(shí)現(xiàn)(Object)只在服務(wù)端.用戶如果想使用哪個(gè)實(shí)現(xiàn),調(diào)用過程是:
先根據(jù)那個(gè)接口動(dòng)態(tài)代理生成一個(gè)代理對(duì)象,調(diào)用這個(gè)代理對(duì)象的時(shí)候,用戶的調(diào)用請(qǐng)求被RPC捕捉到,然后包裝成調(diào)用請(qǐng)求,序列化成數(shù)據(jù)流發(fā)送到服務(wù)端;服務(wù)端從數(shù)據(jù)流中解析出調(diào)用請(qǐng)求,然后根據(jù)用戶所希望調(diào)用的接口,調(diào)用真正的實(shí)現(xiàn)對(duì)象,再把調(diào)用結(jié)果返回給客戶端
RPC的實(shí)體模型
注意:用戶在調(diào)用代理對(duì)象時(shí)RPC是怎樣攔截這次調(diào)用請(qǐng)求的?
創(chuàng)建代理對(duì)象時(shí)需要為它關(guān)聯(lián)一個(gè)InvocationHandler,對(duì)代理對(duì)象的每次調(diào)用都會(huì)進(jìn)入綁定的InvocationHandler中,RPC就從這里獲取用戶的請(qǐng)求
Listener:監(jiān)聽RPC Server的端口,如果客戶端有連接請(qǐng)求到達(dá),它就接收連接,然后把連接轉(zhuǎn)發(fā)到某個(gè)Reader,讓Reader讀取那個(gè)連接的數(shù)據(jù)。如果有多個(gè)Reader,當(dāng)有新連接過來時(shí),就在這些Reader間順序分發(fā)。注意Hadoop0.21版本在支持多Reader時(shí)有個(gè)bug(JIRA),如果有Reader在Server運(yùn)行期間沒有被使用,Server進(jìn)程不能正常關(guān)閉
Reader:從某個(gè)客戶端連接中讀取數(shù)據(jù)流,把它轉(zhuǎn)化成調(diào)用對(duì)象(Call),然后放到調(diào)用隊(duì)列(call queue)里
Handler:真正做事的實(shí)體,它從調(diào)用隊(duì)列中獲取調(diào)用信息,然后反射調(diào)用真正的對(duì)象,得到結(jié)果,再把此次調(diào)用放到響應(yīng)隊(duì)列(response queue)里
>Responder:不斷地檢查響應(yīng)隊(duì)列中是否有調(diào)用信息,如果有,就把調(diào)用的結(jié)果返回給客戶端

HDFS的文件讀取

文件讀取的流程如下:
1:使用HDFS提供的客戶度開發(fā)庫Client,向遠(yuǎn)程的NameNode發(fā)起RPC請(qǐng)求
2:NameNode會(huì)根據(jù)情況返回文件的部分或者全部Block列表,對(duì)于每個(gè)Block,NameNode都會(huì)返回有該Block副本的DataNode地址
3:客戶端開發(fā)庫Client會(huì)選取離客戶端最接近的DataNode來讀取Block,如果客戶端本身就是DataNode,將從本地直接獲取數(shù)據(jù)
4:讀取完當(dāng)前Block的數(shù)據(jù)后,關(guān)閉與當(dāng)前的DataNode連接,并為讀取下一個(gè)Block尋找最佳的DataNode
5:讀取完列表的Block后,且文件讀取還沒有結(jié)束,客戶端開發(fā)庫會(huì)繼續(xù)向NameNode獲取下一批Block列表
6:讀取完一個(gè)Block都會(huì)進(jìn)行CheckSum驗(yàn)證,如果讀取DataNode時(shí)會(huì)出現(xiàn)錯(cuò)誤,客戶端會(huì)通知NameNode,然后從下一個(gè)擁有該Block復(fù)制的DataNode繼續(xù)讀
HDFS的文件寫入

寫入文件的過程比讀取復(fù)雜,步驟如下:
1:使用HDFS提供的客戶端開發(fā)庫Client,向遠(yuǎn)程的NameNode發(fā)起RPC請(qǐng)求
2:NameNode會(huì)檢查要?jiǎng)?chuàng)建的文件是否已經(jīng)存在,創(chuàng)建者是否有權(quán)限進(jìn)行操作,成功后會(huì)為文件創(chuàng)建一個(gè)記錄,否則會(huì)讓客戶端拋出異常
3:當(dāng)客戶端開始寫入文件的時(shí)候,開發(fā)庫會(huì)將文件切分多個(gè)packet,并在內(nèi)部以數(shù)據(jù)隊(duì)列(data queue)的形式管理這些packet,并向NameNode申請(qǐng)新的Block,獲取用來存儲(chǔ)replicas的合適的DataNode列表,列表的大小根據(jù)在NameNode中對(duì)replication的設(shè)置而定
4:開始以管道(pipeline)的形式將Packet寫入所有的replicas中。開發(fā)庫把packet以流的方式寫入第一個(gè)DataNode,該DataNode把packet存儲(chǔ)之后,再把器傳遞給在此管道中的下一個(gè)DataNode,直到最后一個(gè)DataNode,這種寫數(shù)據(jù)的方式呈流水線的形式
5:最后一個(gè)DataNode成功存儲(chǔ)之后會(huì)返回一個(gè)ack packet,在管道里傳遞給客戶端,在客戶端的開發(fā)庫內(nèi)部維護(hù)著ack queue,成功收到DataNode返回的ack packet后會(huì)從ack queue移除相應(yīng)的packet
6: 如果傳輸過程中,有某個(gè)DataNode出現(xiàn)了故障,當(dāng)前的管道會(huì)被關(guān)閉,出現(xiàn)故障的DataNode會(huì)從當(dāng)前的管道中移除,剩余的Block會(huì)繼續(xù)剩下的DataNode中繼續(xù)以管道的形式傳輸,同時(shí)NameNode會(huì)分配一個(gè)新的DataNode,保持replicas設(shè)定的數(shù)量
HDFS的HA(High Availability,高可用性)機(jī)制
Hadoop2.X版本之前,NameNode是HDFS集群的單點(diǎn)故障點(diǎn)(SPOF)
影響HDFS集群不可用主要包括以下兩種情況:
1:類似機(jī)器宕機(jī)這樣的意外情況將導(dǎo)致集群不可用,只有重啟NameNode之后才可使用
2:計(jì)劃內(nèi)的軟件或硬件升級(jí)(NameNode節(jié)點(diǎn)),將導(dǎo)致集群在短時(shí)間范圍內(nèi)不可用
一個(gè)典型的HA集群,兩個(gè)單獨(dú)的機(jī)器配置為NameNode,在任何時(shí)候,一個(gè)NameNode處于活動(dòng)狀態(tài),另一個(gè)處于待機(jī)狀態(tài),活動(dòng)NameNode負(fù)責(zé)處理集群中所有客戶端的操作,待機(jī)時(shí)僅僅作為一個(gè)Slave,保持足夠的狀態(tài),如果有必要提供一個(gè)快速的故障轉(zhuǎn)移
為了提供快速的故障轉(zhuǎn)移,必須保證備用節(jié)點(diǎn)有最新的集群中塊的位置信息,為了達(dá)到這一點(diǎn),DataNode節(jié)點(diǎn)需要配置兩個(gè)NameNode的位置,同時(shí)發(fā)送塊的位置信息和心跳信息到兩個(gè)NameNode
為了防止"腦裂場景"的出現(xiàn),必須為共享存儲(chǔ)配置至少一個(gè)fencing方法。在宕機(jī)期間,如果不能確定之間的活動(dòng)節(jié)點(diǎn)已經(jīng)放棄活動(dòng)狀態(tài),fencing進(jìn)程負(fù)責(zé)中斷以前的活動(dòng)節(jié)點(diǎn)編輯存儲(chǔ)的共享訪問,這可以防止任何進(jìn)一步的修改名字空間.允許新的活動(dòng)節(jié)點(diǎn)安全地進(jìn)行故障轉(zhuǎn)移

HA架構(gòu)解釋如下:
只有一個(gè)NameNode是Active,并且只有這個(gè)ActiveNameNode能提供服務(wù),改變NameSpace。以后可以考慮讓StandbyNameNode提供讀服務(wù)
提供手動(dòng)Failover,在升級(jí)過程中,Failover在NameNode-DataNode之間寫不變的情況下才能生效
在之前的NameNode重新恢復(fù)之后,不能提供failback
數(shù)據(jù)一致性比Failover更重要
HA的設(shè)置和Failover都應(yīng)該保證在兩者操作錯(cuò)誤或者配置錯(cuò)誤的時(shí)候,不得導(dǎo)致數(shù)據(jù)損壞
NameNode的短期垃圾回收不應(yīng)該觸發(fā)Failover
DataNode會(huì)同時(shí)向NameNode Active和NameNode Standary匯報(bào)塊的信息。NameNode Active和NameNode Standby 通過NFS備份MetaData信息到一個(gè)磁盤上面
HDFS的federation機(jī)制
簡單的說,HDFS Federation就是使得HDFS支持多個(gè)名字空間,并且允許在HDFS中同時(shí)存在多個(gè)NameNode
引入Federation的最主要原因是對(duì)HDFS系統(tǒng)中文件的隔離,Federation能夠快速解決大部分單NameNode HDFS的問題
HDFS Federation使用了多個(gè)獨(dú)立的NameNode/NameSpace使得HDFS的命名服務(wù)能夠水平擴(kuò)展

HDFS Federation中的NameNode之間是聯(lián)盟關(guān)系,它們之間相互獨(dú)立且不需要相互協(xié)調(diào)。HDFS Federation中的NameNode提供了名字空間和塊關(guān)聯(lián)功能.HDFS Federation中的DataNode被所有的NameNode用作公共存儲(chǔ)塊的地方.每一個(gè)DataNode都會(huì)向所在集群中所有的NameNode注冊,并周期性的發(fā)送心跳和塊信息報(bào)告,同時(shí)處理來自NameNode的指令
塊池(Block Pool)就是屬于單個(gè)名字空間的一組Block
Federation HDFS中有多組獨(dú)立的塊,同一個(gè)DataNode中可以存儲(chǔ)屬于多個(gè)塊池的多個(gè)塊。
塊池允許一個(gè)名字空間在不通知其他名字空間的情況下,為一個(gè)新的Block創(chuàng)建Block ID.同時(shí),一個(gè)NameNode失效不會(huì)影響其下的DataNode為其他NameNode的服務(wù)
在HDFS中,所有的更新、回滾都是以NameNode和BlockPool為單元發(fā)生的.即同HDFS Federation中不同的NameNode/BlockPool之間沒有什么關(guān)系
多個(gè)名字空間的管理問題
在一個(gè)集群中需要唯一的名字空間還是多個(gè)名字空間,核心問題是名字空間中數(shù)據(jù)的共享和訪問問題。
使用全局唯一的名字空間是解決數(shù)據(jù)共享和訪問的一種方法
在多個(gè)名字空間下,還可以使用Client Side Mount Table方式做到數(shù)據(jù)共享和訪問

HDFS Federation中名字空間管理的基本原理:
將各個(gè)名字空間掛載到全局mount-table中,就可以將數(shù)據(jù)到全局共享;
同樣,名字空間掛載到個(gè)人的mount-table中,就成為應(yīng)用程序可見的名字空間視圖
維護(hù)HDFS
追加數(shù)據(jù)
1.Client調(diào)用fs的append操作
2.向流對(duì)象寫數(shù)據(jù)
3.關(guān)閉流對(duì)象
并行復(fù)制
distcp(分布式復(fù)制)是用于大規(guī)模集群內(nèi)部和集群之間復(fù)制的工具。它使用MapReduce實(shí)現(xiàn)文件分發(fā)、錯(cuò)誤處理和恢復(fù),以及報(bào)告生成。它把文件和目錄的列表作為Map任務(wù)的輸入,每個(gè)任務(wù)會(huì)完成源列表中部分文件的復(fù)制
操作命令:
hadoop distcp -overwrite -delete -i dir1 dir2
參數(shù)如下:
-delete:刪除已經(jīng)存在的目標(biāo)文件,不會(huì)刪除源文件。這個(gè)刪除是通過FS Shell實(shí)現(xiàn)的。所以如果垃圾回收機(jī)制啟動(dòng),刪除的目標(biāo)文件會(huì)進(jìn)入trash
-i:忽略失敗.這個(gè)選項(xiàng)會(huì)比默認(rèn)情況提供關(guān)于復(fù)制的更精確的統(tǒng)計(jì),同時(shí)它還將保留失敗復(fù)制操作的日志。這些日志信息可以用于調(diào)試
-overwrite:覆蓋目標(biāo)。如果一個(gè)Map失敗并且沒有使用-i選項(xiàng),那些復(fù)制失敗的文件,以及這個(gè)分塊任務(wù)中的所有文件都會(huì)被重新復(fù)制
升級(jí)與回滾
Hadoop升級(jí)分為兩種:
一種是集群布局不發(fā)生任何變化的,這種升級(jí)非常簡單,類似安裝一次新的Hadoop程序。
另外一種是集群布局發(fā)送變化的
兩種升級(jí)升級(jí)都簡單分為以下幾步:
1.在執(zhí)行新一輪的升級(jí)前,要確保前一次升級(jí)已經(jīng)完成
hadoop dfsadmin -upgradeProgress status
2.進(jìn)行數(shù)據(jù)的備份,以方便升級(jí)后對(duì)照,如果有問題可發(fā)現(xiàn)然后回滾版本
hadoop fs -lsr / > ~/namenode.log
hadoop fsck / >> ~/namenode.log
cp -r ${dfs.name.dir} ~/namenode_backup
3.使用stop-all.sh關(guān)閉hadoop集群
4.把${dfs.name.dir}目錄下的所有內(nèi)容復(fù)制到新配置的路徑下,這是集群布局有變化的操作,如果沒有新配置布局就不用這個(gè)操作了,單獨(dú)啟動(dòng)新的主節(jié)點(diǎn)NameNode的hdfs進(jìn)行更新操作
${NEW_HADOOP}/bin/start-dfs.sh -upgrade
使用如下命令進(jìn)行監(jiān)控,查看是否升級(jí)完成
${NEW_HADOOP}/bin/hadoop dfsadmin -upgradeProgress status
5.把新版本的Hadoop程序和配置文件一起分發(fā)給集群里所有的機(jī)器,根據(jù)情況看是不是需要進(jìn)行個(gè)別修改,沒有特別的就不用改了。修改/etc/profile中的Hadoop環(huán)境變量,改成新版本Hadoop的指向?,F(xiàn)在使用啟動(dòng)集群的start-all.sh命令來啟動(dòng)集群就行了
6.使用fs -lsr 和fsck與namenode.log文件進(jìn)行核對(duì)前后信息變化,如果沒有問題,數(shù)據(jù)塊體驗(yàn)也通過,就順利完成升級(jí),這時(shí)需要執(zhí)行如下命令來最終確定升級(jí)完成和清理前版本數(shù)據(jù)
hadoop dfsadmin -finalizeUpgrade
rm -r ~/namenode_backup ~/namenode.log
至此升級(jí)完成,不能再進(jìn)行回滾操作,如果升級(jí)后發(fā)現(xiàn)數(shù)據(jù)不符,可以使用如下命令回滾版本
stop-all.sh
start-dfs.sh -rollback
添加節(jié)點(diǎn)
1.修改host。和普通的DataNode一樣,添加NameNode的IP
2.修改NameNode的配置文件conf/slaves。添加新增節(jié)點(diǎn)的Ip或主機(jī)名
3.在新節(jié)點(diǎn)的機(jī)器上啟動(dòng)服務(wù)
bin/hadoop-daemon.sh start datanode
bin/hadoop-daemon.sh start tasktracker
4.均衡Block
bin/start-balancer.sh
為什么要執(zhí)行start-balancer.sh操作呢?
如果不執(zhí)行start-balancer.sh操作.cluster會(huì)把新的數(shù)據(jù)都存放在新的節(jié)點(diǎn)上,這樣會(huì)降低MapReduce的工作效率
執(zhí)行start-balancer.sh操作的優(yōu)化如下
1.設(shè)置平衡閥值,默認(rèn)是10%,值越低各節(jié)點(diǎn)越平衡,但消耗時(shí)間也更長
bin/start-balancer.sh -threshold 5
2.設(shè)置balancer的帶寬,默認(rèn)只有1M/s.編輯hdfs-site.xml文件
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>10485760</value>
</property>
刪除節(jié)點(diǎn)
1.集群配置
修改conf/hdfs-site.xml文件
<property>
<name>dfs.hosts.exclude</name>
<value>/data/soft/hadoop/conf/excludes</value>
</property>
2.確定要下架的機(jī)器
dfs.hosts.exclude定義的文件內(nèi)容為每個(gè)需要下線的機(jī)器,一行一個(gè)。這將阻止它們連接NameNode.
例如/data/soft/hadoop/conf/excludes的內(nèi)容如下:
ubuntu4
這樣就把ubuntu4這臺(tái)設(shè)備從hadoop集群中刪除了。還有一種方法可以實(shí)現(xiàn)ubuntu4設(shè)備從hadoop集群中刪除,配置如下:
<property>
<name>dfs.hosts.exclude</name>
<value>ubuntu4</value>
</property>
3.強(qiáng)制重新加載配置
bin/hadoop dfsadmin -refreshNode
它會(huì)在后臺(tái)進(jìn)行Block塊的移動(dòng)
4.關(guān)閉節(jié)點(diǎn)
bin/hadoop dfsadmin -report
可以查看到現(xiàn)有集群上連接的節(jié)點(diǎn)信息
5.再次編輯excludes文件
一旦完成機(jī)器下架,下架的設(shè)備就可以從excludes文件移除了。登錄要下架的機(jī)器,會(huì)發(fā)現(xiàn)DataNode進(jìn)程沒有了,但是TaskTracker依然存在,需要手動(dòng)關(guān)閉
HDFS權(quán)限管理
hadoop分布式文件系統(tǒng)實(shí)現(xiàn)了一個(gè)和POSIX系統(tǒng)類似的文件和目錄的權(quán)限模型。每個(gè)文件和目錄有一個(gè)所有者(owner)和一個(gè)組(group)
總的來說,文件或目錄的權(quán)限就是它的模式。HDFS采用了UNIX表示和顯示模式的習(xí)慣,包括使用八進(jìn)制數(shù)來表示權(quán)限。當(dāng)新建一個(gè)文件或目錄,所有者即客戶進(jìn)程的用戶,它的所屬組是父目錄的組
HDFS并不提供創(chuàng)建用戶身份、創(chuàng)建組或用戶憑證等功能