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