從上一篇文章中我們已經(jīng)知道了NameNode和Secondary NameNode的職責(zé)增显,這篇文章我們主要講講我們怎么往DataNode上寫數(shù)據(jù)和讀數(shù)據(jù)蚓庭。
DataNode的寫操作流程
DataNode的寫操作流程可以分為兩部分馒索,第一部分是寫操作之前的準(zhǔn)備工作,包括與NameNode的通信等;第二部分是真正的寫操作邑闲。我們先看第一部分。
- 首先梧油,HDFS client會(huì)去詢問NameNode苫耸,看哪些DataNode可以存儲(chǔ)Block A-file.txt文件的拆分是在HDFS client中完成的,拆分成了3個(gè)Block (A,B,C)儡陨。因?yàn)镹ameNode存儲(chǔ)著整個(gè)文件系統(tǒng)的元數(shù)據(jù)褪子,它知道哪個(gè)DataNode上有空間可以存儲(chǔ)這個(gè)Block A量淌。
- NameNode通過查看它的元數(shù)據(jù)信息,發(fā)現(xiàn)DataNode1嫌褪,2呀枢,7上有空間可以存儲(chǔ)Block A,于是將此信息告訴HDFS Client笼痛。
- HDFS Client接到NameNode返回的DataNode列表信息后裙秋,它會(huì)直接聯(lián)系第一個(gè)DataNode-DataNode1,讓它準(zhǔn)備好接收Block A - 實(shí)際上就是建立彼此間的TCP連接晃痴。然后將Block A和NameNode返回的所有關(guān)于DataNode的元數(shù)據(jù)一并傳給DataNode1.
- 在DataNode1與HDFS Client建立好TCP連接后残吩,它會(huì)把HDFS Client要寫B(tài)lock A的請求順序傳給DataNode2(在與HDFS Client建立好TCP連接后從HDFS Client獲得的DataNodeli信息),要求DataNode2也準(zhǔn)備好接收Block A(建立DataNode2到DataNode1的TCP連接)倘核。
- 同上泣侮,建立DataNode2到DataNode7的TCP連接。
- 當(dāng)DataNode7準(zhǔn)備好之后紧唱,它會(huì)通知DataNode2活尊,表明可以開始接收Block A。
- 同理漏益,當(dāng)DataNode2準(zhǔn)備好之后蛹锰,它會(huì)通知DataNode1,表明可以開始接收Block A绰疤。
- 當(dāng)HDFS Client接到DataNode1的成功反饋信息后铜犬,說明這3個(gè)DataNode都準(zhǔn)備好了,HDFS Client就會(huì)開始往這三個(gè)DataNode寫入Block A轻庆。
下面這張圖片展示了HDFS Client如何往DataNode寫入Block A數(shù)據(jù)癣猾。
在DataNode1,2,7都準(zhǔn)備好接收數(shù)據(jù)后,HDFS Client開始往DataNode1寫入Block A數(shù)據(jù)余爆。同準(zhǔn)備工作一樣纷宇,當(dāng)DataNode1接收完Block A數(shù)據(jù)后,它會(huì)順序?qū)lock A數(shù)據(jù)傳輸給DataNode2蛾方,然后DataNode2再傳輸給DataNode7. 每個(gè)DataNode在接收完Block A數(shù)據(jù)后像捶,會(huì)發(fā)消息給NameNode,告訴它Block數(shù)據(jù)已經(jīng)接收完畢桩砰,NameNode同時(shí)會(huì)根據(jù)它接收到的消息更新它保存的文件系統(tǒng)元數(shù)據(jù)信息拓春。當(dāng)Block A成功寫入3個(gè)DataNode之后,DataNode1會(huì)發(fā)送一個(gè)成功信息給HDFS Client亚隅,同時(shí)HDFS Client也會(huì)發(fā)一個(gè)Block A成功寫入的信息給NameNode痘儡。之后,HDFS Client才能開始繼續(xù)處理下一個(gè)Block-Block B枢步。
機(jī)架感知
其實(shí)NameNode在挑選合適的DataNode去存儲(chǔ)Block的時(shí)候沉删,不僅僅考慮了DataNode的存儲(chǔ)空間夠不夠渐尿,還會(huì)考慮這些DataNode在不在同一個(gè)機(jī)架上。這就需要NameNode必須知道所有的DataNode分別位于哪個(gè)機(jī)架上(所以也稱為機(jī)架感知)矾瑰。當(dāng)然砖茸,默認(rèn)情況下NameNode是不會(huì)知道機(jī)架的存在的,也就是說殴穴,默認(rèn)情況下凉夯,NameNode會(huì)認(rèn)為所有的DataNode都在同一個(gè)機(jī)架上(/defaultRack)。除非我們在hdfs-site.xml里面配置topology.script.file.name選項(xiàng)采幌,這個(gè)選項(xiàng)的值是一個(gè)可執(zhí)行文件的位置劲够,而該只執(zhí)行文件的作用是將輸入的DataNode的ip地址按照一定規(guī)則計(jì)算,然后輸出它所在的機(jī)架的名字休傍,如/rack1, /rack2之類征绎。借助這個(gè)文件,NameNode就具備了機(jī)架感知了磨取。當(dāng)它在挑選DataNode去存儲(chǔ)Block的時(shí)候人柿,它會(huì)遵循以下原則:
- 首先挑選跟HDFS Client所在的DataNode作為存放第一個(gè)Block副本的位置,如果HDFS Client不在任何一個(gè)DataNode上忙厌,比如說Hadoop集群外你自己的電腦凫岖,那么就任意選取一個(gè)DataNode。
- 其次逢净,會(huì)借助NameNode的機(jī)架感知特性哥放,選取跟第一個(gè)Block副本所在DataNode不同的機(jī)架上的任意一個(gè)DataNode來存放Block的第二個(gè)副本,比如說/rack2爹土。Block的第三個(gè)副本也會(huì)存在這個(gè)/rack2上甥雕,但是是另外一個(gè)DataNode
- 最后,如果我們設(shè)置的副本的數(shù)量大于3着饥,那么剩下的副本則隨意存儲(chǔ)在集群中。
所以惰赋,按照上面的原則宰掉,在HDFS Client進(jìn)行Block的寫操作時(shí),流程應(yīng)該如下面圖所示:
DataNode的讀數(shù)據(jù)流程
最后赁濒,我們來看看HDFS Client是如何從DataNode讀取數(shù)據(jù)的轨奄。
如上圖所示,首先拒炎,HDFS Client會(huì)先去聯(lián)系NameNode挪拟,詢問file.txt總共分為幾個(gè)Block而且這些Block分別存放在哪些DataNode上。由于每個(gè)Block都會(huì)存在幾個(gè)副本击你,所以NameNode會(huì)把file.txt文件組成的Block所對應(yīng)的所有DataNode列表都返回給HDFS Client玉组。然后HDFS Client會(huì)選擇DataNode列表里的第一個(gè)DataNode去讀取對應(yīng)的Block谎柄,比如由于Block A存儲(chǔ)在DataNode1,2惯雳,7朝巫,那么HDFS Client會(huì)到DataNode1去讀取Block A;Block C存儲(chǔ)在DataNode石景,7劈猿,8,9潮孽,那么HDFS Client就回到DataNode7去讀取Block C揪荣。