分布式文件系統(tǒng):HDFS 核心原理
點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)”

基礎(chǔ)架構(gòu)
HDFS(Hadoop Distributed File System)是 Apache Hadoop 項(xiàng)目的一個(gè)子項(xiàng)目,Hadoop 非常適于存儲(chǔ)大型數(shù)據(jù), 其就是使用 HDFS 作為存儲(chǔ)系統(tǒng),而HDFS 使用多臺(tái)計(jì)算機(jī)存儲(chǔ)文件,并且提供統(tǒng)一的訪問接口,像是訪問一個(gè)普通文件系統(tǒng)一樣使用分布式文件系統(tǒng)。作為大數(shù)據(jù)生態(tài)最重要的組件之一,HDFS充當(dāng)著大數(shù)據(jù)時(shí)代的數(shù)據(jù)管理者的角色,為各種分布式計(jì)算組件提供用于處理的數(shù)據(jù)存儲(chǔ)的能力。
HDFS 基礎(chǔ)架構(gòu)由四個(gè)角色組成:HDFS Client、NameNode、DataNode 和 SecondaryNameNode。

HDFS Client
HDFS客戶端提交讀寫命令到HDFS,它負(fù)責(zé):
?文件切分:文件上傳 HDFS的時(shí)候,Client 將文件切分成一個(gè)個(gè)Block(數(shù)據(jù)塊),然后進(jìn)行存儲(chǔ)。?與NameNode 交互:獲取文件真實(shí)的位置信息。?與DataNode 交互:讀取或?qū)懭霐?shù)據(jù)。?Client 提供一些命令來管理 和訪問HDFS,比如啟動(dòng)或者關(guān)閉HDFS。
NameNode和DataNode
NameNode 是HDFS的Master節(jié)點(diǎn),它負(fù)責(zé):
?管理 HDFS 的名稱空間?管理數(shù)據(jù)塊(Block)映射信息?配置副本策略?處理客戶端讀寫請(qǐng)求?周期性的接收心跳和塊的狀態(tài)信息報(bào)告
DataNode 是HDFS的Slave節(jié)點(diǎn),它負(fù)責(zé):
?存儲(chǔ)實(shí)際的數(shù)據(jù)塊?執(zhí)行數(shù)據(jù)塊的讀/寫操作?周期性向NameNode匯報(bào)心跳信息?周期性向NameNode匯報(bào)數(shù)據(jù)塊信息?周期性向NameNode匯報(bào)緩存數(shù)據(jù)塊信息

