您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)HDFS塊和Input Splits的區(qū)別有哪些,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
HDFS塊
現(xiàn)在我有一個名為 iteblog.txt 的文件,如下:
[iteblog@iteblog.com /home/iteblog]$ ll iteblog.txt -rw-r--r-- 1 iteblog iteblog 454669963 May 15 12:07 iteblog.txt
很明顯,這個文件大于一個 HDFS 塊大小,所有如果我們將這個文件存放到 HDFS 上會生成 4 個 HDFS 塊,如下(注意下面的輸出做了一些刪除操作):
[iteblog@iteblog.com /home/iteblog]$ hadoop -put iteblog.txt /tmp [iteblog@iteblog.com /home/iteblog]$ hdfs fsck /tmp/iteblog.txt -files -blocks /tmp/iteblog.txt 454669963 bytes, 4 block(s): OK 0. BP-1398136447-192.168.246.60-1386067202761:blk_8133964845_1106679622318 len=134217728 repl=3 1. BP-1398136447-192.168.246.60-1386067202761:blk_8133967228_1106679624701 len=134217728 repl=3 2. BP-1398136447-192.168.246.60-1386067202761:blk_8133969503_1106679626977 len=134217728 repl=3 3. BP-1398136447-192.168.246.60-1386067202761:blk_8133970122_1106679627596 len=52016779 repl=3
可以看出 iteblog.txt 文件被切成 4 個塊了,前三個塊大小正好是 128MB(134217728),剩下的數(shù)據(jù)存放到第 4 個 HDFS 塊中。
答案是這行記錄會被切割成兩部分,一部分存放在 block 0 里面;剩下的部分存放在 block 1 里面。具體的,偏移量為134217710,長度為18的數(shù)據(jù)存放到 block 0 里面;偏移量134217729,長度為82的數(shù)據(jù)存放到 block 1 里面。 可以將這部分的邏輯以下面的圖概括
說明:
圖中的紅色塊代表一個文件
中間的藍(lán)色矩形塊代表一個 HDFS 塊,矩形里面的數(shù)字代表 HDFS 塊的編號,讀整個文件的時候是從編號為0的 HDFS 塊開始讀,然后依次是1,2,3...
最下面的一行矩形代表文件里面存儲的內(nèi)容,每個小矩形代表一行數(shù)據(jù),里面的數(shù)字代表數(shù)據(jù)的編號。紅色的豎線代表 HDFS 塊邊界(block boundary)。
從上圖我們可以清晰地看出,當(dāng)我們往 HDFS 寫文件時,HDFS 會將文件切割成大小為 128MB 的塊,切割的時候不會判斷文件里面存儲的到底是什么東西,所以邏輯上屬于一行的數(shù)據(jù)會被切割成兩部分,這兩部分的數(shù)據(jù)被物理的存放在兩個不同的 HDFS 塊中,正如上圖中的第5、10以及14行被切割成2部分了。
File Split
現(xiàn)在我們需要使用 MapReduce 來讀取上面的文件,由于是普通的文本文件,所以可以直接使用 TextInputFormat
來讀取。下面是使用 TextInputFormat
獲取到的 FileSplit
信息:
scala> FileInputFormat.addInputPath(job,new Path("/tmp/iteblog.txt")); scala> val format = new TextInputFormat; scala> val splits = format.getSplits(job) scala> splits.foreach(println) hdfs://iteblogcluster/tmp/iteblog.txt:0+134217728 hdfs://iteblogcluster/tmp/iteblog.txt:134217728+134217728 hdfs://iteblogcluster/tmp/iteblog.txt:268435456+134217728 hdfs://iteblogcluster/tmp/iteblog.txt:402653184+52016779
可以看出,每個 FileSplit 的起始偏移量和上面 HDFS 每個文件塊一致。但是具體讀數(shù)據(jù)的時候,MapReduce 是如何處理的呢?我們現(xiàn)在已經(jīng)知道,在將文件存儲在 HDFS 的時候,文件被切割成一個一個 HDFS Block,其中會導(dǎo)致一些邏輯上屬于一行的數(shù)據(jù)會被切割成兩部分,那 TextInputFormat
遇到這樣的數(shù)據(jù)是如何處理的呢?
對于這種情況,TextInputFormat
會做出如下兩種操作:
在初始化 LineRecordReader
的時候,如果 FileSplit
的起始位置 start
不等于0, 說明這個 Block 塊不是第一個 Block,這時候一律丟掉這個 Block 的第一行數(shù)據(jù)。
在讀取每個 Block 的時候,都會額外地多讀取一行,如果出現(xiàn)數(shù)據(jù)被切割到另外一個 Block 里面,這些數(shù)據(jù)能夠被這個任務(wù)讀取。
使用圖形表示可以概括如下:
說明:
圖中的紅色虛線代表 HDFS 塊邊界(block boundary);
藍(lán)色的虛線代表Split 讀數(shù)的邊界。
從圖中可以清晰地看出:
當(dāng)程序讀取 Block 0 的時候,雖然第五行數(shù)據(jù)被分割并被存儲在 Block 0 和 Block 1 中,但是,當(dāng)前程序能夠完整的讀取到第五行的完整數(shù)據(jù)。
當(dāng)程序讀取 Block 1 的時候,由于其 FileSplit
的起始位置 start
不等于0,這時候會丟掉第一行的數(shù)據(jù),也就是說 Block 1 中的第五行部分?jǐn)?shù)據(jù)會被丟棄,而直接從第六行數(shù)據(jù)讀取。這樣做的原因是,Block 1 中的第五行部分?jǐn)?shù)據(jù)在程序讀取前一個 Block 的時候已經(jīng)被讀取了,所以可以直接丟棄。
其他剩下的 Block 讀取邏輯和這個一致。
從上面的分析可以得出以下的總結(jié)
Split 和 HDFS Block 是一對多的關(guān)系;
HDFS block 是數(shù)據(jù)的物理表示,而 Split 是 block 中數(shù)據(jù)的邏輯表示;
滿足數(shù)據(jù)本地性的情況下,程序也會從遠(yuǎn)程節(jié)點(diǎn)上讀取少量的數(shù)據(jù),因?yàn)榇嬖谛斜磺懈畹讲煌?Block 上。
關(guān)于“HDFS塊和Input Splits的區(qū)別有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。