MapReduce Input Split(輸入分/切片)詳解--比較容易理解

轉自:https://blog.csdn.net/Dr_Guo/article/details/51150278

看了很多博客,感覺沒有一個說的很清楚,所以我來整理一下。

先看一下這個圖


輸入分片(Input Split):在進行map計算之前,mapreduce會根據輸入文件計算輸入分片(input split),每個輸入分片(input split)針對一個map任務,輸入分片(input split)存儲的並非數據本身,而是一個分片長度和一個記錄數據的位置的數組。

Hadoop 2.x默認的block大小是128MB,Hadoop 1.x默認的block大小是64MB,可以在hdfs-site.xml中設置dfs.block.size,注意單位是byte。

分片大小範圍可以在mapred-site.xml中設置,mapred.min.split.size mapred.max.split.size,minSplitSize大小默認爲1B,maxSplitSize大小默認爲Long.MAX_VALUE = 9223372036854775807

那麼分片到底是多大呢?

minSize=max{minSplitSize,mapred.min.split.size} 

maxSize=mapred.max.split.size

splitSize=max{minSize,min{maxSize,blockSize}}

我們再來看一下源碼


所以在我們沒有設置分片的範圍的時候,分片大小是由block塊大小決定的,和它的大小一樣。比如把一個258MB的文件上傳到HDFS上,假設block塊大小是128MB,那麼它就會被分成三個block塊,與之對應產生三個split,所以最終會產生三個map task。我又發現了另一個問題,第三個block塊裏存的文件大小隻有2MB,而它的block塊大小是128MB,那它實際佔用Linux file system的多大空間?

答案是實際的文件大小,而非一個塊的大小。

有大神已經驗證這個答案了:http://blog.csdn.net/samhacker/article/details/23089157

1、往hdfs裏面添加新文件前,hadoop在linux上面所佔的空間爲 464 MB:


2、往hdfs裏面添加大小爲2673375 byte(大概2.5 MB)的文件:

2673375 derby.jar

3、此時,hadoop在linux上面所佔的空間爲 467 MB——增加了一個實際文件大小(2.5 MB)的空間,而非一個block size(128 MB)

4、使用hadoop dfs -stat查看文件信息: 


這裏就很清楚地反映出: 文件的實際大小(file size)是2673375 byte, 但它的block size是128 MB。

5、通過NameNode的web console來查看文件信息: 


結果是一樣的: 文件的實際大小(file size)是2673375 byte, 但它的block size是128 MB。

6、不過使用‘hadoop fsck’查看文件信息,看出了一些不一樣的內容——  ‘1(avg.block size 2673375 B)’: 

值得注意的是,結果中有一個 ‘1(avg.block size 2673375 B)’的字樣。這裏的 'block size' 並不是指平常說的文件塊大小(Block Size)—— 後者是一個元數據的概念,相反它反映的是文件的實際大小(file size)。以下是Hadoop Community的專家給我的回覆: 

“The fsck is showing you an "average blocksize", not the block size metadata attribute of the file like stat shows. In this specific case, the average is just the length of your file, which is lesser than one whole block.”


最後一個問題是: 如果hdfs佔用Linux file system的磁盤空間按實際文件大小算,那麼這個”塊大小“有必要存在嗎?

其實塊大小還是必要的,一個顯而易見的作用就是當文件通過append操作不斷增長的過程中,可以通過來block size決定何時split文件。以下是Hadoop Community的專家給我的回覆: 

“The block size is a meta attribute. If you append tothe file later, it still needs to know when to split further - so it keeps that value as a mere metadata it can use to advise itself on write boundaries.” 


補充:我還查到這樣一段話

原文地址:http://blog.csdn.net/lylcore/article/details/9136555

一個split的大小是由goalSize, minSize, blockSize這三個值決定的。computeSplitSize的邏輯是,先從goalSize和blockSize兩個值中選出最小的那個(比如一般不設置map數,這時blockSize爲當前文件的塊size,而goalSize是文件大小除以用戶設置的map數得到的,如果沒設置的話,默認是1)。

hadooop提供了一個設置map個數的參數mapred.map.tasks,我們可以通過這個參數來控制map的個數。但是通過這種方式設置map的個數,並不是每次都有效的。原因是mapred.map.tasks只是一個hadoop的參考數值,最終map的個數,還取決於其他的因素。
     爲了方便介紹,先來看幾個名詞:
block_size : hdfs的文件塊大小,默認爲64M,可以通過參數dfs.block.size設置
total_size : 輸入文件整體的大小
input_file_num : 輸入文件的個數

(1)默認map個數
     如果不進行任何設置,默認的map個數是和blcok_size相關的。
     default_num = total_size / block_size;

(2)期望大小
     可以通過參數mapred.map.tasks來設置程序員期望的map個數,但是這個個數只有在大於default_num的時候,纔會生效。
     goal_num = mapred.map.tasks;

