大数据存储之HDFS

大数据存储知识地图

                              

Hadoop分布式文件系统 

            分布式文件系统:它是一种通过网络实现文件在多台主机上进行分布式存储的文件系统。分布式文件系统的设计一般采用“客户机/服务器(Client/Server)”模式目前广泛运用到的分布式文件系统主要包括GFS和HDFS,后者是针对前者的开源实现。这一篇主要讲HDFS.

HDFS简介 

        HDFS原来是Apache Nutch搜索引擎的一部分,后来独立出来作为一个 Apache的一个子项目,并且和MapReduce一起成为Hadoop的核心 组成部分。HDFS支持流数据的读取和处理超大规模文件,并能够运行在由廉价的普通机器组成的集群上。总体而言HDFS要实现一下目标:

  • 廉价兼容的硬件设备
  • 流数据读写
  • 简单文件模型
  • 大数据集
  • 强大的跨平台兼容性

HDFS也有自身的局限性

  • 不适合低延迟数据访问
  • 无法高效存储大量小文件
  • 不支持多用户写入及任意修改文件 

HDFS的相关概念

一、块

     在传统的文件系统中,为了提高磁盘读写效率,一般以数据块为单位,而不是以字节为单位。那HDFS也采用了块的概念,默认的一个块的大小是64M。在HDFS中的文件会被拆分为多个块,每个块作为独立的单元进行存储。

    HDFS采用块的概念的好处:

  • 支持大规模文件存储。
  • 简化系统设计。
  • 适合数据备份

二、名称节点和数据节点

    分布式文件系统在物理结构上是由计算及集群中的多个节点构成的。这些节点分为两类:一类叫“主节点(Master Node)”或者称为“名称节点”(Name Node),另一类叫“从节点(Slave Node)”或者也成为“数据节点(DateNode)”。

   名称节点:负责文件和目录的创建、删除和重命名,同时管理着数据节点和文件块的映射关系。所以客户端只有访问名称节点才能找到请求的文块所在的位置,进而读取所需的文件块。

扫描二维码关注公众号,回复: 5534986 查看本文章

   数据节点:是分布式文件系统HDFS的工作节点,负责数据的读取和存储,存储时,有名称节点分配存储位置,然后由客户端把数据直接写入相应的数据节点;读取时,客户端从名称节点获得数据节点和文件块的映射关系,然后到相应位置访问数据块。

HDFS体系结构

   HDFS采用了主从(Master/Slave)的结构模型,一个HDFS集群中包括一个名称节点和若干个数据节点。 名称节点作为中心服务器,负责管理文件系统的命名空间及客户端对文件的访问。数据节点负责处理文件系统客户端的读写请求,进行数据块的创建、删除和复制等操作。每个数据节点会周期性的向名称节点发送“心跳”信息,报告自己的状态,没有按时发送心跳信息的数据节点会被标记为“宕机”,不再给它分配任何I/O请求。

HDFS的存储原理

1、冗余数据的保存

           作为一个分布式文件系统,为了保证系统的容错性和可用性,HDFS采用了多副本方式对数据进行冗余存储,通常一个数据块的多个副本会被分布到不同的数据节点上。这种多副本有以下优点:

             ①加快数据传输速度。当多个客户端需要同时访问同一个文件时,可以让各个客户端分别从不同的数据块副本中读取数据,这就大大加快了数据的传输速率。

             ②容易检查数据错误。HDFS的数据节点之间通过网络传输数据,采用多个副本可以很容易判断数据传输是否出错。

             ③保证数据的可靠性。即使某个节点出现故障失效,也不会造成数据丢失。

2、数据存取策略

             ①数据存放。为了提高数据的可靠性与数据的可用性,以及充分利用网络带宽,HDFS采用了以机架(Rack)为基础的数据存放策略

             ②数据读取。

             ③数据复制。

3、数据错误与恢复

              ①名称节点出错。

              ②数据节点出错。

              ③数据出错。

