Hadoop学习笔记 — HDFS存储原理

By timebusker on June 2, 2018

Hadoop学习笔记—HDFS存储原理——Hadoop核心之HDFS 架构设计

image

HDFS设计前提和目标

  • 专为存储超大文件而设计:hdfs应该能够支持GB级别大小的文件;它应该能够提供很大的数据带宽并且能够在集群中拓展到成百上千个节点;它的一个实例应该能够支持千万数量级别的文件。
  • 适用于流式的数据访问:hdfs适用于批处理的情况而不是交互式处理;它的重点是保证高吞吐量而不是低延迟的用户响应
  • 容错性:完善的冗余备份机制
  • 支持简单的一致性模型:HDFS需要支持一次写入多次读取的模型,而且写入过程文件不会经常变化
  • 移动计算优于移动数据:HDFS提供了使应用计算移动到离它最近数据位置的接口
  • 兼容各种硬件和软件平台 image
    image

    不适合的场景

  • 大量小文件:文件的元数据都存储在NameNode内存中,大量小文件会占用大量内存。
  • 低延迟数据访问:hdfs是专门针对高数据吞吐量而设计的
  • 多用户写入,任意修改文件

基本概念

数据块(block)
  • HDFS(Hadoop Distributed File System)默认的最基本的存储单位是128M的数据块。
  • 和普通文件系统相同的是,HDFS中的文件是被分成128M一块的数据块存储的(未达到128M数据块大小的也按照一个数据块算)。
  • 不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。 image
    image
元数据节点(Namenode)和数据节点(Datanode)
  • 元数据节点用来管理文件系统的命名空间
    • 其将所有的文件和文件夹的元数据保存在一个文件系统树中。这些信息也会持久化到硬盘上保存成以下文件:命名空间镜像(namespace image)及修改日志(edit log)
    • 其还保存了一个文件包括哪些数据块,分布在哪些数据节点上。然而这些信息并不存储在硬盘上,而是在系统启动的时候从数据节点收集加载到内存中(DataNode定时与NameNode通信同步数据块信息,不需要持久化,数据块信息是动态分布,如果DataNode故障还会导致读写异常)。
  • 数据节点是文件系统中真正存储数据的地方
    • 客户端(client)或者元数据节点(namenode)可以向数据节点请求写入或者读出数据块。
    • 其周期性的向元数据节点回报其存储的数据块信息。
  • 从元数据节点(secondary namenode)
    • 从元数据节点并不是元数据节点出现问题时候的备用节点,它和元数据节点负责不同的事情。
    • 其主要功能就是周期性将元数据节点的命名空间镜像文件和修改日志合并,以防日志文件过大。
    • 合并过后的命名空间镜像文件也在从元数据节点保存了一份,以防元数据节点失败的时候,可以恢复。

image

image

  • 关于fsimage、metadata、edits、fstime——元数据信息(fsimage+ editslog)
    • fsimage是在磁盘文件,fsimage把内存的,序列化到磁盘,存储某一时段NameNode内存元数据信息。
    • metadata是在内存
    • edits:操作日志文件,比如说,上传一个文件或删除一个文件,记录操作日志。
    • fstime:保存最近一次checkpoint的时间,当NameNode故障时,secondary namenode将以checkpoint最近时间点恢复数据。
    • namenode始终在内存中保存metadata,用于处理“读请求”。到有“读请求”时,namenode会首先写editlog到磁盘,即向edits(操作日志文件)中写入日志,成功返回后,才会修改内存,并且向客户端返回。
# 默认是3600秒,每隔一个小时,Secondarynamenode就要下载fsimage和edits,进行数据的同步    
fs.checkpoint.period   
    
# edits一直在变大。一旦达到,就要进行合并。只要达到这两个条件的其中一个,都会进行合并   
fs.checkpoint.size    

image

