HDFS NameNode 高并发数据读写架构及QJM选举深入研究-Hadoop商业环境实战

本文主要是介绍HDFS NameNode 高并发数据读写架构及QJM选举深入研究-Hadoop商业环境实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。期待加入IOT时代最具战斗力的团队。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。

1 Hadoop 2.x 系统架构演进

  • 2.x版本中,HDFS架构解决了单点故障问题,即引入双NameNode架构。
  • 同时借助共享存储系统来进行元数据的同步,共享存储系统类型一般有几类,如:Shared NAS+NFS、BookKeeper、BackupNode 和 Quorum Journal Manager(QJM),下图中用的是QJM作为共享存储组件,通过搭建奇数结点的JournalNode实现主备NameNode元数据操作信息同步。

  • QJM全称是Quorum Journal Manager, 由JournalNode(JN)组成,一般是奇数点结点组成。每个JournalNode对外有一个简易的RPC接口,以供NameNode读写EditLog到JN本地磁盘。当写EditLog时,NameNode会同时向所有JournalNode并行写文件。

2 高并发与QJM写过程息息相关(高并发)

  • EditLog同时写到本地和JournalNode两处地方。
  • 写本地由配置中参数dfs.namenode.name.dir控制。
  • 写JN由参数dfs.namenode.shared.edits.dir控制。
  • 在写EditLog时会由两个不同的输出流来控制日志的写过程,分别为:EditLogFileOutputStream(本地输出流)和QuorumOutputStream(JN输出流)。
  • NN写EditLog也不是直接写到磁盘中,为保证高吞吐,NameNode会分别为EditLogFileOutputStream和QuorumOutputStream定义两个同等大小的Buffer,大小大概是512KB,一个写Buffer(buffCurrent),一个同步Buffer(buffReady),这样可以一边写一边同步,所以EditLog是一个异步写过程,同时也是一个批量同步的过程,避免每写一笔就同步一次日志。
  • 双写双同步过程:hadoop定义了一个缓冲区交换的过程,即bufferCurrent和buffReady。在达到条件时会触发交换。一个负责EditLog写入缓冲区,另外一个缓冲区负责写入磁盘并同步到JournalNodes。
  • 如bufferCurrent在达到阈值同时bufferReady的数据又同步完时,bufferReady数据会清空,同时会将bufferCurrent指针指向bufferReady以满足继续写,另外会将bufferReady指针指向bufferCurrent以提供继续同步EditLog到JN。

  • NameNode使用多线程接收多个客户端发送过来的并发的请求,但是瓶颈却出现在后续的写edits log上。此时就会出现本地磁盘 + 网络传输给journalnodes,性能两大瓶颈:磁盘写 + 网络写!

  • 分段加锁机制 + 内存双缓冲机制

  • 多个客户端线程可以快速的获取锁,生成全局锁txid,然后快速的将edits log写入内存缓冲。每一次只会有一个线程获取全局锁,但是注意因为是写缓冲区,所以很快就会释放锁。

  • 缓冲区的交换发生在EditLog同步结束后,当来一个线程进行检查有没有谁在写磁盘和网络,如果没有了直接交换双缓冲的区域buffCurrent和区域buffReady,接着第二次释放锁。这个过程相当快速,内存里判断几个条件,耗时不了几微秒。

  • 同步EditLog到JN时,有一个专有线程可以批量的将一个缓冲中的多条edits log刷入磁盘和网络。

  • 因此只要没有线程在写磁盘和网络,就达到了缓冲区交换的目的。

  • 也就因此达到了每秒数千次的高并发请求。

      详情请参考石杉的架构笔记:https://juejin.im/post/5bec278c5188253e64332c76
    

3 QJM的隔离双写机制

  • 在ANN每次同步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的发起的所有同步请求都会拒绝,实现隔离功能,防止了脑裂。

3 主备NN切换机制

  • 要完成HA,除了元数据同步外,还得有一个完备的主备切换机制,Hadoop的主备选举依赖于ZooKeeper。
  • HealthMonitor: 监控NameNode健康状态,若状态异常会触发回调ZKFailoverController进行自动主备切换。
  • ActiveStandbyElector: 通知ZK执行主备选举,若ZK完成变更,会回调ZKFailoverController相应方法进行主备状态切换。
  • 防脑裂: ZK本身是强一致和高可用的,可以用它来保证同一时刻只有一个活动节点。
  • ZKFailoverController: 是HealthMontior和ActiveStandbyElector的母体,执行具体的切换操作。

