请教hdfs文件分块的问题
刚学习hadoop不久,有一些疑问,一直没有搞懂,希望高手帮忙解答下。
想问一下,在完全分布模式下,put一个文件到hdfs系统后,比如1G的数据文件, 上传后,这个文件会在上传目标目录中存一份的同时,是否就会开始进行分块,比如按64M 分块,然后把每块存到datanode上?
但是我看 http://www.aboutyun.com/thread-6794-1-1.html , 这个里面写文件的流程是:
文件写入
Client向NameNode发起文件写入的请求。
NameNode根据文件大小和文件块配置情况,返回给Client它所管理部分DataNode的信息。
Client将文件划分为多个Block,根据DataNode的地址信息,按顺序写入到每一个DataNode块中
也就是,分块是client来完成的。 如果是这样,请问client怎么分块,一般用什么技术分块?
分块后,存到哪个datanode上,是基于什么规则?
比如默认保存3个备份的情况下,第1,2备份是保存在某一个机架,第3备份是保存在另外一个机架,对吧。
但是,具体保存在哪个机器上,是基于什么规则呢,是完全随机分布吗?还是有什么hash规则?
分块不复杂的,就像切菜一样,直接分割即可
每块的大小由hadoop-default.xml里配置选项进行划分。
<property>
<name>dfs.block.size</name>
<value>67108864</value>
<description>The default block size for new files.</description>
</property>
这个就是默认的每个块64MB。
数据划分的时候有冗余,个数是由
<property>
<name>dfs.replication</name>
<value>3</value>
<description>Default block replication.
The actual number of replications can be specified when the file is created.
The default is used if replication is not specified in create time.
</description>
</property>
指定的。
具体由InputFormat这个接口来定义的,其中有个getSplits方法
#############################################
FileInputFormat(最常见的InputFormat实现)的getSplits方法中,首先会计算totalSize=8(可以对照源码看看,注意getSplits这个函数里的计量单位是Block个数,而不是Byte个数,后面有个变量叫bytesremaining仍然表示剩余的Block个数,有些变量名让人无语),然后会计算goalSize=totalSize/numSplits=4,对于File1,计算一个Split有多少个Block是这样计算的
long splitSize = computeSplitSize(goalSize, minSize, blockSize);
protected long computeSplitSize(long goalSize, long minSize, long blockSize) {
return Math.max(minSize, Math.min(goalSize, blockSize));
}
这里minSize是1(说明了一个Split至少包含一个Block,不会出现一个Split包含零点几个Block的情况),计算得出splitSize=4,所以接下来Split划分是这样分的:
Split 1: Block11, Block12, Block13,Block14
Split 2: Block15
Split 3: Block21, Block22, Block23
那用户指定的map个数是2,出现了三个split怎么办?在JobInProgress里其实maptasks的个数是根据Splits的长度来指定的,所以用户指定的map个数只是个参考。可以参看JobInProgress: initTasks()
里的代码:
try {
splits = JobClient.readSplitFile(splitFile);
} finally {
splitFile.close();
}
numMapTasks = splits.length;
maps = new TaskInProgress;
所以问题就很清晰了,还如果用户指定了20个map作业,那么最后会有8个Split(每个Split一个Block),所以最后实际上就有8个MapTasks,也就是说maptask的个数是由splits的长度决定的。
页:
[1]