Hadoop 에서 Secondary Namenode 의 역활

Hadoop 에는 NameNode 와 Secondary NameNode 라는 게 있습니다. 일반적인 생각은 아 Master NameNode 가 죽으면, Secondary NameNode 가 Active-Standby 형태로 동작하지 않을까? 라고 희망을 가지게 됩니다. 하지만, 현재까지의 Hadoop 에서는 그런 멋진 기능은 제공하지 않습니다.(facebook 에서 avatar node 라고 해서 이런걸 제공할려고 하고 있습니다.)

그럼, Secondary Namenode 는 무슨 역할을 하는가? 라는 의문이 생기게 됩니다. 정확하게 얘기를 하자면 SNN의 역할은 백업 용도입니다. 하지만, Master Namenode 즉 NN의 운영에 도움을 줍니다. 라고 말할 수 있습니다.

SNN이 fsimage 와 edits.new 를 일정시간 마다 merge 하고 이를 다시 NN에게 전달하기 때문입니다. 여기서 fsimage 는 NN의 메모리 상태를 가지고 있는 파일입니다. edits.new는 변경 사항을 가지고 있는 log 파일이라고 보면 될듯 합니다. 이때 SNN이 fsimage와 edits.new를 병합해서 NN으로 던져주지 않으면, NN에 계속 edits.new가 커지게 되어서, 결국 edits.new가 메모리 사이즈 보다 커지게 되면, 재시작시에 문제가 발생할 수 있습니다.

http://www.jaso.co.kr/279 를 보시면 이에 대한 내용이 잘 나와있습니다. ^^

간단하게 소스를 따라가자면
src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java

를 보면 doWork 라는 함수가 있습니다. doWork 에서 doCheckpoint() 를 호출하게 됩니다.

  public void doWork() {

    //
    // Poll the Namenode (once every 5 minutes) to find the size of the
    // pending edit log.
    //
    long period = 5 * 60;              // 5 minutes
    if (checkpointPeriod = checkpointSize ||
            now >= lastCheckpointTime + 1000 * checkpointPeriod) {
          doCheckpoint();
          lastCheckpointTime = now;
        }
      } catch (IOException e) {
        LOG.error("Exception in doCheckpoint: ");
        LOG.error(StringUtils.stringifyException(e));
        e.printStackTrace();
        checkpointImage.getStorage().imageDigest = null;
      } catch (Throwable e) {
        LOG.error("Throwable Exception in doCheckpoint: ");
        LOG.error(StringUtils.stringifyException(e));
        e.printStackTrace();
        Runtime.getRuntime().exit(-1);
      }
    }
  }

여기서 다시 namenode.rollFsImage(sig)로 호출하게 됩니다.

  boolean doCheckpoint() throws IOException {

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

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

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

    boolean loadImage = downloadCheckpointFiles(sig);   // Fetch fsimage and edits
    doMerge(sig, loadImage);                   // 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);

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

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

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

    return loadImage;
  }

중요한 의문중에 하나는 SNN이 merge 해서 NN에 sync 하게 되면 NN이 다시 이를 재로딩 하는가? 였는데, 그러지는 않고, 그냥 백업 용도로만 저장이 되니다. hadoop 이 내려갔다가 다시 올라올 때, 이 fsimage 와 edits.new 를 다시 병합해서 메모리에 적재하게 됩니다.

관련해서 인터넷 검색에서 좋은 이미지가 나와서 링크합니다. 출처는 여기입니다.
http://datasearch.ruc.edu.cn/~boliangfeng/blog/?p=551

제가 까먹을까 봐서 정리했고 많은 도움 주신 클라우드 컴퓨팅 구현 기술 그룹분들께 감사드립니다. cloudtech@groups.facebook.com