HDFS源码分析心跳汇报之数据块增量汇报

本文深入解析HDFS中DataNode如何周期性地通过reportReceivedDeletedBlocks()方法向NameNode报告数据块的增量变化,包括接收中、已接收和已删除的数据块。介绍了该过程涉及的关键步骤、条件以及数据结构,揭示了HDFS在数据同步和容错性上的设计智慧。
摘要由CSDN通过智能技术生成

        在《HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程》一文中,我们详细了解了数据节点DataNode周期性发送心跳给名字节点NameNode的BPServiceActor工作线程,了解了它实现心跳的大体流程:

        1、与NameNode握手:

              1.1、第一阶段:获取命名空间信息并验证、设置;

              1.2、第二阶段:DataNode注册;

        2、周期性调用sendHeartBeat()方法发送心跳信息,并处理来自心跳响应中的命令;

        3、调用reportReceivedDeletedBlocks()方法发送数据库增量汇报:包括正在接收的、已接收的和已删除的数据块;

        4、调用blockReport()方法周期性进行数据块汇报,并处理返回的相关命令。

        本文,我们重点讲解下其中的第三步:调用reportReceivedDeletedBlocks()方法发送数据库增量汇报:包括正在接收的、已接收的和已删除的数据块。

        首先,这个数据块增量汇报是什么情况下发生的呢?在DataNode与NameNode握手并注册后实现心跳的offerService()方法的while循环内,有这么一段代码,如下:

        // 如果标志位sendImmediateIBR为true,或者数据块增量汇报时间已到,
        // 数据块增量汇报时间间隔是心跳时间间隔的100倍,默认情况下是5分钟
        if (sendImmediateIBR ||
            (startTime - lastDeletedReport > dnConf.deleteReportInterval)) {
          // 调用reportReceivedDeletedBlocks()方法发送数据块增量汇报
          reportReceivedDeletedBlocks();
          
          // 设置上次数据块增量汇报时间lastDeletedReport为startTime
          lastDeletedReport = startTime;
        }
        首先,这个sendImmediateIBR是一个标志位,它标识着是否立即发送一个数据块增量汇报,在BPServiceActor工作线程初始化时默认为false。而数据块增量汇报是否发送,这里有两个条件,只要满足其中一个即可发送数据块增量汇报:

        1、是否立即发送一个数据块增量汇报的标志位sendImmediateIBR为true;

        2、数据块增量汇报的时间间隔已到:数据块增量汇报的时间间隔是心跳时间间隔的100倍,默认情况下是5分钟。

        在讲解reportReceivedDeletedBlocks()方法前,我们先看BPServiceActor工作线程的一个成员变量,定义如下:

  /**
   * Between block reports (which happen on the order of once an hour) the
   * DN reports smaller incremental changes to its block list. This map,
   * keyed by block ID, contains the pending changes which have yet to be
   * reported to the NN. Access should be synchronized on this object.
   * 
   * 在数据块汇报(通常一小时一次)之间,DataNode会汇报其数据块列表的增量变化情况。
   * 这个Map,包含尚未汇报给NameNode的DataNode上数据块正在发生的变化。
   * 访问它必须使用synchronized关键字。
   */
  private final Map<DatanodeStorage, PerStoragePendingIncrementalBR>
      pendingIncrementalBRperStorage = Maps.newHashMap();
        先说下这个pendingIncrementalBRperStorage变量对应的数据结构,它是一个Map,key为DatanodeStorage类型,value为PerStoragePendingIncrementalBR类型。而这个PerStoragePendingIncrementalBR类型在其内部封装了一个叫做pendingIncrementalBR的HashMap,key为blockId,value为ReceivedDeletedBlockInfo,ReceivedDeletedBlockInfo对Block做了一层封装了,它标识了对应Block在DataNode上的状态BlockStatus,BlockStatus是一个枚举类,包含的Block状态分别有正在接收的数据块RECEIVING_BLOCK(1)、已经接收的数据块RECEIVED_BLOCK(2)、已被删除的数据块DELETED_BLOCK(3)三种状态。

        也就是说,pendingIncrementalBRperStorage实际上存储了DataNode上每个DatanodeStorage到对应的增量数据块集合的映射关系,而这个增量数据块,包含正在接收的、已接受的和已删除的。

        在数据块汇报(通常一小时一次)之间,DataNode会汇报其数据块列表的增量变化情况,这个是作为一个小的(smaller)汇报进行的。这个Map,包含尚未汇报给NameNode的DataNode上数据块正在发生的变化,访问它必须使用synchronized关键字。而这个数据块增量汇报,其主要目的就应该是尽早让名字节点NameNode了解数据节点DataNode上数据块的变化情况,而不是通过正常的每小时一次的数据块汇报来告知名字节点,那样的话对于整个文件系统来说,是很被动的一见事。

        好了,我们再看下reportReceivedDeletedBlocks()方法,它是完成数据块增量汇报的核心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值