(一)传统的网络文件系统NFS
传统的网络文件系统(NFS)虽然也称为分布式文件系统,但是其存在一些限制。由于NFS中,文件是存储在单机上,因此无法提供可靠性保证,当很多客户端同时访问NFS Server时,很容易造成服务器压力,造成性能瓶颈。另外如果要对NFS中的文件进行操作,需要首先同步到本地,这些修改在同步到服务端之前,其他客户端是不可见的。某种程度上,NFS不是一种典型的分布式系统,虽然它的文件的确放在远端(单一)的服务器上面。
从NFS的协议栈可以看到,它事实上是一种VFS(操作系统对文件的一种抽象)实现。
HDFS,是Hadoop Distributed File System的简称,是Hadoop抽象文件系统的一种实现。Hadoop抽象文件系统可以与本地系统、Amazon S3等集成,甚至可以通过Web协议(webhsfs)来操作。HDFS的文件分布在集群机器上,同时提供副本进行容错及可靠性保证。例如客户端写入读取文件的直接操作都是分布在集群各个机器上的,没有单点性能压力。
(二)HDFS的设计
● 超大文件
这里非常大指的是几百M、G、或者TB级别。实际应用中已有很多集群存储的数据达到PB级别。
● 流式数据访问
HDFS基于这样的一个假设:最有效的数据处理模式是一次写入、多次读取数据集经常从数据源生成或者拷贝一次,然后在其上做很多分析工作,分析工作经常读取其中的大部分数据,即使不是全部。 因此读取整个数据集所需时间比读取第一条记录的延时更重要。
● 商用硬件
Hadoop不需要特别贵的、reliable的(可靠的)机器,可运行于普通商用机器(可以从多家供应商采购) ,商用机器不代表低端机器。在集群中(尤其是大的集群),节点失败率是比较高的HDFS的目标是确保集群在节点失败的时候不会让用户感觉到明显的中断。
● 延时的数据访问(瓶颈)
对延时要求在毫秒级别的应用,不适合采用HDFS。HDFS是为高吞吐数据传输设计的,因此可能牺牲延时HBase更适合低延时的数据访问。
● 大量的小文件(瓶颈)
文件的元数据(如目录结构,文件block的节点列表,block-node mapping)保存在NameNode的内存中, 整个文件系统的文件数量会受限于NameNode的内存大小。
经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间。如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存。因此十亿级别的文件数量在现有商用机器上难以支持。
● 多方读写,需要任意的文件修改
(三)HDFS的概念
● Blocks(数据块)
物理磁盘中有块的概念,磁盘的物理Block是磁盘操作最小的单元,读写操作均以Block为最小单元,一般为512 Byte。文件系统在物理Block之上抽象了另一层概念,文件系统Block物理磁盘Block的整数倍。通常为几 KB。Hadoop提供的df、fsck这类运维工具都是在文件系统的Block级别上进行操作。
HDFS的Block块比一般单机文件系统大得多,默认为128M。HDFS的文件被拆分成多个分块(chunk),chunk作为独立单元存储。比Block小的文件不会占用整个Block,只会占据实际大小。例如, 如果一个文件大小为1M,则在HDFS中只会占用1M的空间,而不是128M。
● HDFS中的块为什么那么大?
最小化寻址开销
但是块的大小不是越大越好,MapReduce中的map任务通常一次只处理一个块的数据,因此如果任务数太少(小于集群中的节点数量)作业的运行速度就会比较慢。
● Block抽象的好处
block的拆分使得单个文件大小可以大于整个磁盘的容量,构成文件的Block可以分布在整个集群, 理论上,单个文件可以占据集群中所有机器的磁盘。
Block的抽象也简化了存储系统,对于Block,无需关注其权限,所有者等内容(这些内容都在文件级别上进行控制)。
Block作为容错和高可用机制中的副本单元,即以Block为单位进行复制。
(四)Namenode 和 Datanode
整个HDFS集群由Namenode和Datanode构成master-worker(主从)模式。Namenode负责构建命名空间,管理文件的元数据等,而Datanode负责实际存储数据,负责读写工作。
● Namenode
存放文件系统树以及整颗树内所有的文件和目录。如存储文件的元数据如文件名,文件目录结构,文件属性(生成时间,副本数文件权限)命名空间,这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件(namespcae image)和编辑日志文件(edit log)
namenode也记录着每个文件中各个块所在的数据节点信息,但它并不永久保存块的位置信息,因为这些信息会在系统启动时根据数据节点信息创建。
在HDFS中,Namenode可能成为集群的单点故障,Namenode不可用时,整个文件系统是不可用的。HDFS针对单点故障提供了2种解决机制:
备份持久化元数据 将文件系统的元数据同时写到多个文件系统, 例如同时将元数据写到本地文件系统及NFS。这些备份操作都是同步的、原子的。
2)Secondary Namenode
Secondary Namenode节点定期合并主Namenode的namespace
image和edit log,避免edit log过大,这个Secondary Namenode一般在另一台单独的物理机器上运行,因为它需要占用大量CPU时间,并且需要与namenode一样多的内存来执行合并操作,它会保存合并后的命名空间镜像副本,并在namenode发生故障时启用。但是Secondary Namenode的保存是滞后于主节点,所以主节点全部失效,难免会丢失部分数据。这种情况下一般把存储在NFS上的namenode元数据复制到secondary namenode并作为新的主namenode运行。后面介绍高可用HA热备份
● Datanode
Datanode负责存储文件块数据、块数据的校验和和提取Block,读写请求可能来自namenode,也可能直接来自客户端。数据节点周期性向Namenode汇报自己节点上所存储的Block相关信息。
● 块缓存
通常DataNode从磁盘中读取数据块,但是对于频繁访问的文件,其对应的块可能被显示地缓存在DataNode的内存中,以堆外块缓存的形式存在。默认情况下一个块仅缓存在一个DataNode的内存中,也可以指定。作业调度器(用于MapReduce、spark和其他框架)通过在缓存块的DataNode上运行任务,可以利用块缓存的优势提高读写操作性能。
●
namenode在内存中保存文件系统中每个问和每个数据块的引用关系。这意味着对于一个拥有大量文件的超大集群来说,内存将成为限制系统横向扩展的瓶颈。
联邦HDFS允许系统通过添加namenode实现拓展,其中每个namenode管理文件系统命名空间中的一部分。
在联邦环境下,每个namenode 维护一个命名空间卷(namespace volumn)由命名空间的元数据和一个数据块池组成。命名空间卷之间是互相独立的,不互相通信,因此集群中的datanode需要注册到每个namenode,并且储存着来自多个数据块池中的数据块。