从分布式角度解读HDFS运行机制和原理

引言:分布式的一般设计

要想深入学习HDFS就要先了解其设计思想和架构,这样才能继续深入使用HDFS或者深入研究源代码,先从一般的分布式谈起,在宏观上逐步去探究HDFSDE设计思想和架构实现。

  • 分布式

    分布式是近几年非常火的技术概念,无论是云计算、大数据还是高并发的互联网架构话题都会频频出现这个词语,特别是这个大谈“大规模”的时代,分布式貌似成了高大上技术的代名词。引的许多刚入行的技术人员趋之若鹜,其实世界上不会有凭空出现的事物,都是慢慢演化的,新事物一定可以找到旧事物的影子。

    那么我们就先看看“一般的”分布式系统需要解决那些问题、这些问题的通用解决方案和特性。

    分布式的定义

    分布式系统会划分成多个子系统或模块,各自运行在不同的机器上,子系统或模块之间通过网络通信进行协作,实现最终的整体功能。比如分布式操作系统、分布式程序设计语言及其编译(解释)系统、分布式文件系统和分布式数据库系统等。利用多个节点共同协作完成一项或多项具体业务功能的系统就是分布式系统

  • 问题及解决方案

    1:CAP的权衡

    分布式领域有一个非常著名的CAP理论,是由 Eric Brewer 提出的分布式系统中最为重要的理论之一。其定义很好理解,CAP 三个字母分别代表了分布式系统中三个相互矛盾的属性。CAP分别代表Consistency、Availiablity、Tolerance to the partition of network即一致性、可用性、网络分区容忍性。

一致性(Consistency):在CAP理论中的一致性是强一致性,即每个节点上的数据时刻保持一致。

可用性(Availiablity):是指分布式系统在出现异常情况的时候的可用度。

分区容忍性(Tolerance…):是指分布式系统对网络分区的容错度。

CAP 理论指出:无法设计一种分布式协议,使得同时完全具备 CAP 三个属性,即该种协议下的副本始终是强一致性&服务始终是可用的&协议可以容忍任何网络分区异常;分布式系统协议只能在 CAP 这三者间所有折中。

CAP折中的实现可以体现在分布式协议中:

a. Lease 机制牺牲了部分异常情况下的 A,从而获得了完全的 C 与很好的 P。

b. Quorum 机制,即总共有 N 个副本,成功更新 W 个副本则算成功提交,读取时读 R 个副本。这种一般的 Quorum 机制,在 CAP 三大因素中都各做了折中,有一定的 C,有较好的 A,也有较好的 P,是一种较为平衡的分布式协议。

c. 两阶段提交系统具有完全的 C,很不好 A,很不好 P。

d. Paxos 协议具有完全的 C,较好的 A,较好的 P。

2:负载均衡

在某些有多个节点的分布式系统中需要对服务请求进行负载均衡,根据业务需求的不同也可以使用不同的负载均衡算法,例如一致性Hash

3:高并发

有些分布式系统对并发性有很高的要求,通常是使用MVCC:Multiversion concurrency control,多版本并发控制技术。本质是使用COW+Version+CAS这个技术组合来提升系统并发性

1:HDFS的基本知识

最近重新整理关于HDFS的知识点,深入了解它的应用场景和通用的分布式架构,更重要的是理解步骤的原理和实现细节。

1.1 :HDFS的来源

HDFS 源于 Google 在2003年10月份发表的GFS(Google File System) 论文。 它其实就是 GFS 的一个克隆版本

1.2:HDFS的特点

选择HDFS存储数据,是因为HDFS拥有众多优点:

(1):高容错性

  • 数据自动保存多个副本。它通过增加副本的形式,提高容错性
  • 某一个副本丢失以后,它可以自动恢复

(2):适合批处理

  • 通过移动计算而不是移动数据

  • 把数据位置暴露给计算框架

(3): 适合大数据处理

  • 处理数据达到 GB、TB、甚至PB级别的数据
  • 能够处理百万规模以上的文件数量
  • 能够处理10K节点的规模

(4): 流式文件访问

  • 一次写入,多次读取。文件一旦写入不能修改,只能追加
  • 它能保证数据的一致性

(5)搭建在廉价的机器上

  • 通过副本机制,提高可靠性
  • 提供容错和恢复机制,当数据丢失时,可通过副本恢复

当然,HDFS也有缺点,导致它并不适合一些特定的场景

(1):低延时数据访问

  • 它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况下是不行的,比如毫秒级以内读取数据,这样它是很难做到的