HDFS的数据读写过程

          客户端连续调用open()、read()、close()读取数据时,HDFS执行过程如下:

(1)客户端通过FileSystem.open()打开文件,相应地,在HDFS文件系统中,DistributedFileSystem具体实现了FileSystem,因此,调用open()方法后,DistributedFileSystem会创建输入流FSDataInputStream,对于HDFS而言,具体的输入流就是DFSInputStream。

(2)在DFSInputStream 的构造函数中,输入流通过ClientProtocal。getBlockLocations()远程调用名称节点,获得文件开始部分数据块的保存位置。对于该数据块,名称节点返回保存该数据块的所有数据节点的地址,同时,根据距离客户端的远近对数据节点进行排序;然后,DistributedFileSystem会利用DFSInputStream来实例化FSDataInputStream,返回给客户端,同时返回了数据块的数据节点地址。

(3)获得输入流FSDataInputStream后,客户端调用read()函数开始读取数据。输入流根据前面的排序结果,选择距离客户端最近的数据节点建立连接并读取数据。

(4)数据从改数据节点读到客户端,当该数据块读取完毕时,FSDataInputStream关闭和该数据节点的连接。

(5)输入流通过getBlockLocations()方法查找下一个数据块(如果客户端已经缓存了该数据块的位置信息,就不需要调用该方法)。

(6)找到该数据块的最佳数据节点,读取数据。

(7)当客户端读取完毕数据的时候,调用FSDataInputStream的close()函数,关闭输入流。

写数据的过程

客户端向HDFS写数据是一个复杂的过程,下图是在不发生任何异常的情况下,客户端连续调用create()、write()和close()时,HDFS内部的执行过程。

(1)客户端通过FileSystem.create()创建文件。

相应的,在HDFS文件系统中,DistributedFile System 具体实现了FileSystem,因此,调用cream()方法后,DistributedFileSystem会创建输出流对象FSDataInputStream,对于HDFS而言,具体的输出流就是DFSOutputStream。

(2)然后,DistributedFileSystem通过RPC远程调用名称节点,在文件系统的命名空间中创建一个新的文件。名称节点会执行一些检查,比如文件是否已经存在,客户端是否有权限创建文件等。检查通过之后,名称节点会构造一个新文件,斌添加文件信息。远程方法调用结束后,DIstributedFileSystem 会利用DFSOutputStream 来实例化FSDataInputStream,返回给客户端,客户端使用这个输出流写入数据。

(3)获得输出流FSDataOutputStream以后,客户端调用输出流的write()方法向HDFS中对应的文件写入数据。

(4)客户端向输入流FSDataOutputStream中写入的数据,会首先被分成一个个的分包,这些分包被放入DFSOutputStream对象的内部队列。输出流FSDataOutputStream会向名称节点澄清保存文件和副本数据块的若干个数据节点,这些数据节点形成一个数据流管道,队列中的分包最后被打包成数据包,发往数据流管道中的第一个数据节点,第一个数据节点将数据包发送给第二个数据节点,第二个数据节点将数据包发送给第三个数据节点。这样数据包会流经管道的各个节点。

(5)因为各个数据节点位于不同的机器上,数据需要通过网络发送,因此,为了保证所有数据节点的数据都是准确的,接收到的数据的数据节点要向发送者发送确认包(ACK Packet)。确认包沿着数据流管道逆流而上,从数据流管道一次经过各个数据节点并最终发往客户端,当客户端受到应答时,它将对应的粉白从内部队列移除。不断执行(3)~(5)步,知道数据全部写完。

(6)客户端调用close()方法关闭输出流,此时开始,客户端不会再向输出流中写入数据,所以,当DFSOutputStream对象内部队列中的分包都收到应答以后,就可以使用ClientProtocol.complete()方法通知名称节点关闭文件,完成一次正常的写文件过程。

猜你喜欢

转载自blog.csdn.net/qq_19952111/article/details/82878243