fsimage和edits
在Hadoop集群當(dāng)中,NameNode的所有元數(shù)據(jù)信息都保存在fsimage 與 edits 文件中, 這兩個(gè)文件記錄了所有的數(shù)據(jù)的元數(shù)據(jù)信息,當(dāng)集群重啟時(shí)NameNode首先會(huì)從fsimage和edits文件中將元數(shù)據(jù)信息加載到內(nèi)存中,因此NameNode機(jī)器對(duì)內(nèi)存的要求相對(duì)會(huì)比DataNode高很多,元數(shù)據(jù)信息的保存目錄配置在了 hdfs-site.xml 中的這兩個(gè)參數(shù):dfs.namenode.name.dir,dfs.namenode.edits.dir。
edits
?存放了客戶端最近一段時(shí)間的操作日志?客戶端對(duì) HDFS 進(jìn)行寫文件時(shí)的操作會(huì)先被記錄在 edits 文件中?edits 修改時(shí)元數(shù)據(jù)也會(huì)更新
fsimage
?NameNode 中關(guān)于元數(shù)據(jù)的鏡像,一般稱為檢查點(diǎn),fsimage 存放了一份比較完整的元數(shù)據(jù)信息?因?yàn)?fsimage 是 NameNode 的完整的鏡像, 如果每次都加載到內(nèi)存生成樹狀拓?fù)浣Y(jié)構(gòu),這是非常耗內(nèi)存和CPU, 所以一般開始時(shí)對(duì)NameNode 的操作都放在 edits 中?fsimage 內(nèi)包含了 NameNode 管理下的所有 DataNode 文件和文件 block 以及 block所在的 DataNode 的元數(shù)據(jù)信息?隨著 edits 內(nèi)容增大,就需要在一定策略下和 fsimage 合并
由于集群重啟時(shí)NameNode會(huì)重新加載fsimage和edits文件,fsimage文件加載起來很快,但edits文件內(nèi)記錄的都是操作日志,因此edits文件不能無限增長(zhǎng),否則重放日志很慢,會(huì)影響到集群?jiǎn)?dòng)的速度,因此edits文件和fsimage會(huì)定期進(jìn)行合并。
SecondaryNameNode
SecondaryNameNode不是NameNode 的熱備。當(dāng)NameNode 掛掉的時(shí)候,它并不能馬上替換 NameNode 并提供服務(wù),而是作為一個(gè)輔助者分擔(dān)NameNode的工作量。在后面的內(nèi)容中介紹的HDFS的高可用中會(huì)介紹真正的NameNode熱備機(jī)制。
?定期合并 fsimage和edits,并推送給NameNode,把 edits 控制在一個(gè)范圍內(nèi)?在緊急情況下,可輔助恢復(fù) NameNode
上面提到edits文件會(huì)根據(jù)一定策略和fsimage合并,主要由core-site.xml文件中的兩個(gè)參數(shù)來管理:
<property>?<name>fs.checkpoint.periodname>?<value>3600value>property><property>?<name>fs.checkpoint.sizename>?<value>67108864value>property>