(3)設置處理的文件大小
     可以通過mapred.min.split.size 設置每個task處理的文件大小,但是這個大小只有在大於block_size的時候纔會生效。
     split_size = max(mapred.min.split.size, block_size);
     split_num = total_size / split_size;

(4)計算的map個數
compute_map_num = min(split_num,  max(default_num, goal_num))

     除了這些配置以外,mapreduce還要遵循一些原則。 mapreduce的每一個map處理的數據是不能跨越文件的,也就是說min_map_num >= input_file_num。 所以,最終的map個數應該爲:
     final_map_num = max(compute_map_num, input_file_num)

     經過以上的分析,在設置map個數的時候,可以簡單的總結爲以下幾點:
(1)如果想增加map個數,則設置mapred.map.tasks 爲一個較大的值。
(2)如果想減小map個數,則設置mapred.min.split.size 爲一個較大的值。
(3)如果輸入中有很多小文件,依然想減少map個數,則需要將小文件merger爲大文件,然後使用準則2。


版權聲明:本文爲博主原創文章,轉載請加上原文地址,謝謝! https://blog.csdn.net/Dr_Guo/article/details/51150278

DirectX5.0最新遊戲編程指南 DirectDraw教程篇 一、配置DirectX SDK

 DirectX5.0最新遊戲編程指南DirectDraw教程篇    DirectX是爲Visual C++的用戶準備的,因此要編制DirectDraw遊戲程序,最好對VC要有一定的瞭解。不願意使用...
  • holyfire
  • holyfire
  • 2001-04-16 09:37:00
  • 3342

Hadoop-2.4.1源碼分析--MapReduce作業切片(Split)過程

在上一篇文章《Hadoop源碼分析--MapReduce作業(job)提交源碼跟蹤》中,我介紹了Job的提交過程源碼,介紹的最後一個方法是submitJobInternal(Jobjob, Clus...
  • u010010428
  • u010010428
  • 2016-05-21 16:43:51
  • 2308

MapReduce Input Split(輸入分/切片)詳解 - CSDN博客

輸入分片(Input Split):在進行map計算之前,mapreduce會根據輸入文件計算輸入分片...比如把一個258MB的文件上傳到HDFS上,假設block塊大小是128MB,那麼它就會被分成...
  • 2018-4-9

解析如何讀取文件形成InputSplit - CSDN博客

InputFormat 並沒有實現RecordReader  ,只是實現了文件的分片FileSplit。...2.x默認的block大小是128MB,Hadoop 1.x默認的block大小是64MB,可以在hdfs-...
  • 2018-4-14
廣告

Hadoop InputFormat定製時必須知道的原理---如何劃分split,split如何調度,如何讀取

在執行一個Job的時候,Hadoop會將輸入數據劃分成N個Split,然後啓動相應的N個Map程序來分別處理它們。 數據如何劃分?Split如何調度(如何決定處理Split的Map程序應該運行在哪臺...
  • chenhuijie666
  • chenhuijie666
  • 2014-05-21 15:55:31
  • 1242

Hadoop中 MapReduce中InputSplit的分析 - CSDN博客

public InputSplit[] getSplits(JobConf job, int numSplits) throwsIOException { //獲取文件列表的狀態,底層通過HDFS客戶端的//DistributedFileSystem.getFileStatus...
  • 2018-4-17

Hadoop InputFormat定製時必須知道的原理---如何劃分sp..._CSDN博客

在第3步中,JobClient向HDFS提交的資源就包含了InputSplit,這就是數據劃分的結果。也就是說,數據劃分是在JobClient上完成的。在這裏,JobClient會使用指定的InputForm...
  • 2018-3-23

hadoop 文件分塊,block與split關係

  • soony_007
  • soony_007
  • 2013-10-09 19:57:36
  • 3997
hadoop的分塊有兩部分,其中第一部分更爲人熟知一點。   第一部分就是數據的劃分(即把File劃分成Block),這個是物理上真真實實的進行了劃分,數據文件上傳到HDFS裏的時候,需要劃分成一...

hadoop block split 區別

  • baolibin528
  • baolibin528
  • 2015-03-16 15:16:31
  • 695
Hadoop權威指南(第三版)P31 Hadoop divides the input to a MapReduce job into fixed-size pieces called inpu...

Hadoop源碼解析之: TextInputFormat如何處理跨split的行 - CSDN博客

我們知道hadoop將數據給到map進行處理前會使用InputFormat對數據進行兩方面的預處理: 對輸入數據進行切分,生成一組split,一個split會分發給一個mapper進行處理。 針對...
  • 2018-4-5

MapReduce中InputFormat和InputSplit解讀 - CSDN博客

(job)要操作的數據保存在文件系統HDFS上,InputFormat接口定義的方法就是如何讀取...        InputSplit是Hadoop定義的用來傳送給每個單獨的map的...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章