
1)客戶端向namenode請(qǐng)求下載文件,namenode通過(guò)查詢?cè)獢?shù)據(jù),找到文件塊所在的datanode地址。
2)挑選一臺(tái)datanode(就近原則,然后隨機(jī))服務(wù)器,請(qǐng)求讀取數(shù)據(jù)。
3)datanode開(kāi)始傳輸數(shù)據(jù)給客戶端(從磁盤(pán)里面讀取數(shù)據(jù)放入流,以packet為單位來(lái)做校驗(yàn))。
4)客戶端以packet為單位接收,先在本地緩存,然后寫(xiě)入目標(biāo)文件。

1.首先調(diào)用FileSystem對(duì)象的open方法,其實(shí)是一個(gè)DistributedFileSystem的實(shí)例。
2.DistributedFileSystem通過(guò)rpc獲得文件的第一批block的locations,同一個(gè)block按照重復(fù)數(shù)會(huì)返回多個(gè)locations,這些locations按照hadoop拓?fù)浣Y(jié)構(gòu)排序,距離客戶端近的排在前面。
3.前兩步會(huì)返回一個(gè)FSDataInputStream對(duì)象,該對(duì)象會(huì)被封裝DFSInputStream對(duì)象,DFSInputStream可 以方便的管理datanode和namenode數(shù)據(jù)流??蛻舳苏{(diào)用read方法,DFSInputStream最會(huì)找出離客戶端最近的datanode 并連接。
4.數(shù)據(jù)從datanode源源不斷的流向客戶端。
5.如果第一塊的數(shù)據(jù)讀完了,就會(huì)關(guān)閉指向第一塊的datanode連接,接著讀取下一塊。這些操作對(duì)客戶端來(lái)說(shuō)是透明的,客戶端的角度看來(lái)只是讀一個(gè)持續(xù)不斷的流。
6.如果第一批block都讀完了, DFSInputStream就會(huì)去namenode拿下一批block的locations,然后繼續(xù)讀,如果所有的塊都讀完,這時(shí)就會(huì)關(guān)閉掉所有的流。
7.如果在讀數(shù)據(jù)的時(shí)候, DFSInputStream和datanode的通訊發(fā)生異常,就會(huì)嘗試正在讀的block的排序第二近的datanode,并且會(huì)記錄哪個(gè) datanode發(fā)生錯(cuò)誤,剩余的blocks讀的時(shí)候就會(huì)直接跳過(guò)該datanode
DFSInputStream也會(huì)檢查block數(shù)據(jù)校驗(yàn)和,如果發(fā)現(xiàn)一個(gè)壞的block,就會(huì)先報(bào)告到namenode節(jié)點(diǎn),然后 DFSInputStream在其他的datanode上讀該block的鏡像。
8.該設(shè)計(jì)就是客戶端直接連接datanode來(lái)檢索數(shù)據(jù)并且namenode來(lái)負(fù)責(zé)為每一個(gè)block提供最優(yōu)的datanode, namenode僅僅處理block location的請(qǐng)求,這些信息都加載在namenode的內(nèi)存中,hdfs通過(guò)datanode集群可以承受大量客戶端的并發(fā)訪問(wèn)。