在数据块报告过程中,如果遇到报告的块的时间戳大于从节点NameNode的时间戳,会将这样的数据块放入一个消息队列,等从节点消化到相关的块信息,再从消息队列中取出数据块,建立块信息与副本的映射关系。这样,报告的块是放入消息队列呢还是直接建立映射,就取决于时间戳的判断了。这个机制具体是如何实现的呢?下面通过一个示意图来说明。
由上图,该机制分为如下步骤:
1. 主节点NameNode在分配块的时候会递增系统时间戳,并将该时间戳赋值给分配的块,同时将时间戳与文件相应的块信息写入日志管理器内的日志文件;
2. Client上传块信息到DataNode节点,上传完成,DataNode向主从节点报告块信息;
3. 从节点接收到DataNode节点的块报告,如果从节点还没有消化到相应块的时间戳及其块信息,从节点将该块加入消息队列(MQ);
4. 从节点消化到时间戳与文件块信息,从MQ队列中读取到报告的块,然后建立块信息与副本的映射关系;
当然,如果从节点消化到块信息先于DataNode节点报告块信息,则从节点就不会将报告的块加入MQ,而是进入建立块信息与副本的映射流程。这种机制有一个好处就是,如果从节点没有消化到相应的块信息,DataNode不用通过重试向从节点NameNode反复报告块信息,这样会增加DataNode与Namenode的通信压力,而是先保存报告的块信息,等从节点消化到相应块后,直接建立映射。主从节点模式,默认情况下,日志消化的间隔是1分钟,因此也不会因为在MQ内积累太多的块信息而导致从节点性能变慢。