分享

请教hdfs文件分块的问题

hellom 发表于 2015-8-12 18:07:26 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 32799


刚学习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规则?


已有(1)人评论

跳转到指定楼层
tntzbzc 发表于 2015-8-12 18:59:39
分块不复杂的,就像切菜一样,直接分割即可
每块的大小由hadoop-default.xml里配置选项进行划分。

[mw_shl_code=bash,true]<property>
  <name>dfs.block.size</name>
  <value>67108864</value>
  <description>The default block size for new files.</description>
</property>[/mw_shl_code]

这个就是默认的每个块64MB。
数据划分的时候有冗余,个数是由
[mw_shl_code=bash,true]<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>[/mw_shl_code]
指定的。



具体由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[numMapTasks];

所以问题就很清晰了,还如果用户指定了20个map作业,那么最后会有8个Split(每个Split一个Block),所以最后实际上就有8个MapTasks,也就是说maptask的个数是由splits的长度决定的。







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条