當(dāng)edits和fsimage文件合并策略觸發(fā)時(shí),合并流程如下:
1.SNN(SecondaryNameNode)通知NN(NameNode)暫時(shí)切換將日志寫到edits.new內(nèi)2.SNN通過GET請(qǐng)求將NN中的edits和fsimage文件加載到內(nèi)存中3.SNN將內(nèi)存中的edits和fsimage合并生成新的fsimage.ckpt文件4.SNN通過POST請(qǐng)求將生成的fsimage.ckpt文件傳給NN5.NN將收到的fsimage.ckpt替換舊的fsimage文件6.NN將edits.new替換舊的edits文件
高可用架構(gòu)
JournalNode
上面我們介紹的都是HDFS的基礎(chǔ)架構(gòu),從上面的內(nèi)容中我們也可以看出,NameNode對(duì)于HDFS很重要,整個(gè)HDFS文件系統(tǒng)的元數(shù)據(jù)信息都由NameNode來管理,NameNode的可用性直接決定了Hadoop 的可用性,一旦NameNode進(jìn)程不能工作了,就會(huì)影響整個(gè)集群的正常使用。因此在Hadoop2.x版本中加入了HDFS HA的特性,在典型的HA集群中,兩臺(tái)獨(dú)立的機(jī)器被配置為NameNode。在工作集群中,NameNode機(jī)器中的一個(gè)處于Active狀態(tài),另一個(gè)處于Standby狀態(tài)。Active NameNode負(fù)責(zé)群集中的所有客戶端 操作,而Standby充當(dāng)從服務(wù)器,Standby機(jī)器保持足夠的狀態(tài)以提供快速故障切換。
兩個(gè)NameNode為了數(shù)據(jù)同步,會(huì)通過一組稱作JournalNodes的獨(dú)立進(jìn)程進(jìn)行相互通信。當(dāng)Active 狀態(tài)的NameNode的命名空間有任何修改時(shí),會(huì)告知大部分的JournalNodes進(jìn)程。Standby 狀態(tài)的NameNode有能力讀取JNs中的變更信息,并且一直監(jiān)控edit log的變化,把變化應(yīng)用于自己的命名空間。Standby 可以確保在集群出錯(cuò)時(shí),命名空間狀態(tài)已經(jīng)完全同步了 ,以此達(dá)到快速故障切換。
在HA架構(gòu)下,SecondaryNameNode被JournalNode替代,實(shí)現(xiàn)兩個(gè)NameNode之間的信息同步,由Zookeeper實(shí)現(xiàn)兩個(gè)NameNode之間的高可用,相關(guān)的組件如下:
?ZKFailoverController
是基于Zookeeper的故障轉(zhuǎn)移控制器,它負(fù)責(zé)控制NameNode的主備切換,ZKFailoverController會(huì)監(jiān)測(cè)NameNode的健康狀態(tài),當(dāng)發(fā)現(xiàn)Active NameNode出現(xiàn)異常時(shí)會(huì)通過Zookeeper進(jìn)行一次新的選舉,完成Active和Standby狀態(tài)的切換
?HealthMonitor
周期性調(diào)用NameNode的HAServiceProtocol RPC接口(monitorHealth 和 getServiceStatus),監(jiān)控NameNode的健康狀態(tài)并向ZKFailoverController反饋;
?ActiveStandbyElector
接收ZKFC的選舉請(qǐng)求,通過Zookeeper自動(dòng)完成主備選舉,選舉完成后回調(diào)ZKFailoverController的主備切換方法對(duì)NameNode進(jìn)行Active和Standby狀態(tài)的切換;
?DataNode
NameNode包含了HDFS的元數(shù)據(jù)信息和數(shù)據(jù)塊信息(blockmap),為了確??焖偾袚Q,Standby 狀態(tài)的NameNode有必要知道集群中所有數(shù)據(jù)塊的位置。為了做到這點(diǎn),所有的DataNode必須配置兩個(gè)NameNode的地址,同時(shí)發(fā)送數(shù)據(jù)塊位置信息和心跳給他們兩個(gè)。
?共享存儲(chǔ)系統(tǒng)(JournalNode)
共享存儲(chǔ)系統(tǒng)負(fù)責(zé)存儲(chǔ)HDFS的元數(shù)據(jù)(EditsLog),Active NameNode(寫入)和 Standby NameNode(讀取)通過共享存儲(chǔ)系統(tǒng)實(shí)現(xiàn)元數(shù)據(jù)同步,在主備切換過程中,新的Active NameNode必須確保元數(shù)據(jù)同步完成才能對(duì)外提供服務(wù);對(duì)于HA集群而言,確保同一時(shí)刻只有一個(gè)NameNode處于active狀態(tài)是至關(guān)重要的。否則,兩個(gè)NameNode的數(shù)據(jù)狀態(tài)就會(huì)產(chǎn)生分歧,可能丟失數(shù)據(jù),或者產(chǎn)生錯(cuò)誤的結(jié)果。為了保證這點(diǎn),JNs必須確保同一時(shí)刻只有一個(gè)NameNode可以向自己寫數(shù)據(jù)。

Hadoop3.x版本中的新特性允許2個(gè)以上的NameNode節(jié)點(diǎn),該功能能夠通過運(yùn)行更多Standby NameNode來提供更高的容錯(cuò)性,滿足一些部署的需求。比如,通過配置3個(gè)NameNode和5個(gè)JournalNode,集群能夠滿足允許兩個(gè)節(jié)點(diǎn)故障的容錯(cuò)。
聯(lián)邦機(jī)制
雖然HA模式保證了NameNode的高可用,但HDFS中其實(shí)最嚴(yán)重的問題就是小文件過多導(dǎo)致的NameNode維護(hù)的元數(shù)據(jù)信息過多,由此引起的性能下降的問題,因此無論在MapReduce還是Spark程序中都應(yīng)當(dāng)盡量避免產(chǎn)生過多小文件。同時(shí)HDFS也推出了NameNode的水平擴(kuò)展方案:聯(lián)邦機(jī)制(Federation)。
HDFS聯(lián)邦機(jī)制表示有多個(gè)NameNode,但和HA模式下的多個(gè)NameNode的意思不同,在HA模式下的NameNode是主備的概念,而聯(lián)邦機(jī)制中的多NameNode類似分管,表示某個(gè)NameNode管理某塊命名空間(namespace)內(nèi)的元數(shù)據(jù)信息,將本來大量的元數(shù)據(jù)信息分散在多個(gè)NameNode上進(jìn)行管理,它們之間相互獨(dú)立不需要互相協(xié)助,各自分工,管理自己的區(qū)域。