(2):小文件存储

  • 存储大量小文件(这里的小文件是指小于HDFS系统的Block大小的文件(hadoop2.x默认128M))的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。
  • 小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标

(3)并发写入、文件随机修改

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

1.3:HDFS的一般特性

  • HDFS是一个文件系统,用户存储和管理文件,通过统一的命名空间(类似于本地文件系统的目录树),其特点是分布式的,服务器中的每个节点都有自己的角色和职责。
  • HDFS的文件在物理逻辑上是分块存储的——block,块的大小可以通过配置参数dfs.blocksize指定,默认大小在hadoop2.x版本中是128M,之前的版本中是64M。
  • HDFS文件系统会给客户端提高一个统一的抽象目录树,客户端通过路径来访问文件:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
  • 目录结构及文件分块位置信息(元数据)的管理由namenode节点承担,namenode是HDFS集群主节点,负责维护整个HDFS的目录树,以及每一个路径(文件)所对应的数据块信息(blockid及所在的datanode服务器)。
  • DataNode会定期向NameNode回报自身所保存的文件block信息,而Namenode会负责保持文件的副本数量,HDFS内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向NameNode申请来进行的。
  • HDFS适应一次写入,多次读取的场景,不支持文件的修改。因为需要频繁的RPC交互,所以写入性能不好。

1.4 : HDFS的高级特性

  • 安全模式 safe mode

    注意:HDFS正常运行的时候,安全模式一定是off(关闭状态), 是HDFS的一种自我保护,作用:检查数据块的副本率,HDFS处于安全模式,是只读的状态

  • 快照:是一种备份,默认:HDFS快照是关闭

    命令:管理命令

    [-allowSnapshot ]

    [-disallowSnapshot ]

    命令:操作命令

    -createSnapshot 目录 快照名称

    举例:启用目录的快照功能
    hdfs dfsadmin -allowSnapshot /input

    创建快照:
    hdfs dfs -createSnapshot /input backup_input_20180905_01
    快照本质:Created snapshot /input/.snapshot/backup_input_20180905_01

    hdfs dfs -put student0*.txt /input
    重新创建快照
    hdfs dfs -createSnapshot /input backup_input_20180905_0

  • 配额:Quota

  • (1)名称配额: 限定HDFS目录下,存放文件(目录)的个数
    [-setQuota …]

    [-clrQuota …]

    举例:

    hdfs dfs -mkdir /myquota1
    规定这个最多存放3个文件(实际:N-1)
    hdfs dfsadmin -setQuota 3 /myquota1

    (2)空间配额:限定HDFS目录下,文件的大小 —> 值必须大于数据块大小(128M)

    [-setSpaceQuota [-storageType ] …]

    [-clrSpaceQuota [-storageType ] …]

    举例:

    hdfs dfs -mkdir /myquota2

    规定该目录下的文件空间配额是2M

    hdfs dfsadmin -setSpaceQuota 2M /myquota2

  • 回收站:默认HDFS的回收站禁用

    -rm:删除
    参数: -rmr 表示删除目录和子目录
    hdfs dfs -rmr /output
    日志:Deleted /output
    注意:如果启用回收站,观察日志

    (*)补充一个知识:Oracle数据库也有回收站
    通过闪回进行恢复(flashback)
    Oracle有7中类型的闪回

2:HDFS架构及原理

2.1:HDFS架构

HDFS 是一个能够面向大规模数据使用的,可进行扩展的文件存储与传递系统。是一种允许文件通过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和 存储空间。让实际上是通过网络来访问文件的动作,由程序与用户看来,就像是访问本地的磁盘一般。即使系统中有某些节点脱机,整体来说系统仍然可以持续运作 而不会有数据损失。

HDFS存储数据架构图:

在这里插入图片描述

HDFS采用的是master/slave的主从架构来存储数据,这种架构主要分成4个部分,分别是HDFS client,NameNode,DataNode和SecondaryNode。

  1. Client:就是客户端

    客户端的主要工作:

    • 文件切分。文件上传到HDFS的时候,Client将文件切分成一个个小的block,然后进行存储。
    • 与NameNode进行交互,获取文件位置
    • 与DataNode进行交互,读取或写入数据
    • 提供一些命令来管理HDFS,比如一键关闭或启动HDFS,还有访问HDFS等。
  2. NameNode:也就是master,是一个管理者

    • 管理HDFS的名称空间
    • 管理数据块block的映射空间
    • 配置副本策略
    • 处理客户端的读写请求
  3. DataNode:也就是slave,负责存储数据

    • 存储实际的数据块
    • 执行数据块的读/写操作
  4. Secondary NameNode:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务

    • 辅助 NameNode,分担其工作量

    • 定期合并 fsimage和fsedits,并推送给NameNode

    • 在紧急情况下,可辅助恢复 NameNode


2.2:HDFS写数据过程

  • 概述

客户端要向HDFS中写数据,首先要跟NameNode通信以确认可以写文件并获得接收文件block的DataNode,然后客户端按顺序将文件逐个block传递给相应的DataNode,并由接收到block的DataNode负责向其他 DataNode复制block的副本。

  • 写入数据的详细步骤

在这里插入图片描述

  1. 客户端想NameNode发送上传文件请求,NameNode要对上传目录和文件进行检查,判断是否可以上传,并向客户端返回检车结果;

  2. 客户端得到上传文件允许之后读取客户端配置,如果没有指定配置则会读取默认配置,如副本数默认为3,block大小默认为128M,副本是由客户端决定。向NameNode请求上传一个数据块;

  3. NameNode会根据客户端的配置来查询DataNode信息 ,如果使用默认配置,那么最终结果会返回同一个机架上的两个datanode和另一个机架上的DataNode,这种机制称为“机架感知”;

  4. 客户端在开始传输数据块之前会把数据缓存在本地,当缓存大小超过了一个数据块的大小,客户端就会从namenode获取要上传的datanode列表。之后会在客户端和第一个datanode建立连接开始流式的传输数据,这个datanode会一小部分一小部分(4K)的接收数据然后写入本地仓库,同时会把这些数据传输到第二个datanode,第二个datanode也同样一小部分一小部分的接收数据并写入本地仓库,同时传输给第三个datanode,依次类推。这样逐级调用和返回之后,待这个数据块传输完成客户端后告诉namenode数据块传输完成,这时候namenode才会更新元数据信息记录操作日志;

  5. 第一个数据块传输完成后会使用同样的方式传输下面的数据块直到整个文件上传完成。

细节

  • 请求和应答是使用RPC的方式,客户端通过ClientProtocol与NameNode通信,NameNode与DataNode之间使用DataNodeProtocol交互,在设计上,NameNode不会主动发起RPC,而是响应来自客户端的DataNode的RPC请求,客户端与DataNode之间是使用socket进行数据传输,与NameNode之间的交互采用的nio封装的RPC。
  • HDFS有自己的序列化协议
  • 在数据块传输成功后但客户端没有告诉namenode之前如果namenode宕机那么这个数据块就会丢失
  • 在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户端
  • 在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过datanode会定期向namenode汇报自身信息。如果发现异常namenode会指挥datanode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式。

关于RPC和安全模式

  1. RPC通信

  2. 安全模式

    安全模式:Namenode启动后会进入一个称为安全模式的特殊状态。处于安全模式的Namenode是不会进行数据块的复制的。Namenode从所有的 Datanode接收心跳信号和块状态报告。块状态报告包括了某个Datanode所有的数据块列表。每个数据块都有一个指定的最小副本数。当Namenode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的;在一定百分比(这个参数可配置)的数据块被Namenode检测确认是安全之后(加上一个额外的30秒等待时间),Namenode将退出安全模式状态。接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他Datanode上。


2.3:HDFS读数据过程

  • 概述

    客户端将要读取的文件路径发送给namenode,namenode获取文件的元信息(主要是block的存放位置信息)返回给客户端,客户端根据返回的信息找到相应datanode逐个获取文件的block并在客户端本地进行数据追加合并从而获得整个文件。

  • 读取数据的详细步骤

在这里插入图片描述

  1. 客户端向NameNode发起RPC请求,请求读取文件数据

  2. NameNode检查文件是否存在,如果存在文件的元信息(blockid以及对应的DataNode列表)

  3. 客户端收到元信息后选取一个网络距离最近的datanode,依次请求读取每个数据块。客户端首先要校检文件是否损坏,如果损坏,客户端会选取另外的datanode请求

  4. datanode与客户端建立socket连接,传输对应的数据块,客户端收到数据缓存到本地,之后写入文件

  5. 依次传输剩下的数据块,直到整个文件合并完成

细节

从某个Datanode获取的数据块有可能是损坏的,损坏可能是由Datanode的存储设备错误、网络错误或者软件bug造成的。HDFS客户端软件实现了对HDFS文件内容的校验和(checksum)检查。当客户端创建一个新的HDFS文件,会计算这个文件每个数据块的校验和,并将校验和作为一个单独的隐藏文件保存在同一个HDFS名字空间下。当客户端获取文件内容后,它会检验从Datanode获取的数据跟相应的校验和文件中的校验和是否匹配,如果不匹配,客户端可以选择从其他Datanode获取该数据块的副本。

2.4:HDFS删除数据分析

HDFS删除数据比较流程相对简单,只列出详细步骤

  1. 客户端向NameNode发起RPC调用,请求删除文件。NameNode检查合法性
  2. NameNode查询文件相关元信息,向存储文件数据块的DataNode发出删除请求
  3. DataNode删除相关数据块。返回结果
  4. NameNode返回结果给客户端

细节

当用户或应用程序删除某个文件时,这个文件并没有立刻从HDFS中删除。实际上,HDFS会将这个文件重命名转移到/trash目录。只要文件还在/trash目录中,该文件就可以被迅速地恢复。文件在/trash中保存的时间是可配置的,当超过这个时间时,Namenode就会将该文件从名字空间中删除。删除文件会使得该文件相关的数据块被释放。注意,从用户删除文件到HDFS空闲空间的增加之间会有一定时间的延迟。只要被删除的文件还在/trash目录中,用户就可以恢复这个文件。如果用户想恢复被删除的文件,他/她可以浏览/trash目录找回该文件。/trash目录仅仅保存被删除文件的最后副本。/trash目录与其他的目录没有什么区别,除了一点:在该目录上HDFS会应用一个特殊策略来自动删除文件。目前的默认策略是删除/trash中保留时间超过6小时的文件。将来,这个策略可以通过一个被良好定义的接口配置。

当一个文件的副本系数被减小后,Namenode会选择过剩的副本删除。下次心跳检测时会将该信息传递给Datanode。Datanode遂即移除相应的数据块,集群中的空闲空间加大。同样,在调用setReplication API结束和集群中空闲空间增加间会有一定的延迟。

2.5:NameNode元数据管理原理分析

  • 概述

    NameNode职责:响应客户端请求、管理元数据。

    NameNode对元数据有三种存储方式:

    1. 内存元数据(NameSystem)
    2. 磁盘元数据镜像文件
    3. 数据操作日志文件(可通过日志运算出元数据)

    细节

    HDFS不适合存储小文件的原因,每个文件都会产生元信息,当小文件多了之后元信息也就多了,对NameNode会造成压力。

  • 对以上三种存储机制的进一步解释

    1. 内存元数据就是当前namenode正在使用的元数据,是存储在内存中的

    2. 磁盘元数据镜像文件是内存元数据的镜像,保存在namenode工作目录中,它是一个准元数据,作用是在namenode宕机时能够快速较准确的恢复元数据。称为fsimage

    3. 数据操作日志文件是用来记录元数据操作的,在每次改动元数据时都会追加日志记录,如果有完整的日志就可以还原完整的元数据。主要作用是用来完善fsimage,减少fsimage和内存元数据的差距。称为editslog

  • checkpoint机制分析

    因为namenode本身的任务就非常重要,为了不再给namenode压力,日志合并到fsimage就引入了另一个角色secondarynamenode。secondarynamenode负责定期把editslog合并到fsimage,“定期”是namenode向secondarynamenode发送RPC请求的,是按时间或者日志记录条数为“间隔”的,这样即不会浪费合并操作又不会造成fsimage和内存元数据有很大的差距。因为元数据的改变频率是不固定的。

    每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)。

    在这里插入图片描述

细节

  • namenode向secondarynamenode发送RPC请求,请求合并editslog到fsimage

  • secondarynamenode收到请求后从namenode上读取(通过http服务)editslog(多个,滚动日志文件)和fsimage文件

  • secondarynamenode会根据拿到的editslog合并到fsimage。形成最新的fsimage文件。(中间有很多步骤,把文件加载到内存,还原成元数据结构,合并,再生成文件,新生成的文件名为fsimage.checkpoint)。

  • secondarynamenode通过http服务把fsimage.checkpoint文件上传到namenode,并且通过RPC调用把文件改名为fsimage。

namenode和secondary namenode的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据

参考资料:
1:初步掌握HDFS的架构及原理:https://www.cnblogs.com/codeOfLife/p/5375120.html
2:深刻理解HDFS工作机制:https://www.cnblogs.com/wxisme/p/6270860.html

猜你喜欢

转载自blog.csdn.net/yilulvxing/article/details/88088621
今日推荐