Hadoop 学习笔记——HDFS架构设计概览

目录

一、HDFS是什么

二、类Linux文件系统

三、HDFS分层架构

四、HDFS 读写文件原理

四、HDFS Block Replication 机制

五、NameNode 和 DataNode


一、HDFS是什么

随着移动互联网技术的发展,产生的用户数据也越来越多,对服务器存储需求也越来越大。服务器存储扩展有两个方向:1)垂直扩展,添加多个磁盘,缺点是单台机器能支持的磁盘总数有限,并且磁盘数太多会影响机器读取数据的能力。2)水平扩展,添加多台机器组成集群,将文件分散到集群中各个机器上存放,但是需要机器间网络通信以及某个节点挂掉无法提供的问题,而HDFS的出现便是为了解决这个问题的。

HDFS是一个分布式文件系统:引入存放文件元数据信息的服务器Namenode和实际存放数据的服务器Datanode,对数据进行分布式储存和读取。

二、类Linux文件系统

Linux 的ext格式文件系统将一个磁盘分区格式化后,有两个重要的组成部分:inode(索引块)和data block(数据块)。其中inode存放文件路径,文件本身属性,已经存放文件内容的数据块的编号(当文件内容由多个数据块构成时,存放的是编号列表), 数据块存放文件实际的数据数据内容。读取文件内容时,先根据文件路径找到inode,然后从inode读取文件信息以及数据块编号,根据数据块编号读取数据块内容。因此Linux文件系统也被称为索引式文件系统。

HDFS文件系统也设计了类似架构:NameNode(相当于inode)和 DataNode(相当于data block)。Namenode负责存放文件元信息,DataNode负责实际存放数据。

三、HDFS分层架构

Hdfs 是一个文件系统,底层存储依赖操作系统本身的文件存储机制,它将数据分片存放在不同主机上,并且存放的是文件内容序列化后的二进制数据。对于像我这样曾经的初学者来说,最容易犯得一个错误就是喜欢到Linux主机上直接使用cat 命令去查看hdfs 存放的文件内容,实际上只会看到一堆乱码。Hdfs 整体架构如下图所示:

Hadoop 学习笔记——HDFS架构设计概览

四、HDFS 读写文件原理

4.1 Hdfs文件读文件

HDFS的文件读取原理如下图所示:

Hadoop 学习笔记——HDFS架构设计概览

主要包括以下几个步骤:

  • 首先调用FileSystem对象的open方法,其实获取的是一个DistributedFileSystem的实例。
  • DistributedFileSystem通过RPC(远程过程调用)获得文件的第一批block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。
  • 前两步会返回一个FSDataInputStream对象,该对象会被封装成 DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream就会找出离客户端最近的datanode并连接datanode。
  • 数据从datanode源源不断的流向客户端。
  • 如果第一个block块的数据读完了,就会关闭指向第一个block块的datanode连接,接着读取下一个block块。这些操作对客户端来说是透明的,从客户端的角度来看只是读一个持续不断的流。
  • 如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的block块都读完,这时就会关闭掉所有的流。

4.2 HDFS 写文件

HDFS的文件写入原理如下图所示:

Hadoop 学习笔记——HDFS架构设计概览

主要包括以下几个步骤:

  • 客户端通过调用 DistributedFileSystem 的create方法,创建一个新的文件。
  • DistributedFileSystem 通过 RPC(远程过程调用)调用 NameNode,去创建一个没有blocks关联的新文件。创建前,NameNode 会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode 就会记录下新文件,否则就会抛出IO异常。
  • 前两步结束后会返回 FSDataOutputStream 的对象,和读文件的时候相似,FSDataOutputStream 被封装成 DFSOutputStream,DFSOutputStream 可以协调 NameNode和 DataNode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列 data queue。
  • DataStreamer 会去处理接受 data queue,它先问询 NameNode 这个新的 block 最适合存储的在哪几个DataNode里,比如重复数是3,那么就找到3个最适合的 DataNode,把它们排成一个 pipeline。DataStreamer 把 packet 按队列输出到管道的第一个 DataNode 中,第一个 DataNode又把 packet 输出到第二个 DataNode 中,以此类推。
  • DFSOutputStream 还有一个队列叫 ack queue,也是由 packet 组成,等待DataNode的收到响应,当pipeline中的所有DataNode都表示已经收到的时候,这时akc queue才会把对应的packet包移除掉。
  • 客户端完成写数据后,调用close方法关闭写入流。
  • DataStreamer 把剩余的包都刷到 pipeline 里,然后等待 ack 信息,收到最后一个 ack 后,通知 DataNode 把文件标示为已完成。