同一個(gè)namespace下的block集合被稱為Block Pool(存儲(chǔ)池),因此在聯(lián)邦機(jī)制下,每個(gè)NameNode對(duì)應(yīng)一個(gè)Block Pool,對(duì)應(yīng)到DataNode中就是一個(gè)個(gè)的Block Pool,分別有對(duì)應(yīng)的ID,這時(shí)候在DataNode上就不僅僅存儲(chǔ)一個(gè)Block Pool下的數(shù)據(jù)了,而是多個(gè),且存儲(chǔ)在DataNode的datadir路徑里的名為BP-xx.xx的目錄。
聯(lián)邦機(jī)制的好處是,多個(gè)NameNode共有一個(gè)集群里的存儲(chǔ)資源,且每個(gè)NameNode都可以單獨(dú)對(duì)外提供服務(wù),解決了單個(gè)Active NameNode的內(nèi)存瓶頸問題。但聯(lián)邦還是沒有解決單點(diǎn)故障的問題,假如維護(hù)namespace為BP-003的NameNode宕機(jī),則客戶端也無法讀取DataNode中的/BP-003的數(shù)據(jù),因此當(dāng)集群規(guī)模較大的時(shí)候,應(yīng)采用HA+Federation的部署方案,即上圖中每個(gè)Active NameNode都對(duì)應(yīng)了一個(gè)Standby NameNode提升可用性。
副本機(jī)制
HDFS中的文件以Block塊的形式存儲(chǔ)在HDFS文件系統(tǒng)中,目的為:
?一個(gè)文件有可能大于集群中任意一個(gè)磁盤,引入塊機(jī)制,可以很好的解決這個(gè)問題?使用塊作為文件存儲(chǔ)的邏輯單位可以簡(jiǎn)化存儲(chǔ)子系統(tǒng)?塊非常適合用于數(shù)據(jù)備份,提供數(shù)據(jù)容錯(cuò)能力
在Hadoop1.x當(dāng)中, 文件的 block 塊默認(rèn)大小是 64M,在Hadoop2.x中, 文件的 block 塊大小默認(rèn)是128M, block 塊的大小和副本數(shù)量可以通過 hdfs-site.xml 當(dāng)中的配置文件進(jìn)行指定:
<property>? ?<name>dfs.block.sizename>? ?<value>134217728value>property><property><name>dfs.replicationname><value>3value>property>
注意:
?當(dāng)文件大于配置的塊大小時(shí)會(huì)被拆分,如130M的文件會(huì)被拆分為兩個(gè)塊,一個(gè)128M另一個(gè)2M。?當(dāng)文件小于配置的塊大小時(shí)不會(huì)拆分,如100M的文件不會(huì)拆分,只有一個(gè)100M的塊。
機(jī)架感知
分布式的集群通常包含非常多的機(jī)器,由于受到機(jī)架槽位和交換機(jī)網(wǎng)口的限制,通常大型的分布式集群都會(huì)跨好幾個(gè)機(jī)架,由多個(gè)機(jī)架上的機(jī)器共同組成一個(gè)分布式集群。機(jī)架內(nèi)的機(jī)器之間的網(wǎng)絡(luò)速度通常都會(huì)高于跨機(jī)架機(jī)器之間的網(wǎng)絡(luò)速度,并且機(jī)架之間機(jī)器的網(wǎng)絡(luò)通信通常受到上層交換機(jī)間網(wǎng)絡(luò)帶寬的限制。
Hadoop在設(shè)計(jì)時(shí)考慮到數(shù)據(jù)的安全與高效,數(shù)據(jù)文件默認(rèn)在HDFS上存放三份,存儲(chǔ)策略為:
?第一個(gè)block副本放在客戶端所在的數(shù)據(jù)節(jié)點(diǎn)里(如果客戶端不在集群范圍內(nèi),則從整個(gè)集群中隨機(jī)選擇一個(gè)合適的數(shù)據(jù)節(jié)點(diǎn)來存放)?第二個(gè)副本放置在與第一個(gè)副本所在節(jié)點(diǎn)不同的機(jī)架內(nèi)的數(shù)據(jù)節(jié)點(diǎn)上(隨機(jī)選擇)?第三個(gè)副本放置在不同機(jī)架的節(jié)點(diǎn)上?如果還有其他副本,則隨機(jī)放在其他節(jié)點(diǎn)上
這樣設(shè)計(jì)的好處是:
當(dāng)本地?cái)?shù)據(jù)損壞時(shí),節(jié)點(diǎn)可以從同一機(jī)架內(nèi)的相鄰節(jié)點(diǎn)拿到數(shù)據(jù),速度肯定比從跨機(jī)架節(jié)點(diǎn)上拿數(shù)據(jù)要快;當(dāng)整個(gè)機(jī)架的網(wǎng)絡(luò)出現(xiàn)異常,也能保證在其它機(jī)架的節(jié)點(diǎn)上找到數(shù)據(jù)。

