NameNode的元数据管理详细流程

在这里插入图片描述

这里使用的是Hadoop2.7源码包,以创建目录为例,mkdir的流程看NameNode的元数据管理。使用HDFS的JavaAPI创建目录时,会调用Hadoop的FileSystem的mkdir方法,进去之后来到实现类DistributedFileSystem的mkdir方法,然后会进行一些权限检查的操作FsPermission,通过DFSClient连接NameNode并获取到NameNodeRpcServer的一个代理对象namenode。通过这个namenode对象远程调用NameNodeRpcserver的mkdir代码。此时代码流程由客户端来到NameNode上
 NameNodeRpcServer通过FSSystem对象创建目录,在此之前会检查NameNode是否处于安全模式checkNameNodeSafeMode,当不处于安全模式时获取到FSDirectory元数据目录树对象,同时解析传入的路径看是否满足创建条件。解析完后将传入的目录路径封装成INodesInPath,在FSDirectory中找到父目录的位置,同时判断是需要创建目录还是创建文件,目录则封装成INodeDirectory,文件则封装成INodeFile,同时也会坚持是否满足创建目录的条件,最后将这个对象添加到父目录下,父目录也是个INodeDirectory对象。List 文件和目录都是添加进这样一个数据结构,此时activeNameNode的内存元数据已经更新完成。在之后会获取到FSEditLog对象调用logSync()将元数据日志刷写至磁盘,如图所示。
 logSync()HDFS为了提高效率,这里采用的是双缓存机制刷写磁盘。首先是写磁盘操作,通过EditLogFileOutputStream对象将日志写入到内存缓冲中bufCurrent,然后和bufReady内存缓冲交换内存地址,由bufReady将日志刷写至磁盘,此过程只是简单描述,其中用了许多分段加锁机制,在多线程的情况下保证了日志刷写的顺序以及bufReady只要有日志就一直处于刷写磁盘的过程提高了效率。同时往journalNode中发送日志也是采用的此机制,并且代码共用了,只是实现类不一样,往journalNode发日志使用的是QuorumOutputStream,也是双缓存,只不过在写磁盘改成了往journalNode集群发送日志数据,根据配置文件配置的journalNode集群信息,生成对应的AsyncLogger集合,一个AsyncLogger对应一台journalNode,异步发送日志信息至每台journalNode机器上,此过程也是用的PRC通信,所以按照之前的惯例先获取JournalNodeRpcServer代理对象,远程调用JournalNodeRpcServer上的journal方法将日志保存进磁盘,到此activeNameNode往磁盘和journalNode发送元数据日志完成。
 StandbyNameNode启动时会启动一个EditLogTailer线程用于定期从journalNode中获取元数据日志,每隔60s。首先会获取StandbynameNode自己当前的内存中的元数据的对象,获取到最后一条日志的ID,设置获取Journalnode获取日志的流,构建FSEditLogLoader对象,根据自己日志的最大ID去journalNode获取对应ID后续的日志,这里和journalNode通信使用的是HTTP,会根据journalNode的连接信息创建HttpURLConnection,连接journalNode上的journalNodeHttpServer,然后在standbynamenode处通过封装获取到DataInputStream输入流来获取日志,获取到日志对象后根据日志的操作类型对自己的元数据目录树对象进行修改,这里我们是mkdir,所以和activeNameNode的操作一样,将目录封装成INodeDirectory添加到父目录下。到此standbynamenode从journalNode获取editlog结束。
 standByNamenode为了保证元数据安全和减轻activeNameNode合并元数据的压力,还会有个checkpoint的操作。同样在启动时会开启一个StandbyCheckpointer线程用于定期执行元数据的checkpoint,该线程启动后每隔60秒检查一次,根据这个参数配置dfs.namenode.checkpoint.check.period,不能超过1小时,超过一小时默认就是1小时checkpoint一次。当检查到当前日志累积超过100万条没有checkpoint或者超过1小时没有执行checkpoint时就会执行checkpoint操作。调用FSImage的saveNamespace方法将日志刷写保存至磁盘,同时开启一个线程TransferFsImage用于将standbyNameNode的合并后最新的fsimage替换activeNameNode上的最新的fsimage。这里和activeNameNode的连接采用的也是HTTP,比较适合大数据量的传输。同理连接至active上的NameNodeHttpServer调用了ImageServlet将传输过来的数据重命名后替换active本地的fsimage。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值