四、HDFS Block Replication 机制

Hdfs 在存放一个大文件时,比如100GB的日志文件,需要分片存放,在hdfs 术语中,被称之为block(块),每个块的默认大小是128M(低版本中是64M),文件不足128M时,仍然会占用1个block(和Linux 数据块不同的是,该block的实际磁盘占用量为文件实际大小)。当hdfs上小文件过多时,NameNode要记录的元信息也会变得特别多,容易让NameNode内存溢出。

Hdfs 为了解决DataNode节点挂掉时,该节点的数据块无法访问的问题,引入了数据块 replication。Hdfs默认是3副本(自身 + 两个复制块)备份机制,可以设置配置参数来修改副本数目。Hdfs的3副本选择放在哪些DataNode节点上,是根据机架(放置服务器的架子,现在服务器都基本都是刀片式服务器,1个架子上可以放置多台服务器)配置来选择的,具体策略如下:

1) 第一个副本选择离client距离最近的节点,要求client与hdfs集群在同一局域网内才生效(如果是外网环境访问,则只能随机选择一个节点)。如果client 刚好是集群内的一台主机,则直接选择该DataNode作为首个副本放置地。

2) 第二个副本选择和第一个副本在同一机架下的其他主机。

3) 第三个副本选择和第二个副本不在同一机架的其他主机。

五、NameNode 和 DataNode

1. NameNode 会负责整个文件系统的信息,使用FSNameSystem类来表示,负责维护文件系统目录树结构信息,文件对应的block编号列表,以及每一个block在哪几台datanode机器上存放。

NameNode主要是通过两个数据结构FsImage和EditsLog来实现metadata的更新。在启动hdfs时,会从FSImage文件中读取当前HDFS文件的metadata,之后对HDFS的操作步骤都会记录到edit log文件中。

NameNode 启动时,FsImage存放的是上一次checkpoint后的文件元信息,然后和editlog进行合并,构建新的FsImage并做checkpoint。这个过程可能会非常耗时,因为如果NameNode长时间没有过进行重启操作的话,NameNode是不会做日志合并操作的,所有HDFS引入了SecondaryNameNode角色,它是1个不与NameNode在一台机器上的单独进程,主要职责便是定期通过网络拉取NameNode的FsImage和Editlog做合并操作,生成新的checkpoint,发回给NameNode。

2. DataNode 负责实际的数据存储,主要有以下功能:

1) 向NameNode注册以及保持心跳:DataNode 同 NameNode 之间是一个单向通信模型。NameNode 为了保证自身的运行效率,不会主动向 DataNode 发起通信请求,因此所有通信行为都由 DataNode 主动触发。DataNode 启动时会发送注册请求,注册成功后,会定时发送心跳信息,告诉NameNode自己存活,同时取回NamoNode向其发送的指令。

2) 存取数据功能:DataNode启动时创建了DataXceiverServer类的实例,该类用来接收客户端的上传/下载数据请求。

3) block上报功能:NameNode在刚启动时,并不知道文件的block 和存放机器DataNode 的对应关系,因为FsImage中没有保存这个映射关系。DataNode启动时,会先扫描自己存储目录下所有的Block,然后上报给NameNode,NameNode根据上报信息来构建映射关系。在运行期间,如果有block在DataNode上被新建或删除,DataNode也会调用reportBlock方法及时上报信息。

上一篇:大数据 | 分布式文件系统 HDFS


下一篇:Hadoop HDFS原理详解(系统性回顾)