為了降低整體的帶寬消耗和讀取延時(shí),HDFS會(huì)盡量讓程序讀取離它最近的節(jié)點(diǎn)上的副本,以節(jié)約帶寬和提升性能。HDFS通過機(jī)架感知這一特性實(shí)現(xiàn)此功能。
在默認(rèn)情況下,機(jī)架感知沒有被啟用,所有的機(jī)器hadoop都默認(rèn)在同一個(gè)默認(rèn)的機(jī)架下,名為 “/default-rack”,這種情況下,任何一臺(tái)datanode機(jī)器,不管物理上是否屬于同一個(gè)機(jī)架,都會(huì)被認(rèn)為是在同一個(gè)機(jī)架下,此時(shí),就很容易出現(xiàn)增添機(jī)架間網(wǎng)絡(luò)負(fù)載的情況。因?yàn)榇藭r(shí)hadoop集群的HDFS在選機(jī)器的時(shí)候,是隨機(jī)選擇的,也就是說,很有可能由于副本的隨機(jī)分配導(dǎo)致大量的網(wǎng)絡(luò)傳輸從而影響性能和集群的服務(wù)。
通過修改配置文件core-site.xml 中的參數(shù) topology.script.file.name 開啟機(jī)架感知,value指定為一個(gè)可執(zhí)行程序,通常為一個(gè)腳本(根據(jù)入?yún)P返回該IP地址對(duì)應(yīng)的datanode所在的rack)。
例:網(wǎng)絡(luò)拓?fù)淙缦聢D:

