热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HDP1:HDFS架构

学习目标:高可用、单机元数据内存受限、源码设计HDFS是如何实现有状态的高可用架构——HA解决单节点故障HDFS是如何从架构上解决单机内存受限问题——元数据内存受限问题HDFS能支




学习目标:高可用、单机元数据内存受限、源码设计


  • HDFS是如何实现有状态的高可用架构——HA解决单节点故障
  • HDFS是如何从架构上解决单机内存受限问题——元数据内存受限问题
  • HDFS能支撑起亿级流量的核心源码的设计

一、HDFS架构演进


1、Hadoop的三个版本:对应的三个HDFS版本

​ Hadoop1、2、3

​ HDFS 1、2、3

Hadoop1重点解决的两上问题:


  1. 海量数据如何存储
  2. 海量数据如何进行计算

2、HDFS1.0的架构:

​ HDFS1是一个主从式架构,主节点只有一个NameNode,从节点有多个叫DataNode

​ NameNode:

​ 1、管理元数据信息(文件目录树):文件与Block块,Block块与DataNode主机的关系

​ 2、NameNode为了快速响应用户的操作请求,所以所元数据加载到了内存里面

​ DataNode:

​ 1、存储数据,把上传的数据划分成为固定大小的文件块(Hadoop1默认是64MB)

​ 2、为了保证数据的安全,每个文件块默认都有三个副本


3、HDFS2:解决上一架构的缺陷:单节点故障、内存受限


3.1 单点故障:主备自动切换

解决方案图:ANN与SNN自动切换图:(也是在HDFS2解决的问题)

​ 同一时间只有一个ANN在服务,与SNN进行切换时需要实现自动切换,即ZooKeeper,在每个NN上安装一个ZKFC来监控每个NN的健康状况,下图中的绿色方块即ZK实现的一个锁机制,即只有ANN可以进,如果ANN出问题,则将此锁给SNN,并将SNN转换为ANN,实现了自动切换(在实际生产中,有些企业是不用JournalNode,而是直接改源码使用ZooKeeper来代替JournalNode进行存储解决单点故障问题)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CksXVn9m-1608650765428)(/Users/ryan/大数据/大数据架构师/img/image-20201222215138780.png)]

JournalNode是在MR2也就是Yarn中新加的,journalNode的作用是存放EditLog,同步元数据

在MR1中editlog是和fsimage存放在一起的然后SecondNamenode做定期合并,Yarn在这上面就不用SecondNamanode了

配置文件是;hdfs-site.xml文件负责

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruOjbAck-1608650765431)(/Users/ryan/大数据/大数据架构师/img/1353331-20191008160147206-1234947374.png)]

​ Active Namenode与StandBy Namenode之间的就是JournalNode,作用相当于NFS共享文件系统.Active Namenode往里写editlog数据,StandBy再从里面读取数据进行同步.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uB6lYhh0-1608650765434)(/Users/ryan/大数据/大数据架构师/img/1353331-20191008155625658-149426410.png)]

​ 两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当active状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。

​ standby状态的NameNode有能力读取JNs中的变更信息,并且一直监控edit log的变化,把变化应用于自己的命名空间。standby可以确保在集群出错时,命名空间状态已经完全同步了。

一般200个节点以内,JournalNode3个就够了,如果是2000个以内5个即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UlLoSqMe-1608650765436)(/Users/ryan/大数据/大数据架构师/img/1353331-20191008160409794-1622483165.png)]

