Hadoop源码分析笔记(五):HDFS特点和体系结构

HDFS

        Hadoop是一个能够让用户轻松架构和使用的分布式计算平台,用户可以在Hadoop上管理、开发和运行处理大规模数据的应用,其中,Hadoop分布式文件系统(Hadoop Distributed File System,HDFS)扮演了非常基础的使用,它以文件系统的形式为应用提供海量数据存储服务。

HDFS主要特点

        HDFS作为一个分布式文件系统,具有高容错的特点,它可以部署在廉价的通用硬件上,提供高吞吐率的数据访问,适合那些需要处理海量数据集的应用程序。HDFS提供了一套特有的、基于Hadoop抽象文件系统的API,支持以流的形式访问文件系统中的数据。
       HDFS的主要特性包括:
        1、支持超大文件。
        2、检测和快速应对硬件故障。一般的HDFS系统是由数百台甚至上千台存储着数据文件的服务器组成,这些多的服务器意味着高故障率。因此,故障检测和自动恢复是HDFS的一个设计目标。
       3、流式数据访问。HDFS处理的数据规模都比较大,应用一次需要访问大量的数据。同时,这些应用一般是批量处理,而不是用户交互式处理。HDFS使应用程序能够以流的形式访问数据集,注重的是数据的吞吐量,而不是数据访问的速度。
      4、简化的一致性模型。大部分的HDFS程序操作文件时需要一次写入,多次读取,在HDFS中,一个文件一旦经过创建、写入、关闭后,一般就不需要修改了。这样简单的一致性模型,有利于提供高吞吐量的数据访问模型。
       正因为如此,HDFS并不适合如下应用:
       1、低延迟数据的访问。由于Hadoop针对高数据吞吐量做了优化,而牺牲了获取数据的延迟,对于低延迟访问,可以考虑使用HBase。
       2、大量的小文件。HDFS支持超大文件,是通过将数据分布在数据节点并将文件的元数据保持在名字节点上。名字节点的内存大小,决定了HDFS文件系统可保存的文件数量,虽然现在的系统内存都比较大,但大量的小文件还会影响名字节点的性能。
      3、多用户写入文件、修改文件。HDFS中的文件只能有一个写入者,而且写操作总是在文件末。它不支持多个写入者,也不支持在数据写入后,在文件的任意位置进行修改。
       总之,HDFS是以流失数据访问模式存储超大文件而设计的文件系统,并在普通商用硬件集群上运行。

HDFS体系结构

        为了支持流式数据访问和存储超大文件,HDFS引入了一些比较特殊的设计,在一个全配置的集群上,”运行HDFS“意味着网络分布的不同服务器上运行一些守护进程(Daemon),这些进程有各自的特殊角色,并相互配合,一起形成一个分布式文件系统。
       HDFS采用了主从(Master/Slave)体系机构,名字节点NameNode、数据节点DataNode和客户端Client是HDFS中的3个重要角色。
       名称节点可以看作是分布式文件系统中的管理者,它负责管理文件系统命名空间、集群设置和数据块复制等。
       数据节点是文件存储的基本单元,它以数据块的形式保存了HDFS中文件的内容和数据块的数据块的数据效验信息。
       客户端和名字节点、数据节点通信,访问HDFS文件系统,操作文件。
数据块(Block)
       HDFS是针对大文件设计的分布式系统,使用数据块带来了很多的好处,
       1、HDFS可以保存比存储节点单一磁盘大的文件。
       2、简化了存储子系统。
       3、方便容错,有利于数据复制。在HDFS中,为了应对损坏的块以及磁盘、机器故障,数据块会在不同的机器上进行副本(一般副本数为3,即一份数据保存在3个不同的地方),如果一个数据块副本丢失或者损坏了,系统会在其他地方读取副本,在这个过程对用户来说是透明的,它实现了分布式系统中的位置透明性和故障透明性。同时,一个因损坏或机器故障而丢失的块会从其他地方复制到某一个正常的运行机器上面,以保证副本数据恢复到正常水平。