開啟機(jī)架感知后,NameNode就可以畫出上圖所示的datanode網(wǎng)絡(luò)拓?fù)鋱D。D1,R1都是交換機(jī),最底層是datanode。則H1的rackid=/D1/R1/H1,H1的parent是R1,R1的parent是D1。有了這些rackid信息就可以計(jì)算出任意兩臺(tái)datanode之間的距離。
distance(/D1/R1/H1,/D1/R1/H1)=0 相同的datanode
distance(/D1/R1/H1,/D1/R1/H2)=2 同一rack下的不同datanode
distance(/D1/R1/H1,/D1/R1/H4)=4 同一IDC下的不同datanode
distance(/D1/R1/H1,/D2/R3/H7)=6 不同IDC下的datanode
安全模式
安全模式是hadoop的一種保護(hù)機(jī)制,用于保證集群中的數(shù)據(jù)塊的安全性。當(dāng)集群?jiǎn)?dòng)的時(shí)候,會(huì)首先進(jìn)入安全模式,當(dāng)系統(tǒng)處于安全模式時(shí)會(huì)檢查數(shù)據(jù)塊的完整性。
假設(shè)我們?cè)O(shè)置的副本數(shù)(即參數(shù)dfs.replication)是5,那么在datanode上就應(yīng)該有5個(gè)副本存在,假設(shè)只存在3個(gè)副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定義了一個(gè)最小的副本的副本率0.999,我們的副本率0.6明顯小于0.99,因此系統(tǒng)會(huì)自動(dòng)的復(fù)制副本到其他的dataNode,使得副本率不小于0.999.如果系統(tǒng)中有8個(gè)副本,超過我們?cè)O(shè)定的5個(gè)副本,那么系統(tǒng)也會(huì)刪除多余的3個(gè)副本。
在安全模式下,系統(tǒng)會(huì)處于只讀狀態(tài),NameNode不會(huì)處理任何數(shù)據(jù)塊的復(fù)制和刪除命令。DataNode會(huì)向NameNode上傳他們數(shù)據(jù)塊的列表,讓NameNode得到數(shù)據(jù)塊的位置信息,并對(duì)每個(gè)文件對(duì)應(yīng)的數(shù)據(jù)塊副本進(jìn)行統(tǒng)計(jì):
?當(dāng)最小副本條件滿足時(shí),即:一定比例的數(shù)據(jù)塊都到達(dá)最小副本數(shù),系統(tǒng)會(huì)在30s后退出安全模式。?當(dāng)最小的副本條件未達(dá)到要求時(shí),就會(huì)對(duì)副本數(shù)不足的數(shù)據(jù)塊安排DataNode進(jìn)行復(fù)制,直到達(dá)到最小的副本數(shù)。
注意:在啟動(dòng)一個(gè)剛剛格式化的HDFS時(shí)由于沒有數(shù)據(jù)塊,所以系統(tǒng)不會(huì)進(jìn)入安全模式。
HDFS安全模式操作命令:
hdfs dfsadmin ?-safemode ?get #查看安全模式狀態(tài)
hdfs dfsadmin ?-safemode enter #進(jìn)入安全模式
hdfs dfsadmin ?-safemode leave #離開安全模式
安全模式相關(guān)參數(shù)在hdfs-site.xml 文件中配置:
<property>? ?<name>dfs.namenode.safemode.threshold-pctname>? ?<value>0.999fvalue>property><property><name>dfs.namenode.safemode.extensionname><value>30000value>property>
如果 NameNode 長(zhǎng)時(shí)間處于安全模式,可能是因?yàn)?hdfs 的數(shù)據(jù)損壞過多。使用命令hadoop fsck / 檢查 hdfs 文件分布的情況。
平衡策略
在HDFS的DN節(jié)點(diǎn)間的數(shù)據(jù)不平衡情況下,尤其在新增和下架節(jié)點(diǎn)、或者人為干預(yù)副本數(shù)量的時(shí)候,會(huì)大大的影響數(shù)據(jù)讀取的性能,降低任務(wù)的執(zhí)行速度甚至崩潰,因此HDFS有一個(gè)組件叫做Balancer,使用該組件可以保證每個(gè)節(jié)點(diǎn)的數(shù)據(jù)均衡分布。
#開始數(shù)據(jù)平衡:#用默認(rèn)的10%的閾值啟動(dòng)balancerstart-balancer.sh#或指定3%的閾值啟動(dòng)balancerhdfs dfs balancer -threshold 3start-balancer.sh -threshold 3#停止數(shù)據(jù)平衡:stop-balancer.shhdfs balancer[-threshold] [-policy <policy>][-exclude [-f <hosts-file> |list of hosts>]][-include [-f <hosts-file> |list of hosts>]][-idleiterations] -threshold 10 #集群平衡的條件,datanode間磁盤使用率相差閾值,區(qū)間選擇:0~100。Threshold參數(shù)為集群是否處于均衡狀態(tài)設(shè)置了一個(gè)目標(biāo)-policy datanode #默認(rèn)為datanode,datanode級(jí)別的平衡策略-exclude -f /tmp/ip1.txt #默認(rèn)為空,指定該部分ip不參與balance, -f:指定輸入為文件-include -f /tmp/ip2.txt #默認(rèn)為空,只允許該部分ip參與balance,-f:指定輸入為文件-idleiterations 5 #最大迭代次數(shù),默認(rèn)為 5
可選的配置參數(shù)如下:
#并行移動(dòng)的block數(shù)量,默認(rèn)5
dfs.datanode.balance.max.concurrent.moves
#Balance工具所占用的帶寬,默認(rèn)1048576(1MB)
dfs.datanode.balance.bandwidthPerSec
#用于執(zhí)行block移動(dòng)的線程池大小,默認(rèn)1000
dfs.balancer.moverThreads
#每次balance進(jìn)行迭代的過程最大移動(dòng)數(shù)據(jù)量,默認(rèn)10737418240(10GB)
dfs.balancer.max-size-to-move
#獲取block的數(shù)量,默認(rèn)2147483648(2GB)
dfs.balancer.getBlocks.size
#用來平衡的最小block大小,默認(rèn)10485760(10MB)
dfs.balancer.getBlocks.minblock-size
平衡算法根據(jù)各Datanode的使用情況,將集群中的節(jié)點(diǎn)分為四類:過度閑置、平均值以下、平均值以上、過度使用。

