导航

HDFS与小文件相关

Posted on 2011-11-23 08:26  清风无尘  阅读(967)  评论(0编辑  收藏  举报

HDFS也有块(Block)的概念,但它的块是一个很大的单元,默认是64MB。像硬盘中的文件系统一样,在HDFS中的文件将会按块大小进行分解,并作为独立的单元进行存储。但和硬盘中的文件系统不一样的是,存储在块中的一个比块小的文件并不会占据一个块大小的硬盘物理空间(HDFS中一个块只存储一个文件的内容)。
  那为什么HDFS中的块如此之大呢?
  HDFS的块之所以这么大,主要原因就是为了把寻道(Seek)时间最小化。如果一个块足够大,那么从硬盘传输数据的时间将远远大于寻找块的起始位置的时间。这样就使得HDFS的数据传输速度和硬盘的传输速度更加接近。
让我们来个简单的计算,假设寻道时间大约为10ms,传输速度为100MB/s。为了使得寻道时间仅为传输时间的1%,我们就需要设置块的大小为100MB。尽管很多应用的HDFS使用128MB的块,但默认的大小是64MB,这个参数将随着新一代硬盘速度的增长而增长。
  虽然大块有一定好处,但也不能太大。MR中的Map tasks一般一次只处理一个块,所以如果你的tasks太少了(少于你集群中的节点数),相对于设置较小块的Jobs来说,你的Jobs将会运行得比较慢。

 

大量小文件
  因为Namenode把文件系统的元数据放置在内存中,所以文件系统所能容纳的文件数目是由Namenode的内存大小来决定。一般来说,每一个文件、文件夹和Block需要占据150字节左右的空间,所以,如果你有100万个文件,每一个占据一个Block,你就至少需要300MB内存。当前来说,数百万的文件还是可行的,当扩展到数十亿时,对于当前的硬件水平来说就没法实现了。还有一个问题就是,因为Map task的数量是由splits来决定的,所以用MR处理大量的小文件时,就会产生过多的Map task,线程管理开销将会增加作业时间。举个例子,处理10000M的文件,若每个split为1M,那就会有10000个Map tasks,会有很大的线程开销;若每个split为100M,则只有100个Map tasks,每个Map task将会有更多的事情做,而线程的管理开销也将减小很多。
  要想让HDFS能处理好小文件,有不少方法:

  1. 利用SequenceFile、MapFile、Har等方式归档小文件,这个方法的原理就是把小文件归档起来管理,HBase就是基于此的。对于这种方法,如果想找回原来的小文件内容,那就必须得知道与归档文件的映射关系
  2. 横向扩展,一个Hadoop集群能管理的小文件有限,那就把几个Hadoop集群拖在一个虚拟服务器后面,形成一个大的Hadoop集群。google也是这么干过的
  3. 多Master设计,这个作用显而易见了。正在研发中的GFS II也要改为分布式多Master设计,还支持Master的Failover,而且Block大小改为1M,有意要调优处理小文件啊。