浅析HDFS

0X00 HDFS的设计

HDFS作为GFS的开源实现,和GFS是高度一致的。在HDFS中有着下面的优点

  1. 对超大文件支持良好,由于其分布式实现,可以存储超大文件,甚至单个文件大小可以超过集群中任意一台机器的磁盘大小
  2. 采用流式数据访问,一次写入、多次读取是最高效的访问模式。因为Hadoop作为一个大数据处理平台,并没有频繁的写入操作,只是在需要的时候一次将大量的数据写入然后在对这些数据进行读操作
  3. Hadoop并不需要运行在昂贵且高可靠的硬件之上,单个节点可能性能可靠性都参差不齐,但是由于其高可靠性的设计,使之能在遇到节点故障时继续运行且不让用户察觉到明显的终端

但是HDFS也不是适用于各种场景,一下的几种场景就不适

  1. 低时间延迟的数据访问,因为HDFS是以时间延迟为代价针对高数据吞吐量优化的,所以HDFS不适用与低延迟的数据访问
  2. 大量的小文件,因为Namenode的设计是将文件系统的元数据存储在内存中的,所以理论上HDFS中的文件最大数量受限于Namenode的内存容量,因此大量的小文件会占用Namenode大量的内存
  3. HDFS目前不支持有多个写入者的操作,也不支持修改文件系统中的文件

0X01 数据块的设计

我们知道在传统的文件系统中就是分块的,寻址开销与分块的大小成负相关,磁盘利用率与分块大小成负相关。且HDFS的设计就是用来处理大文件的,所以将块设计的很大,默认为64MB且好多时候采用的是128MB的设置。

在HDFS中的块设计和传统文件系统有些不同,在传统文件系统中假设一个块为4kb,如果一个文件只有1kb则仍然会占用4kb的空间,但是在HDFS中一个小于块大小的文件并不会占据整个块的空间。

HDFS架构

0X02 Namenode和Datanode

HDFS中有两种节点,Namenode和Datanode。

其中Namenode管理文件系统的命名空间,他维护着文件系统树和整棵树内所有的文件和目录。

其中的Datanode负责存储并检索数据块,且定期向Namenode发送存储的块的列表。

0X03 Namenode容错机制

Namenode有两种常用的容错机制,第一种是实时将自己的操作和文件同步到NFS上,且是原子操作所以NFS上会有和Namenode完全相同的文件。另一种方式是运行一个辅助的Namenode,定期通过编辑日志合并命名空间镜像。

0X04 联邦HDFS

毕竟HDFS是为处理海量数据诞生的,所以避免不了海量的集群来搭建HDFS,但是前面也说过因为设计的问题导致一个拥有大量文件的集群会对Namenode的内存造成严峻的考验,这时候可以使用联邦HDFS来解决。在联邦环境下可以配置多个Namenode,每个Namenode负责维护一个命名空间卷。也就相当于每个Namenode负责一个目录树中的子目录,这样就可以保证在HDFS中有大量文件的时候也不会对Namenode造成太大的威胁。

0X05 高可用性

虽然Namenode有了备份但是还是存在Namenode的单点问题,也就是说当Namenode出现故障之后依旧会对HDFS整个文件系统造成影响,虽然有备份但是还是要等到有下一台Namenode节点上线之后才会运行,所以当时运行的MapReduce等程序依然会终止。针对这种问题Hadoop在2.x中做出了适当的处理。可以配置一对活动-备用的Namenode用于做热备份。

  1. Namenode之间可以共享编辑日志,且使用高可用的方式实现共享存储
  2. Datanode需要同时向两个Namenode发送数据块处理报告,因为要保持两个Namenode完全相同

在这样的配置之下当活动的Namenode故障以后备用的Namenode可以在几十秒内实现任务接管。且在备用的Namenode也失效的情况下还可以通过配置来指定另一台备用Namenode用于做冷启动。