然后根據(jù)劃分的角色進(jìn)行配對(duì):
?過度使用--> 過度閑置?過度使用-->平均值下?平均值上-->過度閑置
為了保證HDFS數(shù)據(jù)安全性,數(shù)據(jù)塊移動(dòng)策略如下:
?源DataNode的存儲(chǔ)類型和目的DataNode的存儲(chǔ)類型一致?該block的副本未被安排?目的DataNode不包含同樣的副本?移動(dòng)之后該機(jī)架上的block不會(huì)減少
根據(jù)角色配對(duì)以及移動(dòng)策略,Balancer數(shù)據(jù)均衡流程為:
?與NameNode交互,獲取DataNode磁盤使用情況;?根據(jù)數(shù)據(jù)分布情況對(duì)DataNode進(jìn)行角色劃分并配對(duì);?根據(jù)移動(dòng)策略從源DataNode移動(dòng)block到目標(biāo)DataNode,并刪除源DataNode上的block;?獲取移動(dòng)結(jié)果,并繼續(xù)移動(dòng)其他數(shù)據(jù)塊,直到?jīng)]有數(shù)據(jù)可以移動(dòng)或者HDFS集群以及達(dá)到了平衡的標(biāo)準(zhǔn)為止,然后NameNode提交更新后的DataNode信息;
當(dāng)觸發(fā)下面的條件時(shí),Balancer會(huì)自動(dòng)退出:
?集群已達(dá)到均衡狀態(tài);?沒有block能被移動(dòng);?連續(xù)5次(參數(shù):idleiterations) 迭代移動(dòng)沒有任何一個(gè)block被移動(dòng);?當(dāng)與NameNode交互時(shí)出現(xiàn)了IOException;?另一個(gè)Balancer進(jìn)程在運(yùn)行中。
讀寫原理
讀原理