4 hadoop的Chunk缓冲机制(文件上传)

  • Chunk缓冲机制:hadoop支持超大规模的文件上传和数据写入,那么在HDFS客户端源码中,内部实现了高效的chunk缓冲机制。上传数据时首先会被写入一个chunk缓冲数组,这个chunk是一个512字节0.5KB大小的数据片段,而最终的容器是一个缓冲数组,一般为9个chunk的大小,该数组可以容纳多个chunk大小的数据在里面缓冲。基于此机制就可以支持大数据量的文件上传。
  • 当chunk缓冲数组都写满了之后,就会把这个chunk缓冲数组根据chunk大小(512字节0.5KB)切割为多个chunk,一个chunk是一个数据片段,默认是512字节0.5KB。
  • 然后多个chunk会直接一次性写入另外一个内存缓冲Packet数据包内,Packet数据包可以容纳127个chunk,大小大致为64KB。
  • Packet数据包机制:通过这个Packet数据包机制的,可以在内存中容纳大量的数据,避免了频繁的网络传输。
  • 内存队列异步发送机制:当一个Packet被塞满了chunk之后,就会放进一个内存队列进行FIFO排队。
  • DataStreamer线程会不断的获取队列中的Packet数据包,通过网络传输直接连续发送Packet数据包给DataNode,当写满一个Block时,就会通知NameNode Block写入完毕。
  • 本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。期待加入IOT时代最具战斗力的团队。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。

5 hadoop文件契约机制(大规模HDFS文件写请求过期处理)

  • 多个客户端同时并发的写Hadoop HDFS上的同一个文件是不被允许的,因为HDFS上的文件是不允许并发写的。
  • 通过文件契约机制,可以保证同一时间只有一个客户端线程访问同一个文件。
  • 该客户端通过开启一个契约后台线程,不断的进行文件续约,如果某个契约很长时间没续约了,此时就自动过期掉这个契约,让其他的HDFS客户端来写。
  • 注意问题来了,一个nameNode内部可能有成千上万个客户端来同时修改hdfs上的成千上万个文件,这种情况下,如何保证契约后台线程去优雅的检查成千上万个文件的契约是否过期?
  • 在HDFS内部维护了一个TreeSet数据结构来根据最近一次续约时间对契约进行排序,因此往往最老的契约就排在了TreeSet的最前面,最近续约的契约就放在了TreeSet的最后面。每次检查契约是否过期的时候,不用再遍历成千上万的契约,直接判断TreeSet最前面契约还没过期,那么就不用继续检查了!
  • 如果一个契约过期了,那么就删掉最老契约,然后再检查第二旧契约,依次类推。
  • TreeSet排序 + 优先检查最旧契约的机制在支持大规模HDFS文件写请求上,有非常好的性能提升。

6 总结

一直想深入到Hadoop源码上,仔细的研究一番,奈何时间有限,大数据技术栈体系还没有完全形成,希望我的博客系列在完整成型后,深入的研究一波源码。辛苦成文,实属不易。各自珍惜。

另外参考了大神的作品,来完成我的个人学习笔记,勿怪,谢谢!附上地址:https://juejin.im/post/5bf80bd66fb9a049ee801ad9。

本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。期待加入IOT时代最具战斗力的团队。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。

秦凯新 于深圳 201812020147

这篇关于HDFS NameNode 高并发数据读写架构及QJM选举深入研究-Hadoop商业环境实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/441267

相关文章

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper

Python给Excel写入数据的四种方法小结

《Python给Excel写入数据的四种方法小结》本文主要介绍了Python给Excel写入数据的四种方法小结,包含openpyxl库、xlsxwriter库、pandas库和win32com库,具有... 目录1. 使用 openpyxl 库2. 使用 xlsxwriter 库3. 使用 pandas 库

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前

SpringBoot定制JSON响应数据的实现

《SpringBoot定制JSON响应数据的实现》本文主要介绍了SpringBoot定制JSON响应数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录前言一、如何使用@jsonView这个注解?二、应用场景三、实战案例注解方式编程方式总结 前言

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