一般情况下,任何磁盘都有‘最小读写单位’的概念,可以理解为该磁盘的‘block’。建立在该磁盘之上的文件系统也有‘block’的概念,一般为磁盘‘block’大小的整数倍。对于用户来说,这些读写限制都是透明的。(即,用户感觉自己可以读写任意大小的文件。)然而有些应用则是运行在文件系统block层级的,可以感知到block的存在,比如 df 和 fsck。
HDFS 作为一种文件系统,当然也需要有‘block’的概念。不过HDFS的block一般比较大,默认为128MB。与普通的管理单个磁盘的文件系统一样,HDFS也将文件分割成block,每个block都作为一个独立的单元分别保存。不同点在于,在HDFS中,小于block的文件不会占用一个block的空间。(比如,文件大小为1MB,那么它会占用一个HDFS的block,但是只使用底层磁盘1MB的空间,而不是128MB。)
为什么HDFS的block相较于传统文件系统来说大很多 因为HDFS的的一个设计目标就是能够快速读取。而对于磁盘来说,读取一个数据块涉及到三种时间开销,寻道时间、旋转时间和传输时间。传输时间是磁盘本身的特性,不可能通过人工手段来改变,但是对于寻道时间和旋转时间,则可以通过增大一次读取的数据量来减少寻道和旋转的次数。这样的话,就可以将读取数据的速率设计为接近真实的磁盘传输速率。
举个例子,假设某磁盘的寻道时间和旋转时间之和为10ms,传输速率为100MB/s。那么,如果想设计一种读取方式让寻道时间与旋转时间总和 不高于总读取时间的1%的话,则需要将block的大小设置为100MB。
当然,这个观点不可能长期成立。在MapReduce中,一个Map任务一般一次只处理一个block。那么,当Map任务的数量少于集群中节点的个数时,完成此job所需时间就会慢于其他情况。 |
对分布式文件系统进行块级抽象(block)有诸多好处。最大的好处就是可以存储非常大的文件,即文件大小大于单机磁盘。理论上来说,HDFS可以存放下一个文件大小等于集群内所有机器磁盘大小总和的文件。另外,将文件分割为block会使得文件系统的组织方式更加简单。相比于以文件方式分割大文件,block只是固定大小的数据块,即不需要存储元数据,也能够非常容易的计算出一个磁盘上能够保存几个block。通俗来讲就是越简单越好。还有一个优点,就是固定大小的block可以非常容易得进行冗余存储。为防止因为机器挂掉而损失数据,必须将block复制多份,分别保存在不同的机器上。如果其中一个复制块数据损坏了,可以从其他复制块中恢复,如果一个机器挂了,则可以将本台机器上原来存储的block复制存储到其他可用的机器上来确保复制份数维持安全水平。复制冗余块到多个节点上还可以用来分散读取压力,将经常被访问的文件多复制几份到其他机器上,就可以提高集群处理访问的能力。
HDFS的管理命令也与普通文件系统非常相似,比如下边这条命令可以列出HDFS中文件与block的对应关系:
% hdfs fsck / -files -blocks