1 Block
當我們把文件上傳到HDFS時埃仪,文件會被分塊,這個是真實物理上的劃分佩脊。每塊的大小可以通過hadoop-default.xml里配置選項進行設置润梯。系統(tǒng)也提供默認大小,其中Hadoop 1.x中的默認大小為64M社牲,而Hadoop 2.x中的默認大小為128M粪薛。每個Block分別存儲在多個DataNode上(默認是3個),用于數(shù)據(jù)備份進而提供數(shù)據(jù)容錯能力和提高可用性搏恤。?
在很多分布式文件系統(tǒng)中我們都可以看到Block的存在汗菜,這種設計的優(yōu)點是:
存儲的文件大小可以大于集群中任意一個磁盤的容量。這很好理解挑社,文件被劃分到多個Block中存儲,對磁盤透明巡揍;
使用Block抽象而非整個文件作為存儲單元痛阻,可以極大簡化存儲子系統(tǒng)的設計。因為Block size是統(tǒng)一的腮敌,因此一個節(jié)點上可以存儲多少Block就是可以推算的阱当;
Block 非常適合用于數(shù)據(jù)備份俏扩,進而提供數(shù)據(jù)容錯能力和可用性。
同樣在磁盤中弊添,每個磁盤都有默認的數(shù)據(jù)塊大小录淡,這是磁盤進行數(shù)據(jù)讀/寫的最小單位,磁盤塊一般為512字節(jié)油坝。但是在分布式文件系統(tǒng)中數(shù)據(jù)塊一般遠大于磁盤數(shù)據(jù)塊的大小嫉戚,并且為磁盤塊大小的整數(shù)倍,例如HDFS Block size默認為64MB澈圈。
分布式存儲系統(tǒng)中選擇大Block size的主要原因是為了最小化尋址開銷彬檀,使得磁盤傳輸數(shù)據(jù)的時間可以明顯大于定位這個塊所需的時間。然而瞬女,在HDFS中Block size也不好設置的過大窍帝,這是因為MapReduce中的map任務通常一次處理一個塊中的數(shù)據(jù),因此如果Block太大诽偷,則map數(shù)就會減少坤学,作業(yè)運行的并行度就會受到影響,速度就會較慢报慕。
如果一個HDFS上的文件大小(file size) 小于塊大小(block size) 深浮,那么HDFS會實際占用Linux file system的多大空間??
答案是實際的文件大小卖子,而非一個塊的大小略号。
2 Split
split 是邏輯意義上的split。 通常在 M/R 程序或者其他數(shù)據(jù)處理技術上用到洋闽。根據(jù)你處理的數(shù)據(jù)量的情況玄柠,split size是允許用戶自定義的。?
split size 定義好了之后诫舅,可以控制 M/R 中 Mapper 的數(shù)量羽利。如果M/R中沒有定義 split size , 就用默認的HDFS配置作為 input split刊懈。?
輸入分片(Input Split):在進行map計算之前这弧,mapreduce會根據(jù)輸入文件計算輸入分片(input split),每個輸入分片(input split)針對一個map任務虚汛,輸入分片(input split)存儲的并非數(shù)據(jù)本身匾浪,而是一個分片長度和一個記錄數(shù)據(jù)的位置的數(shù)組。
通常一個split就是一個block(FileInputFormat僅僅拆分比block大的文件)卷哩,這樣做的好處是使得Map可以在存儲有當前數(shù)據(jù)的節(jié)點上運行本地的任務蛋辈,而不需要通過網(wǎng)絡進行跨節(jié)點的任務調(diào)度。
通過mapred.min.split.size,?mapred.max.split.size,?block.size來控制拆分的大小冷溶。
如果mapred.min.split.size大于block size渐白,則會將兩個block合成到一個split,這樣有部分block數(shù)據(jù)需要通過網(wǎng)絡讀取逞频。
如果mapred.max.split.size小于block size纯衍,則會將一個block拆成多個split,增加了Map任務數(shù)苗胀。
先獲取文件在HDFS上的路徑和Block信息襟诸,然后根據(jù)splitSize對文件進行切分(splitSize = computeSplitSize(blockSize, minSize, maxSize)),默認splitSize 就等于blockSize的默認值(64m)柒巫。
3 總結
block是物理上的數(shù)據(jù)分割励堡,而split是邏輯上的分割。
如果沒有特別指定堡掏,split size 就等于 HDFS 的 block size 应结。
用戶可以在M/R 程序中自定義split size。
一個split 可以包含多個blocks泉唁,也可以把一個block應用多個split操作鹅龄。
有多少個split,就有多少個mapper亭畜。