HDFS中的SecondaryNameNode节点解析

      大家都知道,在HDFS的集群中有三类节点:NameNode、SecondaryNameNode和DataNode,同时在集群中只有一个NameNode节点,一个SecondaryNameNode节点,剩余的就都是DataNode节点(当然,集群中也可以同时存在多个SecondaryNameNode节点,但这没多大必要,一方面会增加NameNode节点的压力,使其忙于元数据的传输与接收、日志的传输与切换而导致性能的下降,另一方面NameNode节点并不支持做并发checkpoint)。这中master-slave架构虽然简单,却会存在一个致命的问题,那就NameNode节点的单点故障问题(single point of failure),尽管它发生的概率比较小,但对于系统维护人员来说是不容忽视的问题。当然本文不会讨论有关NameNode节点单点故障的社区解决方案而是主要讲解SecondaryNameNode节点(从NameNode)在HDFS中扮演了怎样的角色?

       SecondaryNameNode节点启动之后会不断的对NameNode节点保存的元数据进行备份(定时备份),具体的说来就是:SecondaryNameNode的run方法每隔一段时间就会执行doCheckpoint()方法,SecondaryNameNode的主要工作都在这个方法里。这个方法会从NameNode上取下FSImage和操作日志(当然也包括版本文件和fstime),然后在本地合并,然后再把合并后的FSImage传回NameNode。这样既可以保存一个NameNode上的数据备份,又可以为NameNode节点分担一部分压力。具体的流程如下:

     1.调用startCheckpoint,为接下来的工作准备空间。首先存放FSImage和EditsLog的目录分别由配置文件中的fs.checkpoint.dir项和fs.checkpoint.edits.dir项来设置,然后会分别对这两类目录进行检查和恢复,对于已经存在的chechpoint要将它们设置成为lastCheckpoint;

     2. 创建RPC客户端,用于和NameNode节点通信;

     3.在SecondaryNameNode节点上开启Http服务,主要用来向NameNode节点传输合并好的元数据文件FSImage;

     4.远程调用NameNode的rollEditLog方法,让NameNode停止向edits上写操作日志,而是将新产生的日志转写到临时日志文件edits.new上。同时,NameNode端的FSImage检查点状态要设置为ROLLED_EDITS。最后会返回一个检查点签名CheckpointSignature;

     5.通过NameNode开启的Http服务从NameNode上下载FSImage和对应的操作日志,之后设置本地的检查点状态设置为UPLOAD_DONE;

     6.加载下载的FSImage和操作日志,从而合并成一个新的FSImage;

     7.通知NameNode新的FSImage文件已经合并好了,然后NameNode节点通过SecondaryNameNode节点的http服务来下载新的FSImage;

     8.远程调用NameNode的rollFsImage,来根据下载的最新FSImage替换原来的FSImage,临时日志文件edits.new重命名为edits;

     9.结束本地的一次doCheckpoint

还是来整一张图吧!(csdn上传图片绝对是垃圾,一张244kb的图片整了半个小时愣是没上传上去!!!)




      在这里,我还学要补充的一点就是SecondaryNameNode节点备份的时机,在run的循环方法中,当满足两种情况中的任意一个,SecondaryNameNode节点都会开始备份,这两种情况是:一.设定的间隔时间到了,这个时间可以通过配置文件中fs.checkpoint.period项来设置;二.操作日志文件的大小达到了checkpointSize,这个值也可以通过配置文件中fs.checkpoint.size项来设置(需要远程调用getEditLogSize()方法)SecondaryNameNode节点执行checkpoing的核心代码如下:

  /**
   * 对主节点上的元数据做一次checkpoint
   */
  void doCheckpoint() throws IOException {

    // Do the required initialization of the merge work area.
    startCheckpoint();

    //通知主节点将操作日志切换到edits.new,并获取一张签证,它表示了当前元数据的状态
    CheckpointSignature sig = (CheckpointSignature)namenode.rollEditLog();

    // error simulation code for junit test
    if (ErrorSimulator.getErrorSimulation(0)) {
      throw new IOException("Simulating error0 " +
                            "after creating edits.new");
    }

    downloadCheckpointFiles(sig);   //从主节点下载此次checkpoint时的元数据及操作日志
    doMerge(sig);                   //合并元数据及操作日志
  
    //
    // Upload the new image into the NameNode. Then tell the Namenode
    // to make this new uploaded image as the most current image.
    //
    putFSImage(sig);

    // error simulation code for junit test
    if (ErrorSimulator.getErrorSimulation(1)) {
      throw new IOException("Simulating error1 " +
                            "after uploading new image to NameNode");
    }

    //current/edits.new------->/current/edits
    //current/fsimage.ckpt------->/current/fsimage
    namenode.rollFsImage();
    
    //
    checkpointImage.endCheckpoint();

    LOG.info("Checkpoint done. New Image Size: "
              + checkpointImage.getFsImageName().length());
  }

  为了保证在checkpoint过程中异常恢复及一致性,NameNode节点维护了一个对应的状态机:

HDFS中的SecondaryNameNode节点解析_第1张图片

    





你可能感兴趣的:(HDFS源码解析)