Hadoop自带一个称为HDFS 的分布式文件系统,即Hadoop Distributed Filesystem。有时也简称为DFS。HDFS以流式数据访问模式来分布式存储超大文件,运行于廉价商用硬件集群上。
1.HDFS存储特点
- 超大文件 “超大文件” 在这里指具有几百MB、几百GB甚至几百TB大小的文件。目前已经有存储PB级数据的Hadoop集群了。
- 流式数据访问 数据是存储在各个节点上,当你需要使用数据集,一般是分别读取部分数据就开始处理,而不需要加载完所有数据才开始处理。
- 硬件要求低 Hadoop并不需要运行在昂贵且高可靠的硬件上。它是设计运行在商用硬件(在各种零售店都能买到的普通硬件”)的集群上的,因此至少对于庞大的集群来说,节点故障的几率还是非常高的。HDFS遇到上述故障时,被设计成能够继续运行且不让用户察觉到明显的中断。
- 时间延迟的数据访问 HDFS 是为高数据吞吐量应用优化的,这可能会以提高时间延迟为代价。目前,对于低延迟的访问需求,HBase(参见第20章)是更好的选择。
- 小文件的限制 hdfs是将大文件以数据块的方式存储到datanode,由于namenode将文件系统的元数据存储在内存中,因此该文件系统所能存储的文件总数受限于namenode的内存容量。根据经验,每个文件、目录和数据块的存储信息大约占150字节。因此,举例来说,如果有一百万个文件,且每个文件占一个数据块,那至少需要300 MB的内存。尽管存储,上百万个文件是可行的,但是存储数十亿个文件就超出了当前硬件的能力。
- 单用户写文件 HDFS 中的文件写入只支持单个写入者,注意这里说的是单个文件,而且写操作总是以“只添加”方式在文件末尾写数据。它不支持多个写入者的操作,也不支持在文件的任意位置进行修改。可能以后会支持这些操。
2.HDFS 数据块
磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位。构建于单个磁盘之上的文件系统通过磁盘块来管理该文件系统中的块,该文件系统块的大小可以是磁盘块的整数倍。文件系统块一般为几千字节,而磁盘块一般为512 字节。这些信息(文件系统块大小)对于需要读/写文件的文件系统用户来说是透明的。
HDFS同样也有块(block)的概念,但是大得多,默认为128 MB。与单一磁盘上的文件系统相似,HDFS上的文件也被划分为块大小的多个分块(chunk),作为独立的存储单元。但与面向单一磁盘的文件系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间(例如,当一个1MB的文件存储在一个128MB 的块中时,文件只使用1 MB的磁盘空间,而不是128 MB)。
HDFS的块比磁盘的块大,其目的是为了最小化寻址开销。如果块足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个块组成的大文件的时间取决于磁盘传输速率。
分布式系统使用块抽象的优点:
- 第一个最明显的好处是,一个文件的大小可以大于网络中任意一个磁盘的容量。文件的所有块并不需要存储在同一个磁盘上,因此它们可以利用集群上的任意-
- 第二个好处是,使用抽象块而非整个文件作为存储单元,大大简化了存储子系统的设计。简化是所有系统的目标,但是这对于故障种类繁多的分布式系统来说尤为重要。将存储子系统的处理对象设置为块,可简化存储管理(由于块的大小是固定的,因此计算单个磁盘能存储多少个块就相对容易)。同时也消除了对元数据的顾虑(块只是要存储的大块数据,而文件的元数据,如权限信息,并不需要与块一同存储,这样一来,其他系统就可以单独管理这些元数据)。
- 不仅如此,块还非常适合用于数据备份进而提供数据容错能力和提高可用性。
3.HDFS 块缓存
通常datanode 从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显式地缓存在datanode的内存中,以堆外块缓存(off-heap block cache)的形式存在。默认情况下,一个块仅缓存在一个datanode 的内存中,当然可以对每个文件配置datanode的数量。作业调度器(用于MapReduce、Spark 和其他框架的)通过在缓存块的datanode 上运行任务,可以利用块缓存的优势提高读操作的性能。
与磁盘文件系统相似,HDFS中fsck 指令可以显示块信息。
% hdfs fsck / -files -blocks