名字节点(NameNode)和第二名字节点(Secondary NameNode)
        名字节点是从HDFS主从结构中主节点上面运行的主要进程,它指导主从结构中的从节点,数据节点(DataNode)执行底层的I/O任务。
        名字节点是HDFS的书记员,维护着整个文件系统的文件目录树,文件/目录的元信息和文件的数据块索引,即每个文件对应的数据块列表(上述关系也成名字节点第一关系)。这些信息以两种形式存储在本地文件系统中:一种是命名空间镜像(File System Image,FSImage,也称文件系统镜像),另一种是命名空间镜像的编辑日志(EditLog);
        命名空间镜像保持着某一特定时刻HDFS的目录树、元信息和数据块索引等信息,后续对这些信息的改动,则保存在编辑日志中,它们一起提供了一个完整的名字节点第一关节。名字节点中与数据节点相关的信息不保留在名字节点的本地文件系统中,也就是上面提到的命名空间镜像和编辑日志中,名字节点每次启动时,都会动态地重建这些信息,这些信息构成了名字节点第二关系。运行时,客户端通过名字节点获取上述信息,然后和数据节点进行交互,读写文件数据。另外,名字节点还能获取HDFS整形运行状态的一些信息,如系统的可用空间、已经使用的空间、各数据节点的当前状态等。
       第二名字节点是用于定期合并命名空间镜像和镜像编辑日志的辅助守护进程。和名字节点一样,每个集群都有一个第二名字节点,在大规模部署的条件下,一般第二名字也独自占用一台服务器。

        第二名字节点和名字节点的区别在于它不接收或记录HDFS的任何实时变化,而只是根据集群配置的时间间隔,不停地获取HDFS某一个时间点的命名空间镜像和镜像的编辑日志,合并并得到一个新的命名空间镜像,该新镜像会上传到名字节点,替换原有的命名空间镜像,并请空上述日志。应该说,第二名字节点配合名字节点,为名字节点上的第一关系提供了一个简单的检查点机制,并避免出现编辑日志过大,导致名字节点启动时间过长的问题。

数据节点(DataNode)
         HDFS集群上的从节点都会驻留一个数据节点的守护进程,来执行分布式文件系统中最忙碌的部分:将HDFS数据块写到Linux本地文件系统的实际文件中,或者从这些实际文件读取数据块。
         虽然HDFS是为大文件设计,但存放在HDFS上的文件盒传统文件系统类似,也是将文件分块,然后进行存储。但和传统文件系统不同,在数据节点上,HDFS文件块以Linux文件系统上的普通文件进行保存。客户端进行文件内容操作时,先由名字节点告知客户端每个数据块驻留在哪个数据节点,然后客户端直接与数据节点守护进程进行通信,处理与数据块对应的本地文件。同时,数据节点会和其他数据节点进行通信,复制数据块,保证数据的冗余性。
客户端
        客户端是用户和HDFS进行交互的手段,HDFS提供了各种各样的客户端,包括命令行接口,Java API、Thrift接口、C等。
        Hadoop提供了一套和Linux文件命令类似的命令行工具。
        命令行工具提供了访问HDFS的基本能力,HDFS的Java API提供了更进一步的功能。目前,所有访问HDFS的接口都是基于Java API。Java API实现了上一章介绍的Hadoop抽象文件系统,包括DistributedFileSystem和对应的输入和输出流。
         DistributedFileSystem继承自org.apche.hadoop.fs.FileSystem,实现了Hadoop文件系统界面,提供了处理HDFS文件和目录的相关事务,DFSDataInputStream和DFSDataOutputStream分别实现了FSDataInoutStream和FSDataOutputStream,提供了读写HDFS文件的输入/输出流。
         
          
//HDFS Java API实例
Path inPath=new Path("hdfs://:/user/alice/in/hello.txt");
FileSystem hdfs=FileSystem.get(inPath.toUri(),conf);
FSDataOutputStream fout=hdfs.create(inPath);
String data="test";
for(ing i=0;i<100;i++){
   fout.write(data.getBytes());
}
fout.close();
FileStatus stat=hdfs.getFileStatus(inPath);
System.out.println("副本数:"+stat.getReplication());
hdfs.delete(inPath);
       HDFS正是通过Java的客户端,屏蔽了访问HDFS的各种各样细节,用户通过标准的Hadoop文件接口,就可以访问复杂的HDFS,而不需要考虑名字节点、数据节点等的交互细节,降低了Hadoop应用开发的难度,也证明了Hadoop抽象文件系统的通用性。

       版权申明:本文部分摘自【蔡斌、陈湘萍】所著【Hadoop技术内幕 深入解析Hadoop Common和HDFS架构设计与实现原理】一书,仅作为学习笔记,用于技术交流,其商业版权由原作者保留,推荐大家购买图书研究,转载请保留原作者,谢谢!
 

你可能感兴趣的:(Hadoop源码分析)