block、packet與chunk
在DFSClient寫HDFS的過(guò)程中,有三個(gè)需要搞清楚的單位:block、packet與chunk;
- block是最大的一個(gè)單位,它是最終存儲(chǔ)于DataNode上的數(shù)據(jù)粒度,由dfs.block.size參數(shù)決定,默認(rèn)是64M;注:這個(gè)參數(shù)由客戶端配置決定;
- packet是中等的一個(gè)單位,它是數(shù)據(jù)由DFSClient流向DataNode的粒度,以dfs.write.packet.size參數(shù)為參考值,默認(rèn)是64K;注:這個(gè)參數(shù)為參考值,是指真正在進(jìn)行數(shù)據(jù)傳輸時(shí),會(huì)以它為基準(zhǔn)進(jìn)行調(diào)整,調(diào)整的原因是一個(gè)packet有特定的結(jié)構(gòu),調(diào)整的目標(biāo)是這個(gè)packet的大小剛好包含結(jié)構(gòu)中的所有成員,同時(shí)也保證寫到DataNode后當(dāng)前block的大小不超過(guò)設(shè)定值;
- chunk是最小的一個(gè)單位,它是DFSClient到DataNode數(shù)據(jù)傳輸中進(jìn)行數(shù)據(jù)校驗(yàn)的粒度,由io.bytes.per.checksum參數(shù)決定,默認(rèn)是512B;注:事實(shí)上一個(gè)chunk還包含4B的校驗(yàn)值,因而chunk寫入packet時(shí)是516B;數(shù)據(jù)與檢驗(yàn)值的比值為128:1,所以對(duì)于一個(gè)128M的block會(huì)有一個(gè)1M的校驗(yàn)文件與之對(duì)應(yīng);
寫過(guò)程中的三層buffer
寫過(guò)程中會(huì)以chunk、packet及packet queue三個(gè)粒度做三層緩存;
- 首先,當(dāng)數(shù)據(jù)流入DFSOutputStream時(shí),DFSOutputStream內(nèi)會(huì)有一個(gè)chunk大小的buf,當(dāng)數(shù)據(jù)寫滿這個(gè)buf(或遇到強(qiáng)制flush),會(huì)計(jì)算checksum值,然后填塞進(jìn)packet;
- 當(dāng)一個(gè)chunk填塞進(jìn)入packet后,仍然不會(huì)立即發(fā)送,而是累積到一個(gè)packet填滿后,將這個(gè)packet放入dataqueue隊(duì)列;
- 進(jìn)入dataqueue隊(duì)列的packet會(huì)被另一線程按序取出發(fā)送到datanode;(注:生產(chǎn)者消費(fèi)者模型,阻塞生產(chǎn)者的條件是dataqueue與ackqueue之和超過(guò)一個(gè)block的packet上限)

三層buf