HDFS(Hadoop Distributed File System)是GFS的開(kāi)源實(shí)現(xiàn)。
HDFS架構(gòu)
HDFS是一個(gè)典型的主/備(Master/Slave)架構(gòu)的分布式系統(tǒng),由一個(gè)名字節(jié)點(diǎn)Namenode(Master) +多個(gè)數(shù)據(jù)節(jié)點(diǎn)Datanode(Slave)組成。其中Namenode提供元數(shù)據(jù)服務(wù),Datanode提供數(shù)據(jù)流服務(wù),用戶通過(guò)HDFS客戶端與Namenode和Datanode交互訪問(wèn)文件系統(tǒng)。
如圖3-1所示HDFS把文件的數(shù)據(jù)劃分為若干個(gè)塊(Block),每個(gè)Block存放在一組Datanode上,Namenode負(fù)責(zé)維護(hù)文件到Block的命名空間映射以及每個(gè)Block到Datanode的數(shù)據(jù)塊映射。
▲圖3-1 HDFS架構(gòu)
HDFS客戶端對(duì)文件系統(tǒng)進(jìn)行操作時(shí),如創(chuàng)建、打開(kāi)、重命名等,Namenode響應(yīng)請(qǐng)求并對(duì)命名空間進(jìn)行變更,再返回相關(guān)數(shù)據(jù)塊映射的Datanode,客戶端按照流協(xié)議完成數(shù)據(jù)的讀寫(xiě)。
- HDFS基本概念
HDFS架構(gòu)比較簡(jiǎn)單,但涉及概念較多,其中幾個(gè)重要的概念如下:
1. 塊(Block)
Block是HDFS文件系統(tǒng)處理的最小單位,一個(gè)文件可以按照Block大小劃分為多個(gè)Block,不同于Linux文件系統(tǒng)中的數(shù)據(jù)塊,HDFS文件通常是超大文件,因此Block大小一般設(shè)置得比較大,默認(rèn)為128MB。
2. 復(fù)制(Replica)
HDFS通過(guò)冗余存儲(chǔ)來(lái)保證數(shù)據(jù)的完整性,即一個(gè)Block會(huì)存放在N個(gè)Datanode中,HDFS客戶端向Namenode申請(qǐng)新Block時(shí),Namenode會(huì)根據(jù)Block分配策略為該Block分配相應(yīng)的Datanode replica,這些Datanode組成一個(gè)流水線(pipeline),數(shù)據(jù)依次串行寫(xiě)入,直至Block寫(xiě)入完成。
3. 名字節(jié)點(diǎn)(Namenode)
Namenode是HDFS文件系統(tǒng)的管理節(jié)點(diǎn),主要負(fù)責(zé)維護(hù)文件系統(tǒng)的命名空間(Namespace)或文件目錄樹(shù)(Tree)和文件數(shù)據(jù)塊映射(BlockMap),以及對(duì)外提供文件服務(wù)。
HDFS文件系統(tǒng)遵循POXIS協(xié)議標(biāo)準(zhǔn),與Linux文件系統(tǒng)類似,采用基于Tree的數(shù)據(jù)結(jié)構(gòu),以INode作為節(jié)點(diǎn),實(shí)現(xiàn)一個(gè)目錄下多個(gè)子目錄和文件。INode是一個(gè)抽象類,表示File/Directory的層次關(guān)系,對(duì)于一個(gè)文件來(lái)說(shuō),INodeFile除了包含基本的文件屬性信息,也包含對(duì)應(yīng)的Block信息。
數(shù)據(jù)塊映射信息則由BlockMap負(fù)責(zé)管理,在Datanode的心跳上報(bào)中,將向Namenode匯報(bào)負(fù)責(zé)存儲(chǔ)的Block列表情況,BlockMap負(fù)責(zé)維護(hù)BlockID到Datanode的映射,以方便文件檢索時(shí)快速找到Block對(duì)應(yīng)的HDFS位置。
HDFS每一步操作都以FSEditLog的信息記錄下來(lái),一旦Namenode發(fā)生宕機(jī)重啟,可以從每一個(gè)FSEditLog還原出HDFS操作以恢復(fù)整個(gè)文件目錄樹(shù),如果HDFS集群發(fā)生過(guò)很多變更操作,整個(gè)過(guò)程將相當(dāng)漫長(zhǎng)。
因此HDFS會(huì)定期將Namenode的元數(shù)據(jù)以FSImage的形式寫(xiě)入文件中,這一操作相當(dāng)于為HDFS元數(shù)據(jù)打了一個(gè)快照,在恢復(fù)時(shí),僅恢復(fù)FSImage之后的FSEditLog即可。
由于Namenode在內(nèi)存中需要存放大量的信息,且恢復(fù)過(guò)程中集群不可用,HDFS提供HA(主/備Namenode實(shí)現(xiàn)故障遷移Failover)以及Federation(多組Namenode提供元數(shù)據(jù)服務(wù),以掛載表的形式對(duì)外提供統(tǒng)一的命名空間)特性以提高穩(wěn)定性和減少元數(shù)據(jù)壓力。
4. Datanode
Datanode是HDFS文件系統(tǒng)的數(shù)據(jù)節(jié)點(diǎn),提供基于Block的本地文件讀寫(xiě)服務(wù)。定期向Namenode發(fā)送心跳。Block在本地文件系統(tǒng)中由數(shù)據(jù)文件及元數(shù)據(jù)文件組成,前者為數(shù)據(jù)本身,后者則記錄Block長(zhǎng)度和校驗(yàn)和(checksum)等信息。掃描或讀取數(shù)據(jù)文件時(shí),HDFS即使運(yùn)行在廉價(jià)的硬件上,也能通過(guò)多副本的能力保證數(shù)據(jù)一致性。
5. FileSystem
HDFS客戶端實(shí)現(xiàn)了標(biāo)準(zhǔn)的Hadoop FileSystem接口,向上層應(yīng)用程序提供了各種各樣的文件操作接口,在內(nèi)部使用了DFSClient等對(duì)象并封裝了較為復(fù)雜的交互邏輯,這些邏輯對(duì)客戶端都是透明的。
HDFS讀寫(xiě)流程
HDFS寫(xiě)流程
寫(xiě)詳細(xì)步驟:
- 客戶端向NameNode發(fā)出寫(xiě)文件請(qǐng)求。
- 檢查是否已存在文件、檢查權(quán)限。若通過(guò)檢查,直接先將操作寫(xiě)入EditLog,并返回輸出流對(duì)象。
(注:WAL,write ahead log,先寫(xiě)Log,再寫(xiě)內(nèi)存,因?yàn)镋ditLog記錄的是最新的HDFS客戶端執(zhí)行所有的寫(xiě)操作。如果后續(xù)真實(shí)寫(xiě)操作失敗了,由于在真實(shí)寫(xiě)操作之前,操作就被寫(xiě)入EditLog中了,故EditLog中仍會(huì)有記錄,我們不用擔(dān)心后續(xù)client讀不到相應(yīng)的數(shù)據(jù)塊,因?yàn)樵诘?步中DataNode收到塊后會(huì)有一返回確認(rèn)信息,若沒(méi)寫(xiě)成功,發(fā)送端沒(méi)收到確認(rèn)信息,會(huì)一直重試,直到成功) - client端按128MB的塊切分文件。
- client將NameNode返回的分配的可寫(xiě)的DataNode列表和Data數(shù)據(jù)一同發(fā)送給最近的第一個(gè)DataNode節(jié)點(diǎn),此后client端和NameNode分配的多個(gè)DataNode構(gòu)成pipeline管道,client端向輸出流對(duì)象中寫(xiě)數(shù)據(jù)。client每向第一個(gè)DataNode寫(xiě)入一個(gè)packet,這個(gè)packet便會(huì)直接在pipeline里傳給第二個(gè)、第三個(gè)…DataNode。
(注:并不是寫(xiě)好一個(gè)塊或一整個(gè)文件后才向后分發(fā)) - 每個(gè)DataNode寫(xiě)完一個(gè)塊后,會(huì)返回確認(rèn)信息。
(注:并不是每寫(xiě)完一個(gè)packet后就返回確認(rèn)信息,個(gè)人覺(jué)得因?yàn)閜acket中的每個(gè)chunk都攜帶校驗(yàn)信息,沒(méi)必要每寫(xiě)一個(gè)就匯報(bào)一下,這樣效率太慢。正確的做法是寫(xiě)完一個(gè)block塊后,對(duì)校驗(yàn)信息進(jìn)行匯總分析,就能得出是否有塊寫(xiě)錯(cuò)的情況發(fā)生) - 寫(xiě)完數(shù)據(jù),關(guān)閉輸輸出流。
- 發(fā)送完成信號(hào)給NameNode。
(注:發(fā)送完成信號(hào)的時(shí)機(jī)取決于集群是強(qiáng)一致性還是最終一致性,強(qiáng)一致性則需要所有DataNode寫(xiě)完后才向NameNode匯報(bào)。最終一致性則其中任意一個(gè)DataNode寫(xiě)完后就能單獨(dú)向NameNode匯報(bào),HDFS一般情況下都是強(qiáng)調(diào)強(qiáng)一致性)
HDFS客戶端寫(xiě)流程詳解
圖3-2所示為客戶端完成HDFS文件寫(xiě)入的主流程。
▲圖3-2 客戶端完成HDFS寫(xiě)入的主流程
1)創(chuàng)建文件并獲得租約
HDFS客戶端通過(guò)調(diào)用DistributedFileSystem# create來(lái)實(shí)現(xiàn)遠(yuǎn)程調(diào)用Namenode提供的創(chuàng)建文件操作,Namenode在指定的路徑下創(chuàng)建一個(gè)空的文件并為該客戶端創(chuàng)建一個(gè)租約(在續(xù)約期內(nèi),將只能由這一個(gè)客戶端寫(xiě)數(shù)據(jù)至該文件),隨后將這個(gè)操作記錄至EditLog(編輯日志)。Namenode返回相應(yīng)的信息后,客戶端將使用這些信息,創(chuàng)建一個(gè)標(biāo)準(zhǔn)的Hadoop FSDataOutputStream輸出流對(duì)象。
2)寫(xiě)入數(shù)據(jù)
HDFS客戶端開(kāi)始向HdfsData-OutputStream寫(xiě)入數(shù)據(jù),由于當(dāng)前沒(méi)有可寫(xiě)的Block,DFSOutputStream根據(jù)副本數(shù)向Namenode申請(qǐng)若干Datanode組成一條流水線來(lái)完成數(shù)據(jù)的寫(xiě)入,如圖3-3所示。
▲圖3-3 流水線數(shù)據(jù)寫(xiě)入示意圖
3)串行寫(xiě)入數(shù)據(jù),直到寫(xiě)完Block
客戶端的數(shù)據(jù)以字節(jié)(byte)流的形式寫(xiě)入chunk(以chunk為單位計(jì)算checksum(校驗(yàn)和))。若干個(gè)chunk組成packet,數(shù)據(jù)以packet的形式從客戶端發(fā)送到第一個(gè)Datanode,再由第一個(gè)Datanode發(fā)送數(shù)據(jù)到第二個(gè)Datanode并完成本地寫(xiě)入,以此類推,直到最后一個(gè)Datanode寫(xiě)入本地成功,可以從緩存中移除數(shù)據(jù)包(packet),如圖3-4所示。
▲圖3-4 串行寫(xiě)入數(shù)據(jù)示意圖
4)重復(fù)步驟2和步驟3,然后寫(xiě)數(shù)據(jù)包和回復(fù)數(shù)據(jù)包,直到數(shù)據(jù)全部寫(xiě)完。
5)關(guān)閉文件并釋放租約
客戶端執(zhí)行關(guān)閉文件后,HDFS客戶端將會(huì)在緩存中的數(shù)據(jù)被發(fā)送完成后遠(yuǎn)程調(diào)用Namenode執(zhí)行文件來(lái)關(guān)閉操作。
Datanode在定期的心跳上報(bào)中,以增量的信息匯報(bào)最新完成寫(xiě)入的Block,Namenode則會(huì)更新相應(yīng)的數(shù)據(jù)塊映射以及在新增Block或關(guān)閉文件時(shí)根據(jù)Block映射副本信息判斷數(shù)據(jù)是否可視為完全持久化(滿足最小備份因子)。
HDFS讀流程
讀詳細(xì)步驟:
- client訪問(wèn)NameNode,查詢?cè)獢?shù)據(jù)信息,獲得這個(gè)文件的數(shù)據(jù)塊位置列表,返回輸入流對(duì)象。
- 就近挑選一臺(tái)datanode服務(wù)器,請(qǐng)求建立輸入流 。
- DataNode向輸入流中中寫(xiě)數(shù)據(jù),以packet為單位來(lái)校驗(yàn)。
- 關(guān)閉輸入流
HDFS客戶端讀流程詳解
相對(duì)于HDFS文件寫(xiě)入流程,HDFS讀流程相對(duì)簡(jiǎn)單,如圖3-5所示。
▲圖3-5 HDFS讀流程
1)HDFS客戶端遠(yuǎn)程調(diào)用Namenode,查詢?cè)獢?shù)據(jù)信息,獲得這個(gè)文件的數(shù)據(jù)塊位置列表,返回封裝DFSIntputStream的HdfsDataInputStream輸入流對(duì)象。
2)客戶端選擇一臺(tái)可用Datanode服務(wù)器,請(qǐng)求建立輸入流。
3)Datanode向輸入流中寫(xiě)原始數(shù)據(jù)和以packet為單位的checksum。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-765537.html
4)客戶端接收數(shù)據(jù)。如遇到異常,跳轉(zhuǎn)至步驟2,直到數(shù)據(jù)全部讀出,而后客戶端關(guān)閉輸入流。當(dāng)客戶端讀取時(shí),可能遇到Datanode或Block異常,導(dǎo)致當(dāng)前讀取失敗。正由于HDFS的多副本保證,DFSIntputStream將會(huì)切換至下一個(gè)Datanode進(jìn)行讀取。與HDFS寫(xiě)入類似,通過(guò)checksum來(lái)保證讀取數(shù)據(jù)的完整性和準(zhǔn)確性。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-765537.html
到了這里,關(guān)于【Hadoop面試】HDFS讀寫(xiě)流程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!