1、数据块(block)
数据块是磁盘读/写的最小单位,每个磁盘都有默认的数据块大小。HDFS作为分布式文件系统也有块的概念,但是数据块比较大,默认128MB。与磁盘上的文件系统相似,HDFS上的文件也被划分为块大小的多个分块(chunk),作为存储单元。但HDFS中小于128MB的文件不会占用整个块的空间。(如1MB的文件存在一个128MB的块中,文件只占用1MB,而不是128MB)
为什么HDFS中的块是128MB,这么大?
HDFS中的块比磁盘的块大很多,其目的是为了最小化寻址开销。
不宜过小,因为namenode中存储了文件、文件块等元信息,块很小的话,元信息变大,namenode的内存需求就变大。
不宜过大,因为MapReduce中的map任务通常一次只处理一个块中的数据。块越大,map任务数越小,如果任务数过少(少于集群中的节点数量),任务的运行效率就是降低。
对分布式文件系统中的“块”进行抽象带来的好处
一个文件的大小可以大于网络中任意一个磁盘的容量。因为一个大文件的所有块并不需要存储在一个磁盘上,可以在集群的任意一个磁盘上进行存储。
使用抽象块而不是使用整个文件作为存储单元,简化了存储系统的设计。如简化了存储管理,块大小是固定的,计算一个磁盘能存储多少个块比较容易。
块非常适合用于数据备份进而提供数据容错能力和提高可用性。HDFS中默认一个块有三个副本,确保在块、磁盘或机器发生问题时数据不会丢失。
可以为一些常用的文件设置更多的副本数来提高读取效率。
2、namenode 和 datanode
HDFS集群运行的节点有两类:管理节点(namenode)和工作节点(datanode)。
namenode
namenode负责管理文件系统的命名空间。
负责维护文件系统树及整个树内所有的文件和目录。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件。
记录着每个文件中各个块所在的数据节点信息,但并不是永久保存块的位置信息。系统在启动时,datanode会向namenode汇报,namenode根据汇报重建这些信息。
datanode
datanode是文件系统的工作节点。
datanode根据客户端或namenode的需要存储并检索数据块。
定期向namenode发送自己所存储的块的列表。
3、块缓存
通常datanode都是从磁盘中读取块。对于访问很频繁的文件,其对应的块可以被显示的缓存在datanode的内存中,以堆外缓存(off-heap block cache)的形式存在。默认是一个块仅缓存在一个datanode的内存中,也可以根据每个文件配置datanode的数量,来提高读操作性能。
4、联邦HDFS(federation)
namenode在内存中保存文件系统中每个文件和每个数据块的引用关系,对于一个拥有大量文件的超大集群来说,内存将成为限制系统横向扩展的瓶颈。
在Hadoop2.x发行版中引入了联邦HDFS,允许系统通过添加namenode实现扩展,每个namenode管理文件系统命名空间中的一部分。如一个namenode管理/user目录下文件,另一个namenode管理/share目录下的文件。
namespace volume
在联邦环境下,每个namenode维护一个命名空间卷(namespace volume),由命名空间的元数据和一个数据块池(block pool)组成,数据块池包含该命名空间下文件的所有数据块。
命名空间卷之间相互独立,两两互补通信。一个失效也不影响其他。因此集群中的datanode要注册到每个namenode,并且存储来自多个数据块池中的数据块。
5 、HDFS的高可用
Hadoop2 增加了对HDFS高可用性的支持。
第一种配置了一对 活动-备用(active-standby)namenode。当active namenode失效后,standby namenode就会接管它的任务并开始服务来自客户端的请求,对客户端来说不会有明显的中断。
第二种通过federation机制也就是联邦HDFS可以将多个namenode组成一个集群,外部可通过viewfs://URI来访问。Hadoop会通过你访问的路径来自动选择集群。