块(block)的大小可以通过设置HADOOP_HOME/etc/hadoop/hdfs-site.xml中dfs.blocksize来实现;
在Hadoop2.x的版本中,文件块的默认大小是128M,老版本中默认是64M;
原理:
文件块越大,寻址时间越短,但磁盘传输时间越长;
文件块越小,寻址时间越长,但磁盘传输时间越短。

block大小设置原则:
减少硬盘寻道时间(disk seek time):HDFS的设计是为了支持大数据操作,合适的block大小有助于减少硬盘寻道时间(平衡了硬盘寻道时间、IO时间),提高系统吞吐量。
减少NameNode内存消耗:NameNode需要在内存FSImage文件中记录DataNode中数据块信息,若block size太小,那么需要维护的数据块信息会更多。而HDFS只有一个NameNode节点,内存是极其有限的。
map崩溃问题:若Map任务崩溃,重新启动执行需要重新加载数据,数据块越大,数据加载时间将越长,恢复时间越长。
监管时间问题:主节点监管其他节点的情况,每个节点会周期性的把完成的工作和状态的更新报告回来。若某个节点保存沉默超过预设的时间间隔,主节点“宣告”该节点状态为死亡,并把分配给这个节点的数据发到别的节点。预设的时间间隔是根据数据块 size角度估算的,若size设置不合理,容易误判节点死亡。
约束Map任务输出:MapReduce框架中Map任务输出的结果是要经过排序才给reduce函数操作的。在Map任务的merge on disk和Reduce任务中合并溢写生的文件,用到归并排序算法,对小文件进行排序,然后将小文件归并成大文件。
网络传输问题: 在数据读写计算的时候,需要进行网络传输.如果block过大会导致网络传输时间增长,程序卡顿/超时/无响应. 任务执行的过程中拉取其他节点的block或者失败重试的成本会过高.如果block过小,则会频繁的进行文件传输,对严重占用网络/CPU资源。

为什么block不能过大或者过小?

  1. 如果块设置过大,
    一方面,从磁盘传输数据的时间会明显大于寻址时间,导致程序在处理这块数据时,变得非常慢;
    另一方面,mapreduce中的map任务通常一次只处理一个块中的数据,如果块过大运行速度也会很慢。
  2. 如果块设置过小,
    一方面存放大量小文件会占用NameNode中大量内存来存储元数据,而NameNode的内存是有限的,不可取;
    另一方面文件块过小,寻址时间增大,导致程序一直在找block的开始位置。
    因而,块适当设置大一些,减少寻址时间,那么传输一个由多个块组成的文件的时间主要取决于磁盘的传输速率。

Q:HDFS中块(block)的大小为什么设置为128M?

  1. HDFS中平均寻址时间大概为10ms;
  2. 经过前人的大量测试发现,寻址时间为传输时间的1%时,为最佳状态;
    所以最佳传输时间为10ms/0.01=1000ms=1s
  3. 目前磁盘的传输速率普遍为100MB/s;
    计算出最佳block大小:100MB/s x 1s = 100MB
    所以我们设定block大小为128MB。

ps:实际在工业生产中,磁盘传输速率为200MB/s时,一般设定block大小为256MB
磁盘传输速率为400MB/s时,一般设定block大小为512MB;