如何做到两个NameNode?如何保证两个之间元数据一致性问题?


  • 共享目录方案:没人在用,万一共享目录出问题,数据就出问题了

  • QJM(Quorum Journal Manager):当你写一条数据到一个JournalNode,它就会自动同步到其它另外两个JournalNode上

    3.1.1 QJM原理:

    ​ 奇数点结点(集群能否正常提供服务的依据:只有超过二分之一的节点是存活的,集群才是健康的)组成。每个JournalNode对外有一个简易的RPC接口,以供NameNode读写EditLog到JN本地磁盘。当写EditLog时,NameNode会同时向所有JournalNode并行写文件,只要有N/2+1结点写成功则认为此次写操作成功,遵循Paxos协议。其内部实现框架如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULokzCh8-1608650765439)(/Users/ryan/大数据/大数据架构师/img/1508123397521_3709_1508123422520.png)]


    • FSEditLog类:管理EditLog文件与对大量log记录命名空间的个性,所有EditLog操作的入口

    • JournalSet: 维护Journal的集合,集成本地磁盘和JournalNode集群上EditLog的相关操作

    • FileJournalManager: 实现本地磁盘上 EditLog 操作

    • QuorumJournalManager: 实现JournalNode 集群EditLog操作

    • AsyncLoggerSet: 实现JournalNode 集群 EditLog 的写操作集合

    • AsyncLogger:发起RPC请求到JN,执行具体的日志同步功能

    • JournalNodeRpcServer:运行在 JournalNode 节点进程中的 RPC 服务,接收 NameNode 端的 AsyncLogger 的 RPC 请求。

    • JournalNodeHttpServer:运行在 JournalNode 节点进程中的 Http 服务,用于接收处于 Standby 状态的 NameNode 和其它 JournalNode 的同步 EditLog 文件流的请求。

      img

3.1.2 QJM写过程分析(超级重要:这个是解决可靠性也服务性能的关键——分段加锁与双缓冲方案)

​ 上面提到EditLog,NameNode会把EditLog同时写到本地和JournalNode。写本地由配置中参数dfs.namenode.name.dir控制,写JN由参数dfs.namenode.shared.edits.dir控制,在写EditLog时会由两个不同的输出流来控制日志的写过程,分别为:EditLogFileOutputStream(本地输出流)和QuorumOutputStream(JN输出流)。写EditLog也不是直接写到磁盘中,为保证高吞吐,NameNode会分别为EditLogFileOutputStream和QuorumOutputStream定义两个同等大小的Buffer,大小大概是512KB,一个写Buffer(buffCurrent),一个同步Buffer(buffReady),这样可以一边写一边同步,所以EditLog是一个异步写过程,同时也是一个批量同步的过程,避免每写一笔就同步一次日志

这个是怎么实现边写边同步的呢,这中间其实是有一个缓冲区交换的过程,即bufferCurrent和buffReady在达到条件时会触发交换,如bufferCurrent在达到阈值同时bufferReady的数据又同步完时,bufferReady数据会清空,同时会将bufferCurrent指针指向bufferReady以满足继续写,另外会将bufferReady指针指向bufferCurrent以提供继续同步EditLog。上面过程用流程图就是表示如下:

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bFBUUdaL-1608650765442)(/Users/ryan/大数据/大数据架构师/img/1508123437957_9118_1508123462816.png)]

3.1.3 两个问题(数据可靠性与一致性如何保证):

1)、既然EditLog是异步写的,怎么保证缓存中的数据不丢呢?

​ 这里虽然是异步,但实际所有日志都需要通过logSync同步成功后才会给client返回成功码,假设某一时刻NameNode不可用了,其内存中的数据其实是未同步成功的,所以client会认为这部分数据未写成功。

2)、EditLog怎么在多个JN上保持一致的呢?

2.1).隔离双写:

​ 在ActiveNameNode每次同步EditLog到JN时,先要保证不会有两个NN同时向JN同步日志。这个隔离是怎么做的。这里面涉及一个很重要的概念Epoch(时期) Numbers,很多分布式系统都会用到。Epoch有如下几个特性:


  • 当NN成为活动结点时,其会被赋予一个EpochNumber
  • 每个EpochNumber是惟一的,不会有相同的EpochNumber出现
  • EpochNumber有严格顺序保证,每次NN切换后其EpochNumber都会自增1,后面生成的EpochNumber都会大于前面的EpochNumber