HDFS元数据持久化
  • 当文件系统客户端(client)进行写操作时,首先把它记录在修改日志中(edit log)
  • 元数据节点在内存中更新(保存)了文件系统的元数据信息。在记录了修改日志后,元数据节点则修改内存中的数据结构
  • 每次的写操作成功之前,修改日志都会同步(sync)到文件系统
  • fsimage文件,也即命名空间映像文件,是内存中的元数据在硬盘上的checkpoint,它是一种序列化的格式,并不能够在硬盘上直接修改
  • 同数据的机制相似,当元数据节点失败时,则最新checkpoint的元数据信息从fsimage加载到内存中,然后逐一重新执行日志中(edit log)的修改日志中的操作
  • 从元数据节点就是用来帮助元数据节点将内存中的元数据信息checkpoint到硬盘上的
  • checkpoint的过程如下:
    • 从元数据节点通知元数据节点生成新的日志文件,以后的日志都写到新的日志文件中。
    • 从元数据节点用http get从元数据节点获得fsimage文件及旧的日志文件。
    • 从元数据节点将fsimage文件加载到内存中,并执行日志文件中的操作,然后生成新的fsimage文件。
    • 从元数据节点将新的fsimage文件用http post传回元数据节点
    • 元数据节点可以将旧的fsimage文件及旧的日志文件,换为新的fsimage文件和新的日志文件(第一步生成的),然后更新fstime文件,写入此次checkpoint的时间。
    • 这样元数据节点中的fsimage文件保存了最新的checkpoint的元数据信息,日志文件也重新开始,不会变的很大了。 image
HDFS按块存储的好处:
  • 磁盘数据块是磁盘读写的基本单位,与普通文件系统类似,hdfs也会把文件分块来存储。hdfs默认数据块大小为64MB,磁盘块一般为512B,hdfs块为何如此之大呢?块增大可以减少寻址时间与文件传输时间的比例,若寻址时间为10ms,磁盘传输速率为100MB/s,那么寻址与传输比仅为1%。当然,磁盘块太大也不好,因为一个MapReduce通常以一个块作为输入,块过大会导致整体任务数量过小,降低作业处理速度。
  • 数据块是存储在DataNode中的,为了能够容错数据块是以多个副本的形式分布在集群中的。
  • 文件可以任意大,也不用担心单个结点磁盘容量小于文件的情况。
  • 简化了文件子系统的设计,子系统只存储文件块数据,而文件元数据则交由其它系统(NameNode)管理。
  • 有利于备份和提高系统可用性,因为可以以块为单位进行备份,hdfs默认备份数量为3。
  • 有利于负载均衡。

数据流(data flow)

读文件的过程
  • 应用端Application调用HDFS Client提供的FileSystem的open()函数打开文件
  • HDFS Client通过RPC服务连接元数据节点,得到文件的数据块信息,对于每一个数据块,元数据节点返回保存数据块的数据节点的地址、每个block的副本以及datanode地址信息,datanode按照距离排序
  • HDFS Client返回FSDataInputStream给应用端Application,用来读取数据
  • 应用端Application调用HDFS Client提供stream的read()函数开始读取数据
  • DFSInputStream(该类管理NN和DN的IO操作)连接保存此文件第一个数据块的最近的数据节点(就近读取原则)
  • Data从数据节点读到客户端(client)
  • 当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。
  • 当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。
  • 在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。
  • 失败的数据节点将被记录,以后不再连接。 image
写文件流程
  • 应用端Application调用HDFS Client提供的FileSystem的create()来创建文件
  • HDFS Client通过RPC服务连接元数据节点,在文件系统的命名空间中创建一个新的文件
  • 元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件
  • HDFS Client返回DFSOutputStream给应用端Application用于写数据,DFSOutputStream(HDFS Clinet)进行写数据的同时,也负责着和数据节点、名称节点之间的通信
  • 应用端Application通过DFSOutputStream开始写入数据,DFSOutputStream将数据分成块,写入Data Queue。
  • Data Queue由Data Streamer读取,并**联系元数据节点分配数据节点和数据块编号,用来存储数据块(每块默认复制3块)。分配的数据节点放在一个pipeline里。
  • Data Streamer将数据块写入pipeline中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点(1—>2->3:主要是因为1->3的网络距离最远)。
  • DFSOutputStream为发出去的数据块保存了ack queue,等待pipeline中的数据节点告知数据已经写入成功。
  • 只要最小副本数(dfs.namenode.replication.min=1)写入完成,写入即成功。
  • 客户端调用os.close()方法,将所有剩余包清理到pipeline中并等待确认,联系NN发送文件操作完成的信号,NN已经知道文件由哪些块组成,因此在成功返回前必须等待block被最小量复制
  • 如果数据节点在写入的过程中失败:
    • 关闭pipeline,将ack queue中的数据块放入data queue的开始。
    • 当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。
    • 失败的数据节点从pipeline中移除,另外的数据块则写入pipeline中的另外两个数据节点。
    • 元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。
  • 当客户端结束写入数据,则调用stream的close函数。此操作将所有的数据块写入pipeline中的数据节点,并等待ack queue返回成功。最后通知元数据节点写入完毕。 image

