Hadoop分塊與分片
HDFS儲存系統中,引入了檔案系統的分塊概念(block),塊是儲存的最小單位,HDFS定義其大小為64MB。與單磁碟檔案系統相似,儲存在 HDFS上的檔案均儲存為多個塊,不同的是,如果某檔案大小沒有到達64MB,該檔案也不會佔據整個塊空間。在分散式的HDFS叢集上,Hadoop系統 保證一個塊儲存在一個datanode上。
當我們執行hadoop fs -put aa.txt /bb.txt,則aa.txt會被複製為叢集的/bb.txt。檢視系統的log日誌hadoop-$username-namenode-*.log,可以看到類似於
2011-09-07 08:39:12,506 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.addStoredBlock: blockMap updated: 127.
0.0.1:50010 is added to blk_5715489406767973176_1455 size 32
這樣的資訊,裡面記錄有分配block的元資料資訊和block號(blk_5715489406767973176)。
在另一個日誌中hadoop-$username-datanode-*.log可以看到對應的datanode打印出相應的log:
2011-09-07 08:39:12,495 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Receiving block blk_5715489406767973176_145
5 src: /127.0.0.1:48492 dest: /127.0.0.1:50010
HDFS的namenode只儲存整個檔案系統的元資料映象,這個映象由配置dfs.name.dir指定,datanode則存有檔案的metainfo和具體的分塊,儲存路徑由dfs.data.dir指定。
分析完畢分塊,下面討論一下分片:
hadoop的作業在提交過程中,需要把具體的輸入進行分片。具體的分片細節由InputSplitFormat指定。分片的規則為 FileInputFormat.class中的getSplits()方法指定:
long splitSize = computeSplitSize(goalSize, minSize, blockSize);
computeSplitSize:
Math.max(minSize, Math.min(goalSize, blockSize));
其中goalSize為“InputFile大小”/“我們在配置檔案中定義的mapred.map.tasks”值,minsize為mapred.min.split.size,blockSize為64,所以,這個算式為取分片大小不大於block,並且不小於在mapred.min.split.size配置中定義的最小Size。
當某個分塊分成均等的若干分片時,會有最後一個分片大小小於定義的分片大小,則該分片獨立成為一個分片。