检查点:fsimage总是从namenode复制

时间:2013-07-04 18:38:41

标签: hadoop hdfs

在检查点中,权威指南说

1. The secondary asks the primary to roll its edits file, so new edits goes to a new file
2. The secondary retrieves fsimage and edits from primary (using HTTP GET)

在检查点结束时,辅助名称节点将更新的fsimage发送到namenode。

现在辅助namenode有最新的fsimage,在下一个checkpointing中,secondary namenode会再次从namenode复制fsimage吗?若有,为什么?不能简单地使用校验和比较两个

1 个答案:

答案 0 :(得分:2)

是的,当namenode中的编辑文件大小增长到特定大小时(默认值:fs.checkpoint.size = 4194304),辅助名称将从namenode服务器复制fsimage和编辑文件。

SecondaryNameNode.java中的此代码解释了 -

        long size = namenode.getEditLogSize();
        if (size >= checkpointSize || 
            now >= lastCheckpointTime + 1000 * checkpointPeriod) {
          doCheckpoint();
          lastCheckpointTime = now;
        }

请检查何时调用doCheckpoint();

答案为什么,在设计Hadoop之后(我不知道为什么遵循这个设计) - 看下面的代码正在做什么 (我只保留与此问题相关的陈述)。您可以看到如何调用函数 downloadCheckpointFiles(sig) doMerge(sig)

/**
   * Create a new checkpoint
   */
  void doCheckpoint() throws IOException {

    //---other code skipped---

    // Tell the namenode to start logging transactions in a new edit file
    // Retuns a token that would be used to upload the merged image.
    CheckpointSignature sig = (CheckpointSignature)namenode.rollEditLog();


    downloadCheckpointFiles(sig);   // Fetch fsimage and edits
    doMerge(sig);                   // Do the merge

    //
    // Upload the new image into the NameNode. Then tell the Namenode
    // to make this new uploaded image as the most current image.
    //
    putFSImage(sig);


    namenode.rollFsImage();
    checkpointImage.endCheckpoint();

     //----other code skipped----
  }

然后downloadCheckpointFiles(sig);如何从上方doCheckpoint()内调用。 请参阅下面的代码 -

/**
       * Download <code>fsimage</code> and <code>edits</code>
       * files from the name-node.
       * @throws IOException
       */
      private void downloadCheckpointFiles(final CheckpointSignature sig
                                          ) throws IOException {
        try {
          UserGroupInformation.getCurrentUser().doAs(new PrivilegedExceptionAction<Void>() {

            @Override
            public Void run() throws Exception {


              // get fsimage
              String fileid = "getimage=1";
              File[] srcNames = checkpointImage.getImageFiles();
              assert srcNames.length > 0 : "No checkpoint targets.";
              TransferFsImage.getFileClient(fsName, fileid, srcNames);
              LOG.info("Downloaded file " + srcNames[0].getName() + " size " +
                       srcNames[0].length() + " bytes.");

              // get edits file
              fileid = "getedit=1";
              srcNames = checkpointImage.getEditsFiles();
              assert srcNames.length > 0 : "No checkpoint targets.";
              TransferFsImage.getFileClient(fsName, fileid, srcNames);
              LOG.info("Downloaded file " + srcNames[0].getName() + " size " +
                  srcNames[0].length() + " bytes.");

              checkpointImage.checkpointUploadDone();
              return null;
            }
          });
        } catch (InterruptedException e) {
          throw new RuntimeException(e);
        }

      }

而且,对于你的第三个问题 - “不能简单地用校验和比较两个” -

一个可能的原因是他们不想承担任何风险,因为两个不同文件的校验和有时可能相同。在Namenode中你有一个fsImage,它与secondarynamenode中的不同,但它们的校验和在某种程度上变得相同。这可能发生在你可能永远都不会知道复制似乎是他们确保副本相同的最佳选择。

希望这有帮助。