数据备份

  • HDFS通过备份数据块的形式来实现容错,除了文件的最后一个数据块外,其它所有数据块大小都是一样的。数据块的大小和备份因子都是可以配置的。NameNode负责各个数据块的备份,DataNode会通过心跳的方式定期的向NameNode发送自己节点上的Block 报告,这个报告中包含了DataNode节点上的所有数据块的列表。

  • 文件副本的分布位置直接影响着HDFS的可靠性和性能。一个大型的HDFS文件系统一般都是需要跨很多机架的,不同机架之间的数据传输需要经过网关,并且,同一个机架中机器之间的带宽要大于不同机架机器之间的带宽。如果把所有的副本都放在不同的机架中,这样既可以防止机架失败导致数据块不可用,又可以在读数据时利用到多个机架的带宽,并且也可以很容易的实现负载均衡。但是,如果是写数据,各个数据块需要同步到不同的机架,会影响到写数据的效率。

  • 而在Hadoop中,如果副本数量是3的情况下,Hadoop默认是这么存放的,把第一个副本放到机架的一个节点上,另一个副本放到同一个机架的另一个节点上,把最后一个节点放到不同的机架上。这种策略减少了跨机架副本的个数提高了写的性能,也能够允许一个机架失败的情况,算是一个很好的权衡(V1)。
  • 而在Hadoop中,如果副本数量是3的情况下,Hadoop默认是这么存放的,把第一个副本放到机架的一个节点上,另外两个副本放在另一个机架上的不同服务器上(V2)。

  • 关于副本的选择,在读的过程中,HDFS会选择最近的一个副本给请求者——本地化策略

  • 关于安全模式,当 Hadoop的NameNode节点启动时,会进入安全模式阶段。在此阶段,DataNode会向NameNode上传它们数据块的列表,让 NameNode得到块的位置信息,并对每个文件对应的数据块副本进行统计。当最小副本条件满足时,即一定比例的数据块都达到最小副本数,系统就会退出安全模式,而这需要一定的延迟时间。当最小副本条件未达到要求时,就会对副本数不足的数据块安排DataNode进行复制,直至达到最小副本数。而在安全模式下,系统会处于只读状态,NameNode不会处理任何块的复制和删除命令。

image
image

HDFS中的沟通协议

  • 所有的HDFS中的沟通协议都是基于tcp/ip协议,一个客户端通过指定的tcp端口与NameNode机器建立连接,并通过ClientProtocol协议与NameNode交互。而DataNode则通过DataNode Protocol协议与NameNode进行沟通。HDFS的RCP(远程过程调用)对ClientProtocol和DataNode Protocol做了封装。按照HDFS的设计,NameNode不会主动发起任何请求,只会被动接受来自客户端或DataNode的请求。

可靠性保证

  • 可以允许DataNode失败。DataNode会定期(默认3秒)的向NameNode发送心跳,若NameNode在指定时间间隔内没有收到心跳,它就认为此节点已经失败。此时,NameNode把失败节点的数据(从另外的副本节点获取)备份到另外一个健康的节点。这保证了集群始终维持指定的副本数。

  • 可以检测到数据块损坏。在读取数据块时,HDFS会对数据块和保存的校验和文件匹配,如果发现不匹配,NameNode同样会重新备份损坏的数据块。

HDFS优缺点

优点
  • 高容错性
    • 数据自动保存多个副本: 副本丢失后,自动恢复
    • 适合批处理:移动计算而非数据
    • 适合大数据处理:GB、TB、PB 级数据,百万以上的文件数量规模,10K+节点 规模
    • 高吞吐量:无上限,主要取决于所有DataNode节点的IO吞吐量的和。
缺点

image

Shell命令详解

image

HDFS Federation(联邦HDFS)

image
image

HDFS 高可用

image
image
image
image
image
image

HDFS策略

image
image
image
image
image
image

HDFS压缩策略

最优选择lzo压缩解压方式,压缩效率高,速度快,支持任务切割分片,可适配本地类库。