QJM是怎么保证上面特性的呢,主要有以下几点:具体步骤


  • 第一步,在对EditLog作任何修改前,QuorumJournalManager(NameNode上)必须被赋予一个EpochNumber

  • 第二步, QJM把自己的EpochNumber通过newEpoch(N)的方式发送给所有JN结点

  • 第三步, 当JN收到newEpoch请求后,会把QJM的EpochNumber保存到一个lastPromisedEpoch变量中并持久化到本地磁盘

  • 第四步, ANN同步日志到JN的任何RPC请求(如logEdits(),startLogSegment()等),都必须包含ANN的EpochNumber

  • 第五步,JN在收到RPC请求后,会将之与lastPromisedEpoch对比,如果请求的EpochNumber小于lastPromisedEpoch,将会拒绝同步请求,反之,会接受同步请求并将请求的EpochNumber保存在lastPromisedEpoch



    • 这样就能保证主备NN发生切换时,就算同时向JN同步日志,也能保证日志不会写乱,因为发生切换后,原ANN的EpochNumber肯定是小于新ANN的EpochNumber,所以原ANN向JN的发起的所有同步请求都会拒绝,实现隔离功能,防止了脑裂。


    2.2). 恢复in-process日志

  • 为什么要这步呢,如果在写过程中写失败了,可能各个JN上的EditLog的长度都不一样,需要在开始写之前将不一致的部分恢复。恢复机制如下:


    1 ANN先向所有JN发送getJournalState请求;
    2 JN会向ANN返回一个Epoch(lastPromisedEpoch);
    3 ANN收到大多数JN的Epoch后,选择最大的一个并加1作为当前新的Epoch,然后向JN发送新的newEpoch请求,把新的Epoch下发给JN;
    4 JN收到新的Epoch后,和lastPromisedEpoch对比,若更大则更新到本地并返回给ANN自己本地一个最新EditLogSegment起始事务Id,若小则返回NN错误;
    5 ANN收到多数JN成功响应后认为Epoch生成成功,开始准备日志恢复;
    6 ANN会选择一个最大的EditLogSegment事务ID作为恢复依据,然后向JN发送prepareRecovery; RPC请求,对应Paxos协议2p阶段的Phase1a,若多数JN响应prepareRecovery成功,则可认为Phase1a阶段成功;
    7 ANN选择进行同步的数据源,向JN发送acceptRecovery RPC请求,并将数据源作为参数传给JN。
    8 JN收到acceptRecovery请求后,会从JournalNodeHttpServer下载EditLogSegment并替换到本地保存的EditLogSegment,对应Paxos协议2p阶段的Phase1b,完成后返回ANN请求成功状态。
    9 ANN收到多数JN的响应成功请求后,向JN发送finalizeLogSegment请求,表示数据恢复完成,这样之后所有JN上的日志就能保持一致。
    数据恢复后,ANN上会将本地处于in-process状态的日志更名为finalized状态的日志,形式如edits*[start-txid]*[stop-txid]。


    2.3).日志同步

    这个步骤上面有介绍到关于日志从ANN同步到JN的过程,具体如下:


    1 执行logSync过程,将ANN上的日志数据放到缓存队列中
    2 将缓存中数据同步到JN,JN有相应线程来处理logEdits请求
    3 JN收到数据后,先确认EpochNumber是否合法,再验证日志事务ID是否正常,将日志刷到磁盘,返回ANN成功码
    4 ANN收到JN成功请求后返回client写成功标识,若失败则抛出异常


    通过上面一些步骤,日志能保证成功同步到JN,同时保证JN日志的一致性,进而备NN上同步日志时也能保证数据是完整和一致的。

    2.4). StandbyNameNode的工作机制

  • 这个读过程是面向备NN(StandbyNN)的,SNN定期检查JournalNode上EditLog的变化,然后将EditLog拉回本地。SNN上有一个线程StandbyCheckpointer,会定期将SNN上FSImage和EditLog合并,并将合并完的FSImage文件传回主NN(ANN)上,就是所说的Checkpointing过程。下面我们来看下Checkpointing是怎么进行的。

    在2.x版本中,已经将原来的由SecondaryNameNode主导的Checkpointing替换成由SNN主导的Checkpointing。下面是一个CheckPoint的流向图:

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UpKKvWjp-1608650765445)(/Users/ryan/大数据/大数据架构师/img/1508123569245_7882_1508123594226.png)]

    ​ 【 图.Checkpointing流向图 】

    ​ 总的来说,就是在SNN上先检查前置条件,前置条件包括两个方面:距离上次Checkpointing的时间间隔和EditLog中事务条数限制。前置条件任何一个满足都会触发Checkpointing,然后SNN会将最新的NameSpace数据即SNN内存中当前状态的元数据保存到一个临时的fsimage文件( fsimage.ckpt)然后比对从JN上拉到的最新EditLog的事务ID,将fsimage.ckpt_中没有,EditLog中有的所有元数据修改记录合并一起并重命名成新的fsimage文件,同时生成一个md5文件。将最新的fsimage再通过HTTP请求传回ANN。通过定期合并fsimage有什么好处呢,主要有以下几个方面:

  • 可以避免EditLog越来越大,合并成新fsimage后可以将老的EditLog删除

  • 可以避免主NN(ANN)压力过大,合并是在SNN上进行的

  • 可以保证fsimage保存的是一份最新的元数据,故障恢复时避免数据丢失


