1

在检查点中,权威指南说

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)

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

现在辅助namenode有最新的fsimage,在下一个检查点将辅助namenode再次从namenode复制fsimage?如果是为什么?它不能简单地使用校验和比较两个吗

4

1 回答 1

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 中的不同,但它们的校验和不知何故变得相同。这可能会发生,你可能永远不会知道。复制似乎是他们确保副本相同的最佳选择。

希望这可以帮助。

于 2013-07-04T19:37:22.823 回答