千鋒教育大數(shù)據(jù)Hadoop全新升級版入門教程,零基礎(chǔ)從安裝搭建到集群調(diào)優(yōu)

HDFS的讀流程
- 客戶端通過調(diào)用FileSystem對象的open()方法來打開希望讀取的文件,對于HDFS來說,這個對象是DistributedFileSystem,它通過使用遠(yuǎn)程過程調(diào)用(RPC)來調(diào)用namenode,以確定文件起始塊的位置
- 對于每一個塊,NameNode返回存有該塊副本的DataNode地址,并根據(jù)距離客戶端的遠(yuǎn)近來排序。
- DistributedFileSystem實例會返回一個FSDataInputStream對象(支持文件定位功能)給客戶端以便讀取數(shù)據(jù),接著客戶端對這個輸入流調(diào)用read()方法
- FSDataInputStream隨即連接距離最近的文件中第一個塊所在的DataNode,通過對數(shù)據(jù)流反復(fù)調(diào)用read()方法,可以將數(shù)據(jù)從DataNode傳輸?shù)娇蛻舳?/li>
- 當(dāng)讀取到塊的末端時,F(xiàn)SInputStream關(guān)閉與該DataNode的連接,然后尋找下一個塊的最佳DataNode
- 客戶端從流中讀取數(shù)據(jù)時,塊是按照打開FSInputStream與DataNode的新建連接的順序讀取的。它也會根據(jù)需要詢問NameNode來檢索下一批數(shù)據(jù)塊的DataNode的位置。一旦客戶端完成讀取,就對FSInputStream調(diào)用close方法
HDFS的寫流程
- 客戶端通過對DistributedFileSystem對象調(diào)用create()方法來新建文件
- DistributedFileSystem對namenode創(chuàng)建一個RPC調(diào)用,在文件系統(tǒng)的命名空間中新建一個文件,此時該文件中還沒有相應(yīng)的數(shù)據(jù)塊
- namenode執(zhí)行各種不同的檢查,以確保這個文件不存在以及客戶端有新建該文件的權(quán)限。如果檢查通過,namenode就會為創(chuàng)建新文件記錄一條事務(wù)記錄(否則,文件創(chuàng)建失敗并向客戶端拋出一個IOException異常)。DistributedFileSystem向客戶端返回一個FSDataOuputStream對象,由此客戶端可以開始寫入數(shù)據(jù),
- 在客戶端寫入數(shù)據(jù)時,F(xiàn)SOutputStream將它分成一個個的數(shù)據(jù)包(packet),并寫入一個內(nèi)部隊列,這個隊列稱為“數(shù)據(jù)隊列”(data queue)。DataStreamer線程負(fù)責(zé)處理數(shù)據(jù)隊列,它的責(zé)任是挑選出合適存儲數(shù)據(jù)復(fù)本的一組datanode,并以此來要求namenode分配新的數(shù)據(jù)塊。這一組datanode將構(gòu)成一個管道,以默認(rèn)復(fù)本3個為例,所以該管道中有3個節(jié)點.DataStreamer將數(shù)據(jù)包流式傳輸?shù)焦艿乐械谝粋€datanode,該datanode存儲數(shù)據(jù)包并將它發(fā)送到管道中的第2個datanode,同樣,第2個datanode存儲該數(shù)據(jù)包并且發(fā)送給管道中的第三個datanode。DataStreamer在將一個個packet流式傳輸?shù)降谝粋€Datanode節(jié)點后,還會將此packet從數(shù)據(jù)隊列移動到另一個隊列確認(rèn)隊列(ack queue)中。
- datanode寫入數(shù)據(jù)成功之后,會為ResponseProcessor線程發(fā)送一個寫入成功的信息回執(zhí),當(dāng)收到管道中所有的datanode確認(rèn)信息后,ResponseProcessoer線程會將該數(shù)據(jù)包從確認(rèn)隊列中刪除。
如果任何datanode在寫入數(shù)據(jù)期間發(fā)生故障,則執(zhí)行以下操作
- 首先關(guān)閉管道,把確認(rèn)隊列中的所有數(shù)據(jù)包都添加回數(shù)據(jù)隊列的最前端,以確保故障節(jié)點下游的datanode不會漏掉任何一個數(shù)據(jù)包
- 為存儲在另一正常datanode的當(dāng)前數(shù)據(jù)塊制定一個新標(biāo)識,并將該標(biāo)識傳送給namenode,以便故障datanode在恢復(fù)后可以刪除存儲的部分?jǐn)?shù)據(jù)塊
- 從管道中刪除故障datanode,基于兩個正常datanode構(gòu)建一條新管道,余下數(shù)據(jù)塊寫入管道中正常的datanode
- namenode注意到塊復(fù)本不足時,會在一個新的Datanode節(jié)點上創(chuàng)建一個新的復(fù)本。
注意:在一個塊被寫入期間可能會有多個datanode同時發(fā)生故障,但概率非常低。只要寫入了dfs.namenode.replication.min的復(fù)本數(shù)(默認(rèn)1),寫操作就會成功,并且這個塊可以在集群中異步復(fù)制,直到達到其目標(biāo)復(fù)本數(shù)dfs.replication的數(shù)量(默認(rèn)3)
標(biāo)簽: