20190319-HDFS详解

核心设计

20190319-HDFS详解

数据块

HDFS上最基本的存储单位,默认大小128M,小于一个块大小的文件不会占据整个块的空间,快非常适合用于数据备份进而提供数据容错能力和可用性。

数据复制

HDFS为了做到可靠性reliability创建了多分数据块data blocks的复制replicas,并将它们放置在服务器群的计算节点compute nodes中,MapResource就可以在它们所在的节点上处理这些数据了
HDFS将每个文件存储成块序列
每个文件的block大小和复制因子replication都是可配置的

HDFS副本存放策略
  • 作用:数据分块存储和副本的存放,是保证可靠性和高性能的关键

  • 存放说明:在大多数情况下,HDFS默认的副本系数是3

  • 存放策略:
    将每个文件的数据进行分块存储,每一个数据块又保存有多个副本,这些数据块副本分布在不同的机器节点
    Hadoop默认对3个副本的存放策略

1)第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的,系统会尝试不选择哪些太满或者太忙的node)
2)第二个副本放置在第一个节点相同的机架中的不同node中(随机选择)
3)第三个副本和第一个在不同机架中,随机放在不同的node中
4)更多副本随机节点
20190319-HDFS详解

Hadoop心跳机制

Hadoop是Master/Slave结构
Master中有NameNode和ResourceManager
Slave中有Datanode和NodeManager
Slave启动时,会主动链接master,并且每隔3秒链接一次master我们形象的称为心跳。Slave通过心跳汇报自己的信息个master,master也通过心跳给slave下达命令
NameNode通过心跳得知Datanode的状态
ResourceManager通过心跳得知NodeManager的状态
如果master长时间都没有收到slave的心跳,就认为该slave挂掉了

安全模式

集群启动后,可以查看目录,但是上传文件时报错,打开web页面可看到namenode正处于safemode状态。namenode的三种状态:active,standby,safemode

1.进入安全模式的原因:块的丢失,增加新节点时,刚启动时文件还没加载完成
2.能做的:等待
3.进入安全模式的原理
namenode发现集群中的block丢失率达到一定比例,namenode就会进入安全模式,在安全模式下,客户端不能对任何数据进行操作,只能查看元数据信息(比如ls/mkdir)
4.如何退出安全模式?

  • 找到问题所在 进行修复
    比如修复宕机的datanode
  • 手动强行退出安全模式
    (没有解决真正的问题)
hadoop dfsadmin -safemode leave
  • 安全模式常用的操作命令
hdfs dfsadmin -safemode leave     //强制 NameNode 退出安全模式
hdfs dfsadmin -safemode enter     //进入安全模式
hdfs dfsadmin -safemode get         //查看安全模式状态
hdfs dfsadmin -safemode wait         //等待,一直到安全模式结束

原理剖析

HDFS工作机制

1.HDFS写数据
20190319-HDFS详解

  • 步骤
    1)Client向NameNode发起RPC请求
    2) NameNode检查创建的文件是否存在
    3) 数据队列(data queue)管理packet并向NN申请blocks,
    4) 以pipeline将packet写入所有的replicas中。以流的方式写入第一个DN,再传递给下一个DN,直到最后一个DN
    5) 最后一个DN成功存储之后会返回一个ack packet,成功收到DN返回的 ack packet 后会移除packet;某个DN出现了故障,pipeline会被关闭,出现故障的DN会移除,剩余的block会继续传输,同时NN会分配一个新的DN,保持设定的数量。
    6)完成写入后,关闭数据流
    7)告知NN,写数据完成

2.HDFS读数据
20190319-HDFS详解

  • 步骤
    1)Client向NameNode发起RPC请求
    2)NN返回有block拷贝的DN地址
    3)Client 会选取DN读取block
    4)读取完当前block的数据后,关闭当前的DN链接,寻找下一个最佳的DN
    5)当读完列表后,且没有结束,会继续向NN获取下一批block列表
    6)读取完一个block都会进行checksum验证,如都没有错误,则关闭资源
NameNode工作机制

1.Namenode对数据的管理

  • 内存元数据metadata
    1)从形式上讲,元数据可分为内存元数据和元数据文件两种。其中NameNode在内存中维护整个文件系统的元数据镜像,用于HDFS的管理;元数据文件则用于持久化存储。

    2)从类型上讲,元数据有三类重要信息:
    -第一类是文件和目录自身的属性信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等。
    -第二类记录文件内容存储相关信息,例如文件块情况、副本个数、每个副本所在的Data Node 信息等。
    -第三类用来记录HDFS中所有Data Node信息,用于Data Node管理。

    3)内存元数据结构
    INode
    文件和目录是文件系统的基本元素,HDFS将这些元素抽象成INode,每一个文件或目录都对应一个唯一的INode。它由FSNamesystem的成员变量dir实现对整个HDFS中INode的组织和操作,它是一个FSDirectory类。

    INode信息完全位于内存,因此有效的提高元数据的服务性能,然而一旦掉电将不再存在,故需要将INode信息保存到磁盘,这个功能是由FSImage完成的,它是架构在内存元数据与磁盘元数据文件之间的桥梁。

    由于所有的元数据位于内存,其大小随文件系统的规模增大而增大,如果每次都将整个内存元数据导出磁盘,将会带来很大的系统开销,所以HDFS在实现时,没有采用定期导出元数据的方法,而是采用元数据镜像文件(FSImage)+日志文件(edits)的备份机制,其中镜像文件是某一时刻内存元数据的真实组织情况,而日志文件则记录了该时刻以后所有的元数据操作 。

    Block
    Block是对于文件内容组织而言的,按照固定大小,顺序对文件进行划分并编号,划分好的每一个块就称之为一个Block,HDFS默认的Block大小为128MB。

    当一个客户端访问某一个文件特定偏移量的内容时,HDFS首先根据路径信息找到该文件对应的INode ,根据偏移计算出Block位置,然后找出相应的BlockInfo,再找到副本所在Data Node 的信息,选择其中一个Data Node进行连接,获取相应的内容。

    4)磁盘元数据文件
    磁盘元数据文件包括以下四个:

    fsimage:元数据镜像文件

    edits:日志文件

    fstime:保存最近一次Checkpoint的时间。

    VERSION:标志性文件,最后被创建,它的存在表明前三个元数据文件的创建成功。

  • 磁盘数据镜像文件fsimage
    镜像文件实际是存放目录结构、文件属性等相关信息。fsimage文件是NameNode中关于元数据的镜像,一般称为检查点,它是在NameNode启动时对整个文件系统的快照。fsimage文件是hadoop文件系统元数据的一个永久性的检查点,其中包含hadoop文件系统中的所有目录和文件idnode的序列化信息。

  • 数据操作日志文件edits
    记录着对集群的每一个操作。编辑日志是记录对文件或者目录的修改信息,比如删除目录,修改文件等信息。编辑日志一般命名规则是“edits_*”,它在NameNode启动后,记录对文件系统的改动序列。edits文件存放的是hadoop文件系统的所有更新操作的路径,文件系统客户端执行的所有写操作首先会被记录到edits文件中。

2.存储机制
内存中有一份完整的元数据(内存metadata)
磁盘有一个”准完整“的元数据镜像文件(在NN的工作目录中)
用于衔接内存metadata和持久化元数据镜像fsimage之间的操作日志(edits文件)

DataNode工作机制

工作职责
存储管理用户的文件块数据
定期向 NameNode 汇报自身所持有的 block 信息(通过心跳信息上报)

SecondaryNamenode工作机制

edits文件会在集群运行的过程中不断增多,占用更多的存储空间,虽然有合并,但是只有在namenode重启时才会进行。并且在实际工作环境很少重启namenode,
这就带来了一下问题:
(1)edits文件不断增大,如何存储和管理?
(2)因为需要合并大量的edits文件生成fsimage,导致namenode重启时间过长。
(3)一旦namenode宕机,用于恢复的fsiamge数据很旧,会造成大量数据的丢失。

1.SNN通知NN切换edits文件
SecondaryNameNode通知NameNode准备提交edits文件,此时主节点将新的写操作数据记录到一个新的文件edits.new中。

2.SNN从NN获得fsimage和edits
SecondaryNameNode通过HTTP GET方式获取NameNodFailed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.e的fsimage与edits文件(在SecondaryNameNode的current同级目录下可见到 temp.check-point或者previous-checkpoint目录,这些目录中存储着从namenode拷贝来的镜像文件)。

3.SNN将fsimage载入内存,然后开始合并edits
SecondaryNameNode开始合并获取的上述两个文件,产生一个新的fsimage文件fsimage.ckpt。

4.SNN将新的fsimage发回给NN
SecondaryNameNode用HTTP POST方式发送fsimage.ckpt至NameNode。

5.NN用新的fsimage替换旧的fsimage
NameNode将fsimage.ckpt与edits.new文件分别重命名为fsimage与edits,然后更新fstime,整个checkpoint过程到此结束。
20190319-HDFS详解

从工作过程可以看出,SecondaryNameNode的重要作用是定期通过编辑日志文件合并命名空间镜像,以防止编辑日志文件过大。SecondaryNameNode一般要在另一台机器上运行,因为它需要占用大量的CPU时间与namenode相同容量的内存才可以进行合并操作。它会保存合并后的命名空间镜像的副本,并在namenode发生故障时启用。

HDFS的HA运行机制

20190319-HDFS详解

  • Active NameNode 和 Standby NameNode
    两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。

  • 主备切换控制器 ZKFailoverController
    ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode 目前也支持不依赖于 Zookeeper 的手动主备切换。

  • Zookeeper 集群
    为主备切换控制器提供主备选举支持。

  • 共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和

  • NameNode
    通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。

  • DataNode 节点
    除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。

流程
20190319-HDFS详解
1.HealthMonitor 初始化完成之后会启动内部的线程来定时调用对应 NameNode 的HAServiceProtocol RPC 接口的方法,对 NameNode 的健康状态进行检测。
2.HealthMonitor 如果检测到 NameNode 的健康状态发生变化,会回调 ZKFailoverController 注册的相应方法进行处理。
3.如果 ZKFailoverController 判断需要进行主备切换,会首先使用 ActiveStandbyElector 来进行自动的主备选举。
4.ActiveStandbyElector 与 Zookeeper 进行交互完成自动的主备选举。
5.ActiveStandbyElector 在主备选举完成后,会回调 ZKFailoverController 的相应方法来通知当前的 NameNode 成为主 NameNode 或备 NameNode。
6.ZKFailoverController 调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法将 NameNode 转换为 Active 状态或 Standby 状态。
20190319-HDFS详解