本文大部分內(nèi)容轉(zhuǎn)自初步掌握HDFS的架構(gòu)及原理皮璧,并參考了網(wǎng)易云課堂《大數(shù)據(jù)技術(shù)原理與應(yīng)用》課程Chapter 3的內(nèi)容舟扎。
01?
什么是分布式文件系統(tǒng)?
分布式文件系統(tǒng)(Distributed File System)悴务,簡(jiǎn)單來(lái)說(shuō)睹限,就是把文件分布存儲(chǔ)到多個(gè)計(jì)算機(jī)節(jié)點(diǎn)上,這些節(jié)點(diǎn)可分為以下兩類(lèi):
?主節(jié)點(diǎn) (Master Node)讯檐,或名稱(chēng)結(jié)點(diǎn)(NameNode)
?從節(jié)點(diǎn)(Slave Node)羡疗,或數(shù)據(jù)節(jié)點(diǎn) (DataNode)
節(jié)點(diǎn)之間通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)進(jìn)行連接。
02
什么是HDFS别洪?
HDFS是被設(shè)計(jì)成適合運(yùn)行在通用硬件上的分布式文件系統(tǒng)叨恨,它是Hadoop項(xiàng)目的核心子項(xiàng)目,是分布式計(jì)算中數(shù)據(jù)存儲(chǔ)管理的基礎(chǔ)挖垛。
它和現(xiàn)有的分布式文件系統(tǒng)有很多共同點(diǎn)痒钝。但同時(shí),它和其他的分布式文件系統(tǒng)的區(qū)別也是很明顯的痢毒。它所具有的高容錯(cuò)送矩、高可靠性、高可擴(kuò)展性哪替、高獲得性栋荸、高吞吐率等特征為海量數(shù)據(jù)提供了不怕故障的存儲(chǔ),為超大數(shù)據(jù)集(Large Data Set)的應(yīng)用處理帶來(lái)了很多便利凭舶。
03
為什么使用HDFS晌块?
?高容錯(cuò)性:數(shù)據(jù)自動(dòng)保存多個(gè)副本,提高容錯(cuò)性帅霜,某一個(gè)副本丟失以后匆背,它可以自動(dòng)恢復(fù)。
?適合批處理:它是通過(guò)移動(dòng)計(jì)算而不是移動(dòng)數(shù)據(jù)身冀;它會(huì)把數(shù)據(jù)位置暴露給計(jì)算框架靠汁。
?適合大數(shù)據(jù)處理:處理數(shù)據(jù)達(dá)到 GB蜂大、TB、甚至PB級(jí)別的數(shù)據(jù)蝶怔;能夠處理百萬(wàn)規(guī)模以上的文件數(shù)量奶浦,數(shù)量相當(dāng)之大;能夠處理10K節(jié)點(diǎn)的規(guī)模踢星。
?流式文件訪問(wèn):一次寫(xiě)入澳叉,多次讀取。文件一旦寫(xiě)入不能修改沐悦,只能追加成洗。
?可構(gòu)建在廉價(jià)機(jī)器上:它通過(guò)多副本機(jī)制,提高可靠性藏否。它提供了容錯(cuò)和恢復(fù)機(jī)制瓶殃。比如某一個(gè)副本丟失,可以通過(guò)其它副本來(lái)恢復(fù)副签。
04?
哪些場(chǎng)合不適合使用HDFS遥椿?
?低延時(shí)數(shù)據(jù)訪問(wèn):比如毫秒級(jí)的來(lái)存儲(chǔ)數(shù)據(jù),這是不行的淆储,它做不到冠场。
它適合高吞吐率的場(chǎng)景,就是在某一時(shí)間內(nèi)寫(xiě)入大量的數(shù)據(jù)本砰。但是它在低延時(shí)的情況下是不行的碴裙,比如毫秒級(jí)以內(nèi)讀取數(shù)據(jù),這樣它是很難做到的点额。
?小文件存儲(chǔ):存儲(chǔ)大量小文件(這里的小文件是指小于HDFS系統(tǒng)的Block大小的文件(默認(rèn)64M))的話舔株,它會(huì)占用 NameNode大量的內(nèi)存來(lái)存儲(chǔ)文件、目錄和塊信息还棱。這樣是不可取的载慈,因?yàn)镹ameNode的內(nèi)存總是有限的。
小文件存儲(chǔ)的尋道時(shí)間會(huì)超過(guò)讀取時(shí)間诱贿,它違反了HDFS的設(shè)計(jì)目標(biāo)娃肿。
?并發(fā)寫(xiě)入咕缎、文件隨機(jī)修改:一個(gè)文件只能有一個(gè)寫(xiě)珠十,不允許多個(gè)線程同時(shí)寫(xiě)。僅支持?jǐn)?shù)據(jù) append(追加)凭豪,不支持文件的隨機(jī)修改焙蹭。
05
HDFS如何存儲(chǔ)數(shù)據(jù)?
(1)HDFS的存儲(chǔ)單位
HDFS以塊作為存儲(chǔ)單位嫂伞,默認(rèn)一個(gè)塊64MB孔厉。塊的大小遠(yuǎn)遠(yuǎn)大于普通文件系統(tǒng)拯钻,可以最小化尋址開(kāi)銷(xiāo)。
HDFS采用抽象的塊概念可以帶來(lái)以下幾個(gè)明顯的好處:
支持大規(guī)模文件存儲(chǔ):文件以塊為單位進(jìn)行存儲(chǔ)撰豺,一個(gè)大規(guī)模文件可以被分拆成若干個(gè)文件塊粪般,不同的文件塊可以被分發(fā)到不同的節(jié)點(diǎn)上,因此污桦,一個(gè)文件的大小不會(huì)受到單個(gè)節(jié)點(diǎn)的存儲(chǔ)容量的限制亩歹,可以遠(yuǎn)遠(yuǎn)大于網(wǎng)絡(luò)中任意節(jié)點(diǎn)的存儲(chǔ)容量。
簡(jiǎn)化系統(tǒng)設(shè)計(jì):首先凡橱,大大簡(jiǎn)化了存儲(chǔ)管理小作,因?yàn)槲募K大小是固定的,這樣就可以很容易計(jì)算出一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多少文件塊稼钩;其次顾稀,方便了元數(shù)據(jù)的管理,元數(shù)據(jù)不需要和文件塊一起存儲(chǔ)坝撑,可以由其他系統(tǒng)負(fù)責(zé)管理元數(shù)據(jù)静秆。
適合數(shù)據(jù)備份:每個(gè)文件塊都可以冗余存儲(chǔ)到多個(gè)節(jié)點(diǎn)上,大大提高了系統(tǒng)的容錯(cuò)性和可用性绍载。
(2)HDFS的存儲(chǔ)架構(gòu)
HDFS 采用Master/Slave的架構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)诡宗,這種架構(gòu)主要由四個(gè)部分組成,分別為HDFS Client击儡、NameNode塔沃、DataNode和Secondary NameNode。
(1)Client:就是客戶端阳谍。
文件切分蛀柴。文件上傳 HDFS 的時(shí)候,Client 將文件切分成 一個(gè)一個(gè)的Block矫夯,然后進(jìn)行存儲(chǔ)鸽疾。
與 NameNode 交互,獲取文件的位置信息训貌。
與 DataNode 交互制肮,讀取或者寫(xiě)入數(shù)據(jù)。
Client 提供一些命令來(lái)管理 HDFS递沪,比如啟動(dòng)或者關(guān)閉HDFS豺鼻。
Client 可以通過(guò)一些命令來(lái)訪問(wèn) HDFS。
(2)NameNode:就是 master款慨,它是一個(gè)主管儒飒、管理者。
管理 HDFS 的名稱(chēng)空間檩奠。
管理數(shù)據(jù)塊(Block)映射信息桩了。
配置副本策略附帽。
處理客戶端讀寫(xiě)請(qǐng)求。
(3)DataNode:就是Slave井誉。NameNode 下達(dá)命令蕉扮,DataNode 執(zhí)行實(shí)際的操作。
存儲(chǔ)實(shí)際的數(shù)據(jù)塊颗圣。
執(zhí)行數(shù)據(jù)塊的讀/寫(xiě)操作慢显。
(4)SecondaryNameNode:NameNode 的冷備。
輔助 NameNode欠啤,分擔(dān)其工作量荚藻。
定期合并 FsImage和EditLog,并推送給NameNode洁段。
在緊急情況下应狱,可輔助恢復(fù) NameNode。
06
HDFS如何檢測(cè)和處理錯(cuò)誤數(shù)據(jù)祠丝?
HDFS具有較高的容錯(cuò)性疾呻,可以兼容廉價(jià)的硬件,它把硬件出錯(cuò)看作一種常態(tài)写半,而不是異常岸蜗,并設(shè)計(jì)了相應(yīng)的機(jī)制檢測(cè)數(shù)據(jù)錯(cuò)誤和進(jìn)行自動(dòng)恢復(fù),主要包括以下幾種情形:名稱(chēng)節(jié)點(diǎn)出錯(cuò)叠蝇、數(shù)據(jù)節(jié)點(diǎn)出錯(cuò)和數(shù)據(jù)出錯(cuò)璃岳。
(1)名稱(chēng)節(jié)點(diǎn)出錯(cuò)
名稱(chēng)節(jié)點(diǎn)保存了所有的元數(shù)據(jù)信息,其中悔捶,最核心的兩大數(shù)據(jù)結(jié)構(gòu)是FsImage和Editlog铃慷,如果這兩個(gè)文件發(fā)生損壞,那么整個(gè)HDFS實(shí)例將失效蜕该。
因此犁柜,HDFS設(shè)置了備份機(jī)制,把這些核心文件同步復(fù)制到備份服務(wù)器SecondaryNameNode上堂淡。當(dāng)名稱(chēng)節(jié)點(diǎn)出錯(cuò)時(shí)馋缅,就可以根據(jù)備份服務(wù)器SecondaryNameNode中的FsImage和Editlog數(shù)據(jù)進(jìn)行恢復(fù)。
(2)數(shù)據(jù)節(jié)點(diǎn)出錯(cuò)
每個(gè)數(shù)據(jù)節(jié)點(diǎn)會(huì)定期向名稱(chēng)節(jié)點(diǎn)發(fā)送“心跳”信息绢淀,向名稱(chēng)節(jié)點(diǎn)報(bào)告自己的狀態(tài)萤悴。
當(dāng)數(shù)據(jù)節(jié)點(diǎn)發(fā)生故障,或者網(wǎng)絡(luò)發(fā)生斷網(wǎng)時(shí)更啄,名稱(chēng)節(jié)點(diǎn)就無(wú)法收到來(lái)自一些數(shù)據(jù)節(jié)點(diǎn)的心跳信息稚疹,這時(shí)居灯,這些數(shù)據(jù)節(jié)點(diǎn)就會(huì)被標(biāo)記為“宕機(jī)”祭务,節(jié)點(diǎn)上面的所有數(shù)據(jù)都會(huì)被標(biāo)記為“不可讀”内狗,名稱(chēng)節(jié)點(diǎn)不會(huì)再給它們發(fā)送任何I/O請(qǐng)求。
這時(shí)义锥,有可能出現(xiàn)一種情形柳沙,即由于一些數(shù)據(jù)節(jié)點(diǎn)的不可用,會(huì)導(dǎo)致一些數(shù)據(jù)塊的副本數(shù)量小于冗余因子拌倍。
名稱(chēng)節(jié)點(diǎn)會(huì)定期檢查這種情況赂鲤,一旦發(fā)現(xiàn)某個(gè)數(shù)據(jù)塊的副本數(shù)量小于冗余因子,就會(huì)啟動(dòng)數(shù)據(jù)冗余復(fù)制柱恤,為它生成新的副本数初。
(3)數(shù)據(jù)出錯(cuò)
網(wǎng)絡(luò)傳輸和磁盤(pán)錯(cuò)誤等因素,都會(huì)造成數(shù)據(jù)錯(cuò)誤梗顺。
客戶端在讀取到數(shù)據(jù)后泡孩,會(huì)采用md5和sha1對(duì)數(shù)據(jù)塊進(jìn)行校驗(yàn),以確定讀取到正確的數(shù)據(jù)寺谤。
在文件被創(chuàng)建時(shí)仑鸥,客戶端就會(huì)對(duì)每一個(gè)文件塊進(jìn)行信息摘錄,并把這些信息寫(xiě)入到同一個(gè)路徑的隱藏文件里面变屁。
當(dāng)客戶端讀取文件的時(shí)候眼俊,會(huì)先讀取該信息文件,然后粟关,利用該信息文件對(duì)每個(gè)讀取的數(shù)據(jù)塊進(jìn)行校驗(yàn)疮胖,如果校驗(yàn)出錯(cuò),客戶端就會(huì)請(qǐng)求到另外一個(gè)數(shù)據(jù)節(jié)點(diǎn)讀取該文件塊闷板,并且向名稱(chēng)節(jié)點(diǎn)報(bào)告這個(gè)文件塊有錯(cuò)誤获列,名稱(chēng)節(jié)點(diǎn)會(huì)定期檢查并且重新復(fù)制這個(gè)塊。
07?
HDFS如何讀取文件蛔垢?
HDFS的文件讀取原理击孩,主要包括以下幾個(gè)步驟:
① 首先調(diào)用FileSystem對(duì)象的open方法,其實(shí)獲取的是一個(gè)DistributedFileSystem的實(shí)例鹏漆。
② DistributedFileSystem通過(guò)RPC(遠(yuǎn)程過(guò)程調(diào)用)獲得文件的第一批block的locations巩梢,同一block按照重復(fù)數(shù)會(huì)返回多個(gè)locations,這些locations按照hadoop拓?fù)浣Y(jié)構(gòu)排序艺玲,距離客戶端近的排在前面括蝠。
③ 前兩步會(huì)返回一個(gè)FSDataInputStream對(duì)象,該對(duì)象會(huì)被封裝成 DFSInputStream對(duì)象饭聚,DFSInputStream可以方便的管理datanode和namenode數(shù)據(jù)流忌警。客戶端調(diào)用read方法秒梳,DFSInputStream就會(huì)找出離客戶端最近的datanode并連接datanode法绵。
④ 數(shù)據(jù)從datanode源源不斷的流向客戶端箕速。
⑤ 如果第一個(gè)block塊的數(shù)據(jù)讀完了,就會(huì)關(guān)閉指向第一個(gè)block塊的datanode連接朋譬,接著讀取下一個(gè)block塊盐茎。這些操作對(duì)客戶端來(lái)說(shuō)是透明的,從客戶端的角度來(lái)看只是讀一個(gè)持續(xù)不斷的流徙赢。
⑥ 如果第一批block都讀完了字柠,DFSInputStream就會(huì)去namenode拿下一批blocks的location,然后繼續(xù)讀狡赐,如果所有的block塊都讀完窑业,這時(shí)就會(huì)關(guān)閉掉所有的流。
08
HDFS如何寫(xiě)文件枕屉?
HDFS的文件寫(xiě)入原理数冬,主要包括以下幾個(gè)步驟:
① 客戶端通過(guò)調(diào)用 DistributedFileSystem 的create方法,創(chuàng)建一個(gè)新的文件搀庶。
② DistributedFileSystem 通過(guò) RPC(遠(yuǎn)程過(guò)程調(diào)用)調(diào)用 NameNode拐纱,去創(chuàng)建一個(gè)沒(méi)有blocks關(guān)聯(lián)的新文件。創(chuàng)建前哥倔,NameNode 會(huì)做各種校驗(yàn)秸架,比如文件是否存在,客戶端有無(wú)權(quán)限去創(chuàng)建等咆蒿。如果校驗(yàn)通過(guò)东抹,NameNode 就會(huì)記錄下新文件,否則就會(huì)拋出IO異常沃测。
③ 前兩步結(jié)束后會(huì)返回 FSDataOutputStream 的對(duì)象缭黔,和讀文件的時(shí)候相似,F(xiàn)SDataOutputStream 被封裝成 DFSOutputStream蒂破,DFSOutputStream 可以協(xié)調(diào) NameNode和 DataNode馏谨。客戶端開(kāi)始寫(xiě)數(shù)據(jù)到DFSOutputStream,DFSOutputStream會(huì)把數(shù)據(jù)切成一個(gè)個(gè)小packet附迷,然后排成隊(duì)列 data queue惧互。
④ DataStreamer 會(huì)去處理接受 data queue,它先問(wèn)詢 NameNode 這個(gè)新的 block 最適合存儲(chǔ)的在哪幾個(gè)DataNode里喇伯,比如重復(fù)數(shù)是3喊儡,那么就找到3個(gè)最適合的 DataNode,把它們排成一個(gè) pipeline稻据。DataStreamer 把 packet 按隊(duì)列輸出到管道的第一個(gè) DataNode 中艾猜,第一個(gè) DataNode又把 packet 輸出到第二個(gè) DataNode 中,以此類(lèi)推。
⑤ DFSOutputStream 還有一個(gè)隊(duì)列叫 ack queue匆赃,也是由 packet 組成淤毛,等待DataNode的收到響應(yīng),當(dāng)pipeline中的所有DataNode都表示已經(jīng)收到的時(shí)候炸庞,這時(shí)ack queue才會(huì)把對(duì)應(yīng)的packet包移除掉。
⑥ 客戶端完成寫(xiě)數(shù)據(jù)后荚斯,調(diào)用close方法關(guān)閉寫(xiě)入流埠居。
⑦ DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息事期,收到最后一個(gè) ack 后滥壕,通知 DataNode 把文件標(biāo)示為已完成。
Enjoy reading :)