第二部分:HDFS文件讀取的解析
文件讀取流程
流程分析
使用HDFS提供的客戶端開發(fā)庫Client,向遠(yuǎn)程的Namenode發(fā)起RPC請求;
Namenode會視情況返回文件的部分或者全部block列表,對于每個(gè)block,Namenode都會返回有該block拷貝的DataNode地址;
客戶端開發(fā)庫Client會選取離客戶端最接近的DataNode來讀取block;如果客戶端本身就是DataNode,那么將從本地直接獲取數(shù)據(jù).
讀取完當(dāng)前block的數(shù)據(jù)后,關(guān)閉與當(dāng)前的DataNode連接,并為讀取下一個(gè)block尋找最佳的DataNode;
當(dāng)讀完列表的block后,且文件讀取還沒有結(jié)束,客戶端開發(fā)庫會繼續(xù)向Namenode獲取下一批的block列表。
讀取完一個(gè)block都會進(jìn)行checksum驗(yàn)證,如果讀取datanode時(shí)出現(xiàn)錯(cuò)誤,客戶端會通知Namenode,然后再從下一個(gè)擁有該block拷貝的datanode繼續(xù)讀。
第三部分:HDFS文件寫入的解析
文件寫入流程
流程分析
使用HDFS提供的客戶端開發(fā)庫Client,向遠(yuǎn)程的Namenode發(fā)起RPC請求;
Namenode會檢查要?jiǎng)?chuàng)建的文件是否已經(jīng)存在,創(chuàng)建者是否有權(quán)限進(jìn)行操作,成功則會為文件
創(chuàng)建一個(gè)記錄,否則會讓客戶端拋出異常;
當(dāng)客戶端開始寫入文件的時(shí)候,會將文件切分成多個(gè)packets,并在內(nèi)部以數(shù)據(jù)隊(duì)列"data queue"的形式管理這些packets,并向Namenode申請新的blocks,獲取用來存儲replicas的合適的datanodes列表,列表的大小根據(jù)在Namenode中對replication的設(shè)置而定。
開始以pipeline(管道)的形式將packet寫入所有的replicas中。把packet以流的方式寫入第一個(gè)datanode,該datanode把該packet存儲之后,再將其傳遞給在此pipeline中的下一個(gè)datanode,直到最后一個(gè)datanode,這種寫數(shù)據(jù)的方式呈流水線的形式。
最后一個(gè)datanode成功存儲之后會返回一個(gè)ack packet,在pipeline里傳遞至客戶端,在客戶端的開發(fā)庫內(nèi)部維護(hù)著"ack queue",成功收到datanode返回的ack packet后會從"ack queue"移除相應(yīng)的packet。
如果傳輸過程中,有某個(gè)datanode出現(xiàn)了故障,那么當(dāng)前的pipeline會被關(guān)閉,出現(xiàn)故障的datanode會從當(dāng)前的pipeline中移除,剩余的block會繼續(xù)剩下的datanode中繼續(xù)以pipeline的形式傳輸,同時(shí)Namenode會分配一個(gè)新的datanode,保持replicas設(shè)定的數(shù)量。
流水線復(fù)制
當(dāng)客戶端向
HDFS
文件寫入數(shù)據(jù)的時(shí)候,一開始是寫到本地臨時(shí)文件中。假設(shè)該文件的副
本系數(shù)設(shè)置為
3
,當(dāng)本地臨時(shí)文件累積到一個(gè)數(shù)據(jù)塊的大小時(shí),客戶端會從
Namenode
獲取一個(gè)
Datanode
列表用于存放副本。然后客戶端開始向第一個(gè)
Datanode
傳輸數(shù)據(jù),第一個(gè)
Datanode
一小部分一小部分
(4 KB)
地接收數(shù)據(jù),將每一部分寫入本地倉庫,并同時(shí)傳輸該部分到列表中
第二個(gè)
Datanode
節(jié)點(diǎn)。第二個(gè)
Datanode
也是這樣,一小部分一小部分地接收數(shù)據(jù),寫入本地
倉庫,并同時(shí)傳給第三個(gè)
Datanode
。最后,第三個(gè)
Datanode
接收數(shù)據(jù)并存儲在本地。因此,
Datanode
能流水線式地從前一個(gè)節(jié)點(diǎn)接收數(shù)據(jù),并在同時(shí)轉(zhuǎn)發(fā)給下一個(gè)節(jié)點(diǎn),數(shù)據(jù)以流水線的
方式從前一個(gè)
Datanode
復(fù)制到下一個(gè)
更細(xì)節(jié)的原理
客戶端創(chuàng)建文件的請求其實(shí)并沒有立即發(fā)送給
Namenode
,事實(shí)上,在剛開始階
段
HDFS
客戶端會先將文件數(shù)據(jù)緩存到本地的一個(gè)臨時(shí)文件。應(yīng)用程序的寫操作被透
明地重定向到這個(gè)臨時(shí)文件。當(dāng)這個(gè)臨時(shí)文件累積的數(shù)據(jù)量超過一個(gè)數(shù)據(jù)塊的大小
,客戶端才會聯(lián)系
Namenode
。
Namenode
將文件名插入文件系統(tǒng)的層次結(jié)構(gòu)中,并
且分配一個(gè)數(shù)據(jù)塊給它。然后返回
Datanode
的標(biāo)識符和目標(biāo)數(shù)據(jù)塊給客戶端。接著
客戶端將這塊數(shù)據(jù)從本地臨時(shí)文件上傳到指定的
Datanode
上。當(dāng)文件關(guān)閉時(shí),在臨
時(shí)文件中剩余的沒有上傳的數(shù)據(jù)也會傳輸?shù)街付ǖ?/span>
Datanode
上。然后客戶端告訴
Namenode
文件已經(jīng)關(guān)閉。此時(shí)
Namenode
才將文件創(chuàng)建操作提交到日志里進(jìn)行存儲
。如果
Namenode
在文件關(guān)閉前宕機(jī)了,則該文件將丟失。
第四部分:副本機(jī)制
特點(diǎn)
1.
數(shù)據(jù)類型單一
2.
副本數(shù)比較多
3.
寫文件時(shí)副本的放置方法
4.
動態(tài)的副本創(chuàng)建策略
5.
弱化的副本一致性要求
副本擺放策略
修改副本數(shù)
1.集群只有三個(gè)Datanode,hadoop系統(tǒng)replication=4時(shí),會出現(xiàn)什么情況?
對于上傳文件到hdfs上時(shí),當(dāng)時(shí)hadoop的副本系數(shù)是幾,這個(gè)文件的塊數(shù)副本數(shù)就會有幾份,無論以后你怎么更改系統(tǒng)副本系統(tǒng),這個(gè)文件的副本數(shù)都不會改變,也就說上傳到分布式系統(tǒng)上的文件副本數(shù)由當(dāng)時(shí)的系統(tǒng)副本數(shù)決定,不會受replication的更改而變化,除非用命令來更改文件的副本數(shù)。因?yàn)閐fs.replication實(shí)質(zhì)上是client參數(shù),在create文件時(shí)可以指定具體replication,屬性dfs.replication是不指定具體replication時(shí)的采用默認(rèn)備份數(shù)。文件上傳后,備份數(shù)已定,修改dfs.replication是不會影響以前的文件的,也不會影響后面指定備份數(shù)的文件。只影響后面采用默認(rèn)備份數(shù)的文件。但可以利用hadoop提供的命令后期改某文件的備份數(shù):hadoop fs -setrep -R 1。如果你是在hdfs-site.xml設(shè)置了dfs.replication,這并一定就得了,因?yàn)槟憧赡軟]把conf文件夾加入到你的 project的classpath里,你的程序運(yùn)行時(shí)取的dfs.replication可能是hdfs-default.xml里的 dfs.replication,默認(rèn)是3??赡苓@個(gè)就是造成你為什么dfs.replication老是3的原因。你可以試試在創(chuàng)建文件時(shí),顯式設(shè)定replication。replication一般到3就可以了,大了意義也不大。
轉(zhuǎn)載請注明出處【
http:///forum/blogPost/list/5936.html#19653】
|
|