3.2 内存受限:HDFS联邦

​ HDFS为了快速响应客户请求,它会把元数据状态存储在内存中,以实现快速响应。

一般用到联邦是在节点超过1000台以上,即将NN设置为多组,类似于C盘,D盘,E盘方案,可以通过联邦实现多组ANN同时使用,当客户进行访问时就可以指定元数据存储的位置,和DN没有任何关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gu98kVTY-1608650765448)(/Users/ryan/大数据/大数据架构师/img/image-20201222215431315.png)]

联邦即引入了NameSpace,原先单NameNode只有Block块组成,使用联邦后由namespace(命名空间)和Block Storage(块的存储)两层,由目录、文件、块组成。采用联邦后解决了内存受限问题,但还是存在单节点故障,所以每组下面都会有一个ANN和SNN组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yp0B67CR-1608650765451)(/Users/ryan/大数据/大数据架构师/img/70.png)]

当用户存储文件时需要存到某组NN中时,采用"文件名hash"的方法,这些文件可能会被放到不同的namespace中,为了方便管理多个命名空间,HDFS Federation采用了经典的Client Side Mount Table

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7G1UVcy-1608650765454)(/Users/ryan/大数据/大数据架构师/img/image-20201222225236409.png)]


4、HDFS3架构:支持多NN

​ HA方案支持多个Namenode,引入纠删码技术。


二、亿级流量支撑——分段加锁与双缓冲方案

思考:

NN管理着元数据,用户所有的操作请求都要操作NN,大一点的平台一天需要运行几十万,上百万的任务。一个任务就会有很多的请求,这些所有的请求都会在NN这儿(更新目录树),对于NN来说这就是亿级的流量,NN是如何支撑亿级流量的呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hJdZGLU0-1608650765458)(/Users/ryan/大数据/大数据架构师/img/image-20201222231538451.png)]

为了保证数据的安全,必须将内存中的数据写到磁盘上,记录日志,为了解决磁盘IO瓶颈,引入:分段加锁和双缓冲的方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vBdpxE8-1608650765461)(/Users/ryan/大数据/大数据架构师/img/image-20201222231816464.png)]

​ 使用内存缓冲:CurrentBuffer响应客户并发请求,到一定闽值时进行内存交换,交给SyncBuffer进行溢写磁盘,与Kafka的原理一样。



推荐阅读
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • Hadoop2.6.0 + 云centos +伪分布式只谈部署
    3.0.3玩不好,现将2.6.0tar.gz上传到usr,chmod-Rhadoop:hadophadoop-2.6.0,rm掉3.0.32.在etcp ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • Hadoop源码解析1Hadoop工程包架构解析
    1 Hadoop中各工程包依赖简述   Google的核心竞争技术是它的计算平台。Google的大牛们用了下面5篇文章,介绍了它们的计算设施。   GoogleCluster:ht ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
author-avatar
万熊卡拉梦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有