摘要:助輔助做元數(shù)據(jù)的備份。元數(shù)據(jù)存儲(chǔ)在內(nèi)存和磁盤中,這是因?yàn)榇疟P的讀寫效率較低,而保存到內(nèi)存又有斷電消失的隱患。但磁盤中的元數(shù)據(jù)并不是最新的,內(nèi)存中的元數(shù)據(jù)才是實(shí)時(shí)的。將中的和復(fù)制到自身節(jié)點(diǎn)上并加載進(jìn)內(nèi)存,根據(jù)的記錄操作更改元數(shù)據(jù)信息。
HDFS(Hadoop Distributed File System )
前言:最近正式進(jìn)入了大數(shù)據(jù)框架的學(xué)習(xí)階段,文章來(lái)自個(gè)人OneNote筆記全部手碼,記錄學(xué)習(xí)僅作自勉與交流,如有錯(cuò)誤希望交流指正。
HDFS概念:HDFS是一種用于在普通硬件上運(yùn)行的分布式文件系統(tǒng),提供高度容錯(cuò)的服務(wù),并被設(shè)計(jì)為部署在低成本的硬件上
HDFS適合批量處理,而不是用戶交互使用。重點(diǎn)是高吞吐量的數(shù)據(jù)訪問(wèn),而不是低延遲的數(shù)據(jù)訪問(wèn)。
運(yùn)行在HDFS上的應(yīng)用程序具有較大的數(shù)據(jù)集。因此,HDFS被調(diào)優(yōu)以支持大文件。
HDFS設(shè)計(jì)思想:
分而治之 負(fù)載均衡
??HDFS使用的典型塊大小為128 MB(此處指Hadoop2.X,Hadoop3.X默認(rèn)256M)。盡可能的將每個(gè)塊駐留在不同的DataNode上。將超級(jí)大的文件切分成每一個(gè)小文件(數(shù)據(jù)塊)進(jìn)行存儲(chǔ)在不同的節(jié)點(diǎn)上。同時(shí)切分的數(shù)據(jù)塊太大了,容易造成集群中節(jié)點(diǎn)的存儲(chǔ)的負(fù)載不均衡。太小了會(huì)造成一個(gè)文件切分過(guò)多的塊會(huì)造成NameNode的壓力過(guò)大。
??除了最后一個(gè)塊之外,文件中的所有塊都是相同大小的,如一個(gè)500M的文件被默認(rèn)被切分成4*128M的文件塊,第四塊的大小為500-3×128=116M,每個(gè)block塊都有一個(gè)唯一的塊ID。如果想更改默認(rèn)塊大小可以更改dfs.blocksize屬性。
冗余數(shù)據(jù) 提高容錯(cuò)
??為了解決數(shù)據(jù)丟失的問(wèn)題,hadoop使用空間換取數(shù)據(jù)安全,在hdfs中每一個(gè)數(shù)據(jù)塊都會(huì)進(jìn)行備份存儲(chǔ)。默認(rèn)的情況下每一個(gè)數(shù)據(jù)塊存儲(chǔ)3份。副本之前地位相同沒(méi)有優(yōu)先級(jí),提供服務(wù)時(shí)誰(shuí)有空誰(shuí)服務(wù)。
??應(yīng)用程序可以指定文件的副本數(shù)量。復(fù)制因子(副本的數(shù)量)可以在文件創(chuàng)建時(shí)指定,以后可以更改。由于NameNode不允許DataNodes擁有同一個(gè)block的多個(gè)副本,也就是說(shuō)同一個(gè)節(jié)點(diǎn)的多個(gè)數(shù)據(jù)塊中肯定沒(méi)有相同的。因此創(chuàng)建的副本的最大數(shù)量是當(dāng)時(shí)的DataNodes總數(shù)。
??如果復(fù)制因子大于3,則隨機(jī)確定第4次復(fù)制和后續(xù)復(fù)制的位置,同時(shí)將每個(gè)rack(機(jī)架策略,下面會(huì)寫到) 的副本數(shù)量保持在上限以下(replicas - 1) / racks + 2。如果副本數(shù)量不符合設(shè)置則會(huì)根據(jù)條件自動(dòng)管理,關(guān)系如下:
數(shù)據(jù)副本 < 復(fù)制因子:如果某個(gè)數(shù)據(jù)節(jié)點(diǎn)宕機(jī)導(dǎo)致數(shù)據(jù)副本小于復(fù)制因子則會(huì)復(fù)制此數(shù)據(jù)到另一個(gè)數(shù)據(jù)節(jié)點(diǎn)
數(shù)據(jù)副本>復(fù)制因子:如果因?yàn)樯厦娴那闆r復(fù)制了數(shù)據(jù)之后,之前宕機(jī)的節(jié)點(diǎn)突然恢復(fù)運(yùn)行,此時(shí)副本數(shù)大于復(fù)制因子則會(huì)刪除一個(gè)數(shù)據(jù)節(jié)點(diǎn)中的副本。
復(fù)制因子>DataNodes:如果復(fù)制因子大于數(shù)據(jù)節(jié)點(diǎn)總數(shù)NameNodes,而上面也提到了NameNode不允許單節(jié)點(diǎn)擁有同一個(gè)block的多個(gè)副本,則NameNode對(duì)這個(gè)block進(jìn)行記錄,當(dāng)集群中添加了新的DataNode時(shí)再?gòu)?fù)制補(bǔ)足副本
下圖為副本數(shù)的設(shè)置,可以在hdfs-site.xml文件中設(shè)置,如果不是設(shè)置的話默認(rèn)為3。后續(xù)也可以通過(guò)在集成開(kāi)發(fā)環(huán)境中編寫hdfs-site.xml或使用命令的方式設(shè)置,命令>IDE配置的文件>集群配置文件
HDFS采用一主多從架構(gòu)(Hadoop3.X已經(jīng)支持多個(gè)NameNode)
主:NameNode
存儲(chǔ)塊到DataNodes的映射元數(shù)據(jù)用于管理文件系統(tǒng)命名空間。
執(zhí)行文件系統(tǒng)命名空間操作,比如打開(kāi)、關(guān)閉和重命名文件和目錄。
處理調(diào)節(jié)來(lái)自Client的讀寫請(qǐng)求。
負(fù)責(zé)分配block的存儲(chǔ)節(jié)點(diǎn)。
負(fù)責(zé)負(fù)載均衡。
助:SecondaryNameNode
輔助NameNode做元數(shù)據(jù)的備份、CheckPoint 。
輔助并分擔(dān)NameNode的壓力,當(dāng)NameNode宕機(jī)時(shí)不能主動(dòng)頂替NameNode,但是可以輔助NameNode的恢復(fù)。
從:DataNode
存儲(chǔ)數(shù)據(jù),管理自身節(jié)點(diǎn)的數(shù)據(jù)存儲(chǔ)。
真實(shí)的處理讀寫請(qǐng)求。
按指定周期向NameNode發(fā)送心跳報(bào)告。
元數(shù)據(jù)的概念:NameNode中存儲(chǔ)著元數(shù)據(jù),元數(shù)據(jù)包括(以下D表示存儲(chǔ)于磁盤disk,M表示內(nèi)存memory):
抽象目錄樹(shù)(DM)
數(shù)據(jù)與block的映射關(guān)系(DM)
block存儲(chǔ)的數(shù)據(jù)節(jié)點(diǎn)位置(M)
??元數(shù)據(jù)就像是所有數(shù)據(jù)的目錄一樣,集群?jiǎn)?dòng)時(shí)會(huì)將磁盤中的元數(shù)據(jù)讀取到內(nèi)存,并根據(jù)DataNodes傳遞的心跳報(bào)告記錄block存儲(chǔ)的位置。元數(shù)據(jù)存儲(chǔ)在內(nèi)存和磁盤中,這是因?yàn)榇疟P的讀寫效率較低,而保存到內(nèi)存又有斷電消失的隱患。但磁盤中的元數(shù)據(jù)并不是最新的,內(nèi)存中的元數(shù)據(jù)才是實(shí)時(shí)的。
下圖為NameNode元數(shù)據(jù)目錄下的截圖(路徑是手動(dòng)設(shè)置的,不是默認(rèn)路徑)
其中
edits_XXXXXXXXX-XXXXX 歷史日志文件,記錄了客戶端對(duì)數(shù)據(jù)的操作日志
edits_inprogress_XXXXXXXX 正在編輯的日志文件,記錄了目前對(duì)數(shù)據(jù)的操作
fsimage_xxxxxxxxx 元數(shù)據(jù)的一個(gè)持久化的CheckPoint,包含 Hadoop 文件系統(tǒng)中的所有目錄和文件元數(shù)據(jù)信息,但不包含文件塊位置的信息。該文件是通過(guò)真實(shí)元數(shù)據(jù)序列化的結(jié)果,集群?jiǎn)?dòng)時(shí)對(duì)這些文件進(jìn)行反序列化
seen_txid:合并點(diǎn)記錄文件,用戶對(duì)數(shù)據(jù)進(jìn)行操作時(shí)不直接修改元數(shù)據(jù)而是記錄當(dāng)前操作到日志文件,等集群空閑時(shí)再合并到元數(shù)據(jù)中,而合并點(diǎn)記錄文件中記錄的就是即將要合并的操作(還沒(méi)合并),這個(gè)合并的操作由SecondaryNameNode或指定的CheckPointNode來(lái)完成。
可以通過(guò)hdfs oiv將元數(shù)據(jù)轉(zhuǎn)換為其他格式文件(如XML)來(lái)查看,oev參數(shù)轉(zhuǎn)換日志文件,其中參數(shù)p表示轉(zhuǎn)換,參數(shù) i 表示輸入,參數(shù) o 表示輸出
hdfs oiv -p XML -i fsimage_0000000000000000062 -o fs62.xml hdfs oev -p XML -i edits_0000000000000000046-0000000000000000061 -o edit46.xml
將轉(zhuǎn)換好的文件從Linux下取出到Windows并使用VS Code格式化查看:
可以看到每一步操作都有非常詳細(xì)的記錄,將時(shí)間戳轉(zhuǎn)換為具體時(shí)間即可查看操作時(shí)間
上面提到了元數(shù)據(jù)的合并且由SecondaryNameNode完成(以下簡(jiǎn)稱SNN)
CheckPoint由于磁盤內(nèi)的元數(shù)據(jù)相對(duì)于內(nèi)存中的元數(shù)據(jù)不是實(shí)時(shí)的,那么如何判斷何時(shí)該進(jìn)行元數(shù)據(jù)合并呢?
CheckPoint默認(rèn)觸發(fā)的條件有兩條,任意滿足一條都會(huì)啟動(dòng)CheckPoint
距離上次元數(shù)據(jù)合并時(shí)間超過(guò)1小時(shí)
當(dāng)前產(chǎn)生的操作記錄超過(guò)100W條,此條件每分鐘檢查一次
默認(rèn)CheckPointNode為SNN,那么首先請(qǐng)求開(kāi)始CheckPoint,要求NameNode停止操作edit_inprogress并將后面的操作寫入到一個(gè)新文件中。
SNN將NameNode中的fsimage和edits復(fù)制到自身節(jié)點(diǎn)上并加載進(jìn)內(nèi)存,根據(jù)edits的記錄操作更改元數(shù)據(jù)信息。(在這個(gè)過(guò)程中需要注意的是如果不是第一次進(jìn)行CheckPoint,那么SNN拉取的是合并點(diǎn)記錄文件編號(hào)到最新編輯日志文件中的文件,而不是所有文件)
SNN將合并好的元數(shù)據(jù)信息命名為fsimage.checkpoint并發(fā)送給NameNode,自己也保存一份
NameNode接收文件并將其改名為fsimage替換舊的元數(shù)據(jù)文件
如果在集群沒(méi)有達(dá)到CheckPoint條件的時(shí)候被正常關(guān)閉了,那么內(nèi)存中的完整元數(shù)據(jù)將會(huì)被序列化到磁盤元數(shù)據(jù)文件中。
HDFS四大機(jī)制
心跳機(jī)制:
NameNode如何確認(rèn)DataNode存活?
每個(gè)DataNode定期向NameNode發(fā)送一條心跳消息,心跳報(bào)告間隔默認(rèn)為3S。網(wǎng)絡(luò)分區(qū)可能導(dǎo)致DataNodes的子集與NameNode失去連接,NameNode通過(guò)心跳機(jī)制來(lái)檢測(cè)此情況,如果一個(gè)NameNode連續(xù)10次接收不到dataNode的心跳信息,會(huì)主動(dòng)的對(duì)該DataNode發(fā)送兩次檢查,檢查的時(shí)間默認(rèn)為五分鐘,兩次檢查失敗該DataNode將被標(biāo)記為 死亡 ,并且不會(huì)再向它們發(fā)送任何IO請(qǐng)求。此外,DataNode每小時(shí)還需要向NameNode重新報(bào)告自身所有數(shù)據(jù)信息保證有效性。
已注冊(cè)死亡的DataNode的任何數(shù)據(jù)都不再適用于HDFS。DataNodeDeath可能導(dǎo)致某些塊的復(fù)制因子低于其指定值。NameNode經(jīng)常跟蹤需要復(fù)制的塊,并在必要時(shí)啟動(dòng)復(fù)制。由于許多原因,重新復(fù)制的必要性可能會(huì)出現(xiàn):DataNode可能變得不可用,副本可能被破壞,DataNode上的硬盤可能會(huì)失敗,或者文件的復(fù)制因子可能會(huì)增加。
標(biāo)記DataNodes死亡的超時(shí)時(shí)間是謹(jǐn)慎的(默認(rèn)情況下超過(guò)10分鐘),以避免由DataNodes的狀態(tài)抖動(dòng)引起的復(fù)制風(fēng)暴。用戶可以設(shè)置較短的間隔以將DataNodes標(biāo)記為陳舊的,并通過(guò)配置性能敏感的工作負(fù)載來(lái)避免在讀取和/或?qū)懭霑r(shí)陳舊的節(jié)點(diǎn)。
安全模式
如集群?jiǎn)?dòng)時(shí)就進(jìn)入了安全模式,不允許任何寫操作,此時(shí)發(fā)生了什么?
啟動(dòng)NameNode并將磁盤中的元數(shù)據(jù)文件加載到內(nèi)存建立元數(shù)據(jù),并監(jiān)聽(tīng)DataNode的請(qǐng)求與心跳
啟動(dòng)DataNode并向NameNode發(fā)送心跳報(bào)告以注冊(cè)DataNode的存活狀況及block存儲(chǔ)信息
啟動(dòng)SecondaryNameNode
準(zhǔn)備完畢后只要集群內(nèi)的副本達(dá)到“最小副本條件”——文件系統(tǒng)中的每個(gè)副本數(shù) > 最小副本級(jí)別(默認(rèn)為1),NameNode會(huì)在30S后退出安全模式
此外,用戶也可以手動(dòng)使用命令進(jìn)入和離開(kāi)安全模式
機(jī)架策略
HDFS塊放置將通過(guò)在不同的機(jī)架上放置一個(gè)塊副本來(lái)使用機(jī)架感知實(shí)現(xiàn)容錯(cuò)。這提供了在集群內(nèi)發(fā)生網(wǎng)絡(luò)交換機(jī)故障或分區(qū)時(shí)的數(shù)據(jù)可用性。如默認(rèn)機(jī)架數(shù)為2,復(fù)制因子為3.
第一個(gè)副本一般存儲(chǔ)在客戶端所在的節(jié)點(diǎn)上(如果客戶端是一個(gè)DataNode的話,不是就隨機(jī)一個(gè)節(jié)點(diǎn))
第二個(gè)副本存儲(chǔ)在和第一個(gè)副本不同的機(jī)架上的任意節(jié)點(diǎn)
第三個(gè)副本存儲(chǔ)在和第一個(gè)副本相同機(jī)架不同節(jié)點(diǎn)
負(fù)載均衡
每個(gè)數(shù)據(jù)節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)與其硬件實(shí)力的比例差距不大,沒(méi)有絕對(duì)的均衡。集群規(guī)模較小可以使用默認(rèn)的負(fù)載均衡,規(guī)模較大需要手動(dòng)調(diào)整均衡屬性。自動(dòng)調(diào)整負(fù)載均衡的帶寬,這里設(shè)置的帶寬是指負(fù)載均衡傳輸?shù)乃俾剩易詣?dòng)負(fù)載均衡會(huì)在集群空閑的時(shí)候才啟動(dòng):
dfs.datanode.balance.bandwidthPerSec 1048576 //1M
命令方式手動(dòng)負(fù)載均衡:
start-balancer.sh -t 10% //參數(shù)代表了各個(gè)節(jié)點(diǎn)數(shù)據(jù)占用率差值不超過(guò)10%時(shí)視為負(fù)載均衡
寫操作:
Client通過(guò)Distributed FileSystem向NameNode發(fā)送上傳文件的請(qǐng)求和文件信息
NameNode接收請(qǐng)求并分析文件信息決定是否允許上傳(文件/目錄是否存在,客戶端是否有權(quán)限)
如果NameNode分析同意上傳請(qǐng)求那么根據(jù)節(jié)點(diǎn)距離情況返回復(fù)制因子數(shù)目的數(shù)據(jù)節(jié)點(diǎn)列表信息(前提客戶端是一個(gè)數(shù)據(jù)節(jié)點(diǎn),如果不是則首個(gè)節(jié)點(diǎn)隨機(jī)返回一個(gè))
客戶端接收NameNode的允許響應(yīng)并對(duì)文件進(jìn)行邏輯切分
準(zhǔn)備上傳并構(gòu)建PipeLine,根據(jù)NameNode返回的返回的信息找到第一個(gè)寫入的數(shù)據(jù)節(jié)點(diǎn),客戶端通過(guò)FSDataOutputStream模塊請(qǐng)求dn1上傳數(shù)據(jù),dn1收到請(qǐng)求會(huì)繼續(xù)調(diào)用dn2,然后dn2調(diào)用dn3,將這個(gè)通信管道建立完成。dn3、dn2、dn1逐級(jí)應(yīng)答客戶端。
以packet為單位上傳block(先寫入緩存)到通信管道中的每個(gè)節(jié)點(diǎn)
用傳輸?shù)谝粋€(gè)塊的方式完成其他塊的傳輸
所有塊傳輸完成后Client向NameNode發(fā)送傳輸狀態(tài)信息(成功或失敗)同時(shí)關(guān)閉FsDataOutputStream,NameNode根據(jù)狀態(tài)信息更新元數(shù)據(jù)。
讀操作:
Client通過(guò)Distributed FileSystem向NameNode發(fā)送下載文件請(qǐng)求
NameNode查詢?cè)獢?shù)據(jù),找到并返回文件塊所在的DataNode地址,如果找不到直接拋出異常。
客戶端獲取到block的數(shù)據(jù)節(jié)點(diǎn)會(huì)就近選擇節(jié)點(diǎn)按順序開(kāi)始下載block
每個(gè)block下載完成后會(huì)進(jìn)行checksum驗(yàn)證,如果在某個(gè)DataNode讀取數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤則會(huì)通知NameNode并重新從其他擁有該block副本的DataNode進(jìn)行下載
所有block下載完成后關(guān)閉FsDataOutputStream并由分布式文件系統(tǒng)向NameNode報(bào)告下載情況
關(guān)于HDFS寫操作失敗的結(jié)果網(wǎng)上說(shuō)法不一,等學(xué)習(xí)的深入一些自行驗(yàn)證,這里先記錄我看到的兩種:
說(shuō)法一:如果在這個(gè)過(guò)程中有節(jié)點(diǎn)傳輸失敗HDFS默認(rèn)會(huì)進(jìn)行一次重試,再次失敗則放棄失敗的節(jié)點(diǎn),從通信管道中刪除該節(jié)點(diǎn)并報(bào)告給NameNode,如果傳輸?shù)墓?jié)點(diǎn)全部失敗則重新向NameNode發(fā)起請(qǐng)求并構(gòu)建新的PipeLine,也就是說(shuō)最少需要一個(gè)節(jié)點(diǎn)傳輸完成。未達(dá)到復(fù)制因子數(shù)量則在集群空閑時(shí)復(fù)制副本。
說(shuō)法二:復(fù)制管道中的某一個(gè)DataNode無(wú)法將數(shù)據(jù)寫入磁盤,管道立即關(guān)閉。已發(fā)送的但尚未收到確認(rèn)的數(shù)據(jù)包會(huì)被回退到隊(duì)列中,以確保管道中錯(cuò)誤節(jié)點(diǎn)的下游節(jié)點(diǎn)可以獲得數(shù)據(jù)包。在剩下的健康數(shù)據(jù)節(jié)點(diǎn)中,正在寫入的數(shù)據(jù)塊被分配新的ID。當(dāng)發(fā)生故障的數(shù)據(jù)節(jié)點(diǎn)恢復(fù)后,冗余的數(shù)據(jù)塊貌似不屬于任何文件而自動(dòng)丟棄,由剩余節(jié)點(diǎn)組成的新復(fù)制管道會(huì)重新開(kāi)放,繼續(xù)寫操作直至文件關(guān)閉
NameNode故障處理如果運(yùn)行的過(guò)程中NameNode發(fā)生意外宕機(jī)了,可以使用以下方法進(jìn)行挽救
將SecondaryNameNode中保存的備份數(shù)據(jù)復(fù)制到NameNode中,需要先將NameNode中的數(shù)據(jù)刪除
使用-importCheckpoint啟動(dòng)NameNode守護(hù)進(jìn)程,由hadoop修復(fù)NameNode
那么開(kāi)始動(dòng)手摧殘集群(這里先對(duì)虛擬機(jī)拍了快照)
如圖,啟動(dòng)集群后殺死NameNode進(jìn)程并刪除元數(shù)據(jù)文件夾,再次啟動(dòng)NameNode,此時(shí)請(qǐng)求獲取根目錄文件列表失敗
[root@master hadoop]# jps //查看當(dāng)前集群進(jìn)程 8192 DataNode 8610 Jps 8451 NodeManager 8041 NameNode [root@master hadoop]# kill 8041 //殺死NameNode進(jìn)程 [root@master hadoop]# rm -rf data/tmp/dfs/name/* //刪除元數(shù)據(jù)文件夾 [root@master hadoop]# sbin/hadoop-daemon.sh start namenode //多帶帶啟動(dòng)NameNode starting namenode, logging to /usr/local/Software/hadoop/logs/hadoop-root-namenode-master.out [root@master hadoop]# bin/hadoop fs -ls / //請(qǐng)求文件列表失敗 19/08/04 15:38:25 WARN ipc.Client: Failed to connect to server: master/192.168.35.101:9000: try once and fail. java.net.ConnectException: 拒絕連接
那么現(xiàn)在嘗試恢復(fù)NameNode,將SecondaryNameNode的元數(shù)據(jù)備份復(fù)制到NameNode下,再次嘗試獲取集群中的數(shù)據(jù),成功獲取,至于第二種復(fù)制方法設(shè)置有點(diǎn)麻煩,下次有時(shí)間再補(bǔ)充記錄。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/75772.html
閱讀 1259·2021-09-22 15:18
閱讀 2589·2021-09-22 15:17
閱讀 2218·2019-08-30 15:55
閱讀 1567·2019-08-30 15:54
閱讀 1032·2019-08-30 13:12
閱讀 619·2019-08-30 13:12
閱讀 1673·2019-08-29 11:33
閱讀 1433·2019-08-26 17:04