客戶端向HDFS發(fā)送讀取文件的請(qǐng)求完整流程如下:
?客戶端向NN提交讀請(qǐng)求;?NN進(jìn)行權(quán)限檢查、獲取文件塊列表:{blk_a_1: dn1,dn2,dn4 ;blk_a_2: dn2,dn3,dn4}?NN根據(jù)機(jī)架感知將距離客戶端最近的文件塊所在的DN列表返回給客戶端:{blk_a_1:dn1, blk_a_2:dn2}?客戶端和每個(gè)block所在的DN建立管道;?客戶端讀取數(shù)據(jù),以數(shù)據(jù)包packet(64k)進(jìn)行傳輸;?客戶端將接收到的block合并為一個(gè)完整的文件;
NameNode會(huì)視情況返回文件的部分或者全部block列表,對(duì)于每個(gè)block,NameNode 都會(huì)返回含有該 block 副本的 DataNode 地址;這些返回的 DN 地址,會(huì)按照集群拓?fù)浣Y(jié)構(gòu)得出 DataNode 與客戶端的距離,然后進(jìn)行排序,排序兩個(gè)規(guī)則:網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)內(nèi)距離Client 近的排靠前;心跳機(jī)制中超時(shí)匯報(bào)的 DN 狀態(tài)為 STALE,這樣的排靠后;以此來提升網(wǎng)絡(luò)傳輸?shù)男省?/p>
客戶端選取排序靠前的 DataNode 來讀取 block,如果客戶端本身就是DataNode,那么將從本地直接獲取數(shù)據(jù)(短路讀取)。
每讀取完一個(gè) block 都會(huì)進(jìn)行 checksum 驗(yàn)證,如果讀取 DataNode 時(shí)出現(xiàn)錯(cuò)誤,客戶端會(huì)通知 NameNode,然后再從下一個(gè)擁有該block 副本的DataNode 繼續(xù)讀。
寫原理

客戶端向HDFS發(fā)送上傳文件的請(qǐng)求完整流程如下:
1.客戶端向NameNode提交寫請(qǐng)求;2.NN進(jìn)行權(quán)限檢查、判斷是否滿足寫條件;3.NN返回信息:可以上傳;并將寫操作記錄在edits日志內(nèi)。4.客戶端根據(jù)HDFS的塊策略將文件切分為n個(gè)block文件塊;5.請(qǐng)求上傳第一個(gè)文件塊blk_a_1;6.根據(jù)DN上的block信息和機(jī)架感知,選出可以上傳的DN列表:(dn1,dn2,dn4);7.NN返回可上傳的DN列表(dn1,dn2,dn4);8.客戶端和DN建立數(shù)據(jù)傳輸管道,上傳的DN之間也建立管道;9.客戶端向DN以數(shù)據(jù)包packet(64k)傳遞數(shù)據(jù),dn1收到一個(gè)packet會(huì)傳給dn2,dn2收到會(huì)傳給dn4,每傳一個(gè)packet會(huì)放入一個(gè)應(yīng)答隊(duì)列等待應(yīng)答;10.DN將收到的packet數(shù)據(jù)包進(jìn)行緩存;11.在管道的反方向上, DN逐個(gè)發(fā)送 ack(命令正確應(yīng)答), 最終由管道中第一個(gè)DN節(jié)點(diǎn)dn1將ack發(fā)送給客戶端;12.當(dāng)文件塊block的packet傳輸完成則將緩存的臨時(shí)文件放置在指定的HDFS上傳路徑;13.繼續(xù)上傳其余的block文件塊;14.所有block上傳完畢后返回完成信號(hào)給NN;
刪除恢復(fù)機(jī)制
當(dāng)從HDFS中刪除某個(gè)文件時(shí),這個(gè)文件并不會(huì)立刻從HDFS中刪除,而是將這個(gè)文件重命名并轉(zhuǎn)移到回收站 /trash目錄,只要這個(gè)文件還在/trash目錄下,該文件就可以迅速被恢復(fù)?;厥照镜奈恢迷贖DFS上的/user/$USER/.Trash/Current/
文件在/trash目錄中存放的時(shí)間默認(rèn)為6個(gè)小時(shí),當(dāng)超過這個(gè)時(shí)間時(shí),NN就會(huì)將文件從名稱空間中刪除;
刪除文件會(huì)使得該文件相關(guān)的數(shù)據(jù)塊被釋放;注意:從用戶刪除文件到HDFS空閑空間的增加之間會(huì)有一定時(shí)間的延遲;
通過修改hdfs-site.xml文件中下面的配置可以修改回收站過期的時(shí)間:
#時(shí)間單位是秒<property><name>fs.trash.intervalname><value>1440value>property>

版權(quán)聲明:
文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??




