一个磁盘有它的块大小,代表着它能够读写的最小数据量。文件系统通过处理大小为一个磁盘块大小的整数倍数的数据块来运作这个磁盘。文件系统块一般为几千字节,而磁盘块一般为512个字节。这些信息,对于仅仅在一个文件上读或写任意长度的文件系统用户来说是透明的。但是,有些工具会维护文件系统,如df 和 fsck, 它们都在系统块级上操作。
HDFS也有块的概念,不过是更大的单元,默认为64 MB。与单一磁盘上的文件系统相似,HDFS上的文件也被分为以块为大小的分块,作为单独的单元存储。但与其不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间。如果没有特殊指出,"块"在本书中就指代HDFS中的块。
为何HDFS中的一个块那么大?
HDFS的块比磁盘的块大,目的是为了减小寻址开销。通过让一个块足够大,从磁盘转移数据的时间能够远远大于定位这个块开始端的时间。因此,传送一个由多个块组成的文件的时间就取决于磁盘传输送率。
我们来做一个速算,如果寻址时间在10毫秒左右,传输速率是100兆/秒,为了使寻址时间为传输时间的1%,我们需要100 MB左右的块大小。而默认的大小实际为64 MB,尽管很多HDFS设置使用128 MB的块。这一数字将在以后随着新一代磁盘驱动带来的传输速度加快而继续调整。
当然这种假定不应该如此夸张。MapReduce过程中的map任务通常是在一个时间内运行操作一个块,因此如果任务数过于少(少于集群上的节点数量),作业的运行速度显然就比预期的慢。
在分布式文件系统中使用抽象块会带来很多好处。第一个最明显的好处是,一个文件可以大于网络中任意一个磁盘的容量。文件的分块(block,后文有些地方也简称为"块")不需要存储在同一个磁盘上,因此它们可以利用集群上的任意一个磁盘。其实,虽然不常见,但对于HDFS集群而言,也可以存储一个其分块占满集群中所有磁盘的文件。
第二个好处是,使用块抽象单元而不是文件会简化存储子系统。简单化是所有系统的追求,但对于故障种类繁多的分布式系统来说尤为重要的。存储子系统控制的是块,简化了存储管理。(因为块的大小固定,计算一个磁盘能存多少块就相对容易),也消除了对元数据的顾虑(块只是一部分存储的数据-而文件的元数据,如许可信息,不需要与块一同存储,这样一来,其他系统就可以正交地管理元数据。)
不仅如此,块很适合于为提供容错和实用性而做的复制操作。为了应对损坏的块以及磁盘或机器的故障,每个块都在少数其他分散的机器(一般为3个)进行复制。如果一个块损坏了,系统会在其他地方读取另一个副本,而这个过程是对用户透明的。一个因损坏或机器故障而丢失的块会从其他候选地点复制到正常运行的机器上,以保证副本的数量回到正常水平。(参见第4章的"数据的完整性"小节,进一步了解如何应对数据损坏。)同样,有些应用程序可能选择为热门的文件块设置更高的副本数量以提高集群的读取负载量。
与磁盘文件系统相似,HDFS中 fsck 指令会显示块的信息。例如,执行以下命令将列出文件系统中组成各个文件的块:
1. % hadoop fsck / -files -blocks