date: 2020-11-15title: Hadoop HDFS简介(1) #标题
tags: hadoop #标签
categories: Hadoop # 分类

Hadoop作为一个鼎鼎有名的分布式文件系统,一直没有学习过它,现在开始一点点学习。

架构

Hadoop HDFS简介(1) - 图1

上图涉及到的名词解释及其作用如下:

Block数据块

  • 基本存储单位,新版本的默认块大小为128M,旧版本的一般为64M,配置大的块主要是因为:

    • 减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;
    • 减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;
    • 对数据块进行读写,减少建立网络的连接成本。
  • 一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小。

  • 基本的读写单位,类似于磁盘的页,每次都是读写一个块。
  • 每个块都会被复制到多台机器,默认复制3份。

NameNode

  • 存储文件的metadata,运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小。
  • 一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件。
  • 数据会定时保存到本地磁盘,但不保存block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建)。

Secondary NameNode

  • 定时与NameNode进行同步(定期合并文件系统镜像(fsimages)和编辑日志(edits),然后把合并后的传给NameNode,替换其文件系统镜像,并清空编辑日志,类似于CheckPoint机制),但NameNode失效后仍需要手工将其设置成主机。

DataNode

  • 保存具体的block数据。
  • 负责数据的读写操作和复制操作。
  • DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息。
  • DataNode之间会进行通信,复制数据块,保证数据的冗余性。

namenode和secondary namenode的工作机制

Namenode中的元数据是存储在Namenode节点的内存中,因为经常需要进行随机访问,还有响应客户的请求,必然效率过低,因此,元数据需要放在内存中,但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了,因此产生了在磁盘中备份元数据的FsImage——文件系统镜像。

这样又会带来新的问题,当在内存中的元数据更新时,如同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(最进行之操作,效率较高),每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。

但是,如果长时间添加数据到Edits中,会导致该文件过大,效率降低,而且一旦断电,恢复元数据需要的时间很长,因此,需要定期进行FSImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低,因此,引入一个新的节点SecondaryNameNode,专用于FsImage和Edits的合并。

具体工作流程如下(自行理解吧):

Hadoop HDFS简介(1) - 图2

Hadoop写文件

Hadoop HDFS简介(1) - 图3

上图描述了client写文件时的一个完整流程,具体如下:

  • 客户端将文件写入本地磁盘的HDFS Client文件中;
  • 当临时文件大小达到一个block大小时,HDFS client通知NameNode,申请写入文件;
    NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给客户端;
  • 客户端收到这些信息后,将临时文件写入DataNodes;

    • 客户端将文件内容写入第一个DataNode(一般以4kb为单位进行传输);
    • 第一个DataNode接收后,将数据写入本地磁盘,同时也传输给第二个DataNode;
    • 依此类推到最后一个DataNode,数据在DataNode之间是通过pipeline的方式进行复制的;
    • 后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给客户端;
    • 当客户端接收到整个block的确认后,会向NameNode发送一个最终的确认信息;
    • 如果写入某个DataNode失败,数据会继续写入其他的DataNode。然后NameNode会找另外一个好的DataNode继续复制,以保证冗余性;
    • 每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性
  • 文件写完后(客户端关闭),NameNode提交文件(这时文件才可见,如果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)

Rack aware(机架感知)

通过配置文件指定机架名和DNS的对应关系。

假设复制参数是3,在写入文件时,会在本地的机架保存一份数据,然后在另外一个机架内保存两份数据(同机架内的传输速度快,从而提高性能)

整个HDFS的集群,最好是负载平衡的,这样才能尽量利用集群的优势

Hadoop 读文件

Hadoop HDFS简介(1) - 图4

  • 客户端向NameNode发送读取请求;
  • NameNode返回文件的所有block和这些block所在的DataNodes(包括复制节点);
  • 客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)。

HDFS可靠性

HDFS 的可靠性主要有一下几点:

  • 冗余副本策略
  • 机架策略
  • 心跳机制
  • 安全模式
  • 效验和
  • 回收站
  • 元数据保护
  • 快照机制

冗余副本策略

  • 可以在 hdfs-site.xml 中设置复制因子指定副本数量
  • 所有数据块都可副本
  • DataNode 启动时,遍历本地文件系统,产生一份 HDFS 数据块和本地文件的对应关系列表 (blockreport) 汇报给 Namenode

机架策略

  • HDFS 的”机架感知”,通过节点之间发送一个数据包,来感应它们是否在同一个机架。
  • 一般在本机架放一个副本,在其他机架再存放一个副本,这样可以防止机架失效时丢失数据,也可以提高带宽利用率。

心跳机制

  • NameNode 周期性从 DataNode 接受心跳信息和块报告;
  • NameNode 根据块报告验证元数据;
  • 没有按时发送心跳的 DataNode 会被标记为宕机,不会再给他任何 I/O 请求;
  • 如果 DataNode 失效造成副本数量下降,并且低于预先设定的值,NameNode 会检测出这些数据库,并在合适的时机重新复制;
  • 引发重新复制的原因还包括数据副本本身损坏,磁盘错误,复制因子被增大等;

安全模式

  • NameNode 启动时会先经过一个 “安全模式” 阶段;
  • 安全模式阶段不会产生数据写;
  • 在此阶段 NameNode 收集各个 DataNode 的报告, 当数据块达到最小副本数以上时,会被认为是”安全”的;
  • 在一定比例(可设置) 的数据块被确定为”安全” 后 ,在过若干时间,安全模式结束;
  • 当检测到副本数不足的数据块时,该块会被复制,直到达到最小副本数。

效验和

  • 在文件创建时,每个数据块都产生效验和
  • 效验和会作为单独一个隐藏文件保存在命名空间下
  • 客户端获取数据时可以检查效验和是否相同,从而发现数据块是否损坏
  • 如果正在读取的数据块损坏,则可以继续读取其他副本

回收站

  • 删除文件时,其实是放入回收站 /trash
  • 回收站里的文件是可以快速恢复的
  • 可以设置一个时间值,当回收站里文件的存放时间超过了这个值,就被彻底删除,并且释放占用的数据块

元数据保护

  • 映像文件和事物日志是 NameNode 的核心数据.可以配置为拥有多个副本;
  • 副本会降低 NameNode 的处理速度,但增加安全性;
  • NameNode 依然是单点,如果发生故障要手工切换

Hadoop优缺点比较

优点:

  • 高容错性:数据默认保存三个副本,通过增加副本的形式,提高容错性,某个副本丢失后,如果还有空闲的datanode,会再自动同步一份到新的datanode节点上。
  • 适合处理大数据:数据规模可达到GB、TB、甚至PB级别的数据,文件规模可到达百万级别以上的规模。
  • 成本低:可构建在廉价的机器上,通过多副本机制,提高可靠性。

缺点:

  • 不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
  • 无法高效的对大量小文件进行存储

    • 存储小文件的话,它会占用NameNode大量内存来存储文件目录和块信息,这样是不可取的,因为NameNode的内存总是有限的。
    • 小文件存储的寻址时间会超过读取时间,违反了HDFS的设计目标。
  • 不支持并发写入、文件随机修改

    • 同一个文件只能有一个写,不允许多个线程同时写。
    • 仅支持数据append,不支持文件的随机修改。