[입 개발] hadoop fs -tail [-f] URI 의 구현에 대해서

가끔씩 보면 tail -f 는 어떻게 동작할지에 대해서 궁금할때가 생깁니다. 얘가 무슨 수로… 뒤에를 계속 읽어올까?
OS에서 제공하는 notify 관련 함수를 이용할까? 등의 별별 생각을 해보지만… 사실 백가지 생각이 불여일견입니다.

hadoop cmd 는 각각의 command 클래스를 이용하는 CommandPattern 형태로 되어있습니다. 그러나 여기서 관심있는 것은 오직 tail 뿐… 그런데, 너무나 간단하게 Tail 소스만 까면… 끝납니다.

1. -f 옵션이 붙으면, 무한루프를 돈다.(파일 사이즈를 계산해서 offset 보다 적으면 종료)
2. 한번 looping 후에 followDelay 만큼 sleep 한다.
3. 기본적으로 현재 파일 사이즈의 끝 – 1024 만큼의 offset 부터 읽는다.
4. 한번에 읽어들이는 내용은 conf 에 정의되어 있다.(여기서 사이즈가 1024보다 적으면… 음… 맨 뒤가 아닐수도 있는데, 이부분은 뭔가 최저값이 셋팅되지 않을까?)

class Tail extends FsCommand {
  public static void registerCommands(CommandFactory factory) {
    factory.addClass(Tail.class, "-tail");
  }
..
  public static final String NAME = "tail";
  public static final String USAGE = "[-f] <file>";
  public static final String DESCRIPTION =
    "Show the last 1KB of the file.\n" +
    "\t\tThe -f option shows appended data as the file grows.\n";

  private long startingOffset = -1024;
  private boolean follow = false;
  private long followDelay = 5000; // milliseconds

  @Override
  protected void processOptions(LinkedList<String> args) throws IOException {
    CommandFormat cf = new CommandFormat(1, 1, "f");
    cf.parse(args);
    follow = cf.getOpt("f");
  }
  // TODO: HADOOP-7234 will add glob support; for now, be backwards compat
  @Override
  protected List<PathData> expandArgument(String arg) throws IOException {
    List<PathData> items = new LinkedList<PathData>();
    items.add(new PathData(arg, getConf()));
    return items;
  }

  @Override
  protected void processPath(PathData item) throws IOException {
    if (item.stat.isDirectory()) {
      throw new PathIsDirectoryException(item.toString());
    }

    long offset = dumpFromOffset(item, startingOffset);
    while (follow) {
      try {
        Thread.sleep(followDelay);
      } catch (InterruptedException e) {
        break;
      }
      offset = dumpFromOffset(item, offset);
    }
  }

  private long dumpFromOffset(PathData item, long offset) throws IOException {
    long fileSize = item.refreshStatus().getLen();
    if (offset > fileSize) return fileSize;
    // treat a negative offset as relative to end of the file, floor of 0
    if (offset < 0) {
      offset = Math.max(fileSize + offset, 0);
    }
....
    FSDataInputStream in = item.fs.open(item.path);
    try {
      in.seek(offset);
      // use conf so the system configured io block size is used
      IOUtils.copyBytes(in, System.out, getConf(), false);
      offset = in.getPos();
    } finally {
      in.close();
    }
    return offset;
  }
}

[발 번역] Quorum-based Journaling in CDH4.1

해당 글은 Cloudera의  http://blog.cloudera.com/blog/2012/10/quorum-based-journaling-in-cdh4-1/ 를 발번역 한 것입니다. 기존의 HDFS HA를 위해서 사용하던 NFS를 이용한 방법에 Cloudera에서 의문을 품고, 이를 JournalingNode를 이용한 방법으로 개선을 시도했습니다. 왜, 이런 작업을 했고, 어떤 효과가 있을지에 대해서 알아보도록 하겠습니다.

모 고수님들의 이야기를 들어보면, JournalingNode 가 도입되도, 대용량 파일을 올리는 경우가 대부분이므로 크게 성능에는 문제가 없을꺼라고 하시고, 실제로 소규모에서 돌려부신 분의 얘기도, MR(task)에서 MR I/O가 많을 때 부하가 조금 발생하고,  파일 저장시에는 큰 문제가 없다고 하시네요. 다만, 실험군에 따라서 다를테니, 꼭 테스트 해보시고 적용해보시기 바랍니다.(참고로 이 글 보다 중간에 링크된 디자인 문서를 이해하시는게 훨씬 중요합니다.)

 

Quorum-based Journaling in CDH4.1

몇 주전에, Cloudera 에서는 Apache Hadoop을 포함한 클라우데라의 최신 배포판인, CDH4.1 을 출시했습니다. 이 것은 HDFS NameNode의 HA 를 위한 외부 소프트웨어나 특별한 장치에 의존하지 않는 첫번째 Standalone 버전의 출시입니다.( 역자 주: 이전에는 NFS Shared 장치가 HA를 위해서 필요했습니다. ), 이번 글은 개발자 관점에서 해당 새 기능의 내부 동작을 설명합니다. 만약, 해당 기능의 운영과 설정에 대한 정보가 필요하다면 CDH4 High Availability Guide 를 참고하시기 바랍니다.

Background

HDFS 프로젝트가 시작된 이래로, HDFS는 아주 간단한 아키텍처를 유지해왔습니다. 파일시스템 메타데이터를 저장하는 NameNode라고 불리는 마스터 데몬과, 파일시스템 데이터를 저장하는 DataNode라고 불리는 슬레이브 데몬이 있습니다. NameNode는 매우 안정적이고 효율적이며, 간단한 아키텍처는 HDFS가 중요한 서비스 데이터를 수천대의 서버에서 수년 동안 페타 바이트까지 저장하도록 해줍니다. 그러나, 그 동안 NameNode는 HDFS의 SPOF 입니다. 2월에 있었던 CDH4의 첫번째 베타 릴리즈 이후로, 백업 기능을 제공하는 자동 hot failover를 제공하는 Standby NameNode를 소개했었습니다. HA NameNode  디자인에 대한 자세한 토론은 동료인 Aron Myers의 이전 글을 참고 하시기 바랍니다.

Limitations of NameNode HA in Previous Versions

3월에 올렸던 블로그에서 설명한 것처럼, NameNode HA는 특별한 공유 스토리지에 의존합니다. Active NameNode에서 HDFS edit log 쓰고, 동시에 Standby NameNode에서 해당 edit log를 읽어갈 수 있는 를 저장 공간이 필요합니다. 게다가, 이 공유 스토리지는 그 자체로 HA해야 합니다. 공유 스토리지에 접근이 되지 않으면, Active NameNode는 더 이상 namespace의 변경 사항 저장을 계속할 수 없을 것입니다.

CDH4.1 의 HDFS에서는 NFS mount 형태로 제공되는 공유 스토리지가 필요했습니다. 일반적으로 Enterprise 등급의 NAS 장비입니다.(역자주: 이 Enterprise 등급의 NAS는 자체적인 HA를 제공해주지만, 가격은 후덜덜합니다.) 몇몇 조직에서는 이런 구조가 그들의 운영 환경에 적합하고, 실제로 실 서비스 환경에서 HA NameNode를 운영중인 몇몇 고객이 있습니다. 그러나, 다른 고객들과 커뮤니티 멤버들은 NFS 에 기반한 스토리지에서 다음과 같은 제약 사항을 발견했습니다.

  • Custom hardware – NAS 장비를 사용하면, 매우 비싸질 수 있습니다. 게다가, fencing 설정을 위해서 원격 설정가능한 파워 분배 장치(PDU) 나 다른 특별한 장치가 필요할 것입니다. 추가적인 장비 비용이 필요하고, 운영 비용도 들 것입니다. 많은 조직이 데이터센터내에 NAS 장비나 다른 특별한 하드웨어를 추가하지 않기를 원합니다.(역자 주: fencing이라는 것은 현재 동작중인 클러스터에서 특정 멤버를 클러스터에서 제거하는 것을 말합니다.)
  • Complex deployment – HDFS가 설치된 이후에도, 관리자는 NFS를 마운트하고, 해당장비에 맞는 fencing 스크립트를 설정하고, 그외의 여러 작업을 수행해야 합니다. 이것은 HA 배포를 어렵게 하고 때로는 잘못설정해서 이용할 수 없는 경우도 생깁니다.
  • Poor NFS client implementations – 많은 Linux 버전에서 NFS client를 구현은 버그도 많고, 설정하기 어렵습니다. 예를 들어, 관리자가 mount 옵션을 잘못 설정하기 쉽고, 이렇게 되면 NameNode는 장애 시나리오에서 복구가 되지 않을 것입니다.
  • External dependencies – 스토리지를 위해서 NAS 장비에 대한 의존은 하나 이상의 인프라스트럭처에 대해서 모니터링과 유지보수를 필요로 합니다. 최소한, NAS를 사용하는 것은 추가적인 경고나 모니터링 수치를 설정해야 하고, 몇몇 조직에서는 하둡 운영 조직이외에도 다른 스토리지 관련 직에 대한 내부 의존성이 생깁니다.(역자 주: 예를 들어서, NAS를 관리하는 조직이 따로 있다면, 해당 하둡 운영팀에서 NAS 문제가 발생했을 때는 어떻게 손을 쓸 수 가 없습니다.)

Removing These Limitations

위의 제약사항으로 부터, 여러가지 옵션을 평가하고, 실제 가능한 교체를 위해서 다음과 같은 요구사항 리스트를 만들었습니다.

  • No requirement for special hardware – 하둡과 마찬가지로, 오직 Commodity 하드웨어에만 의존해야 합니다. 특히, 실제 장비들은 현재 클러스터의 일부분이어야 합니다.
  • No requirement for custom fencing configuration -STONITH 와 같은 fencing 방법은 특별한 장비를 필요로 합니다. 오직 소프트웨어적인 방법에만 의존해야 합니다.
  • No SPOFs – 최종 목표가 HA이기 때문에, 다른 컴포넌트에 HA 요구사항을 집어넣고 싶지 않습니다.
 SPOF와 특별한 하드웨어를 피하겠다는 주어진 요구사항으로 인해서, 어떤 디자인이라도 여러대의 commodity 장비 위에 여러개의 replica 를 저장하는 방식을 사용해야 한다는 것을 알게 되었습니다. 여기다가 다음과 같은 요구사항이 추가되었습니다.
  • Configurable for any number of failures – 한 종류의 장애에 대해서만 견고한 시스템을 디자인하는 것 보다는, 메타데이터를 복제하는 추가 노드를 이용해서, 요구하는 복구 레벨에 따라서 처리할 수 있도록 유연성이 필요합니다.
  • One slow replica should not affect latency – 메타데이터의 Write Path는 NameNode의 성능을 결정하는 중요한 컴포넌트이기 때문에, latency가 낮게 유지된다는 것에 대한 확신이 필요했습니다. 여러개의 리플리카를 가지고 있다면, 그 중의 하나가 장애가 나거나 느리더라도 시스템의 latency에는 영향을 주지 않는다는 확신이 필요합니다..
  • Adding journal replicas should not negatively impact latency – 만약 관리자가 여러 장애가 동시에 일어나는 것에 대비하기 위해서 추가적인 리플리카를 설정하는 것을 허용한다면, 이것이 성능에 부정적인 영향을 미쳐서는 안됩니다.
 하둡을 좀 더 쉽게 배포하고, 운영할 수 있는데 초점을 맞추고 있는 회사로써, 다음과 같은 운영측면의 요구사항도 고려해야 했습니다.

  • Consistency with other Hadoop components– 새롭게 소개되는 모든 컴포넌트는 기존에 존재하던 것들과 유사한 동작을 하도록 디자인되어야 했습니다. 예를 들어, XML 기반의 config을 사용하고 log4j를 logging에 사용하고, 같은 metric framework를 사용하는 것입니다.
  • Operations-focused metrics – NameNode 운영의 중요한 부분이기 때문에, metrics를 보여주는 것에 높은 우선순위를 두었습니다. 새로운 시스템은 오래 동작하는 실 클러스터로 동작한다면, 모든 중요한 metric를 보여주는 것과 실제로 이용할 수 없는 어떤 문제에 대해서도 일찍 경고를 주는 것이 필요했습니다.
  • Security – CDH는 데이터에 대한 암호화와 Kerberos를 통한 강한 인증 기능등의 종합적인 보안을 제공합니다. 모든 새로운 컴포넌트는 스택의 나머지 부분과 같은 수준을 유지하도록 디자인되었습니다. 암호화가 필요한 고객에게, 데이터를 암호화하는 것 만큼 메타데이터를 암호화 하는 것도 중요합니다.

QuorumJournalManager

클라우데라에서의  고객들과 커뮤니티와의 내부적인 토론 후에, QuorumJournalManager 라고 불리는 시스템을 디자인했습니다. 이 시스템은 다음과 같은 간단한 아이디어에 기반합니다. HDFS edit log들을 NFS 같이 한 지점에 저장하는 것보다는 여러 군데에 저장하자는 것입니다. 그리고 분산 프로토콜을 이용해서 여러 곳의 데이터가 올바르게 동기화 되는 것을 보장한다는 것입니다. 해당 시스템에서 원격 저장소는 JournalNode 라고 불리는 새로운 형태의 HDFS 데몬입니다. NameNode는 JournalNode 들에 edit log를 저장하는 클라이언트로써 동작합니다. 그리고 해당 노드들의 과반수가 복제에 성공했을 때 해당 변경 사항을 커밋하게 됩니다.

유사하게 NameNode가 Standby 상태에 있을 때, 네임스페이스에 대한 hot backup을 유지하기 위해서 edits 를 읽을 필요가 있습니다. 이때 JournalNode에 저장된 다른 아무 replica에서 읽을 수 있습니다.

Distributed Commit Protocol

위의 그림은 간단합니다. NameNode는 세 노드 각각에 edits를 저장하고, 과반수가 복제되었을 때, 성공하게 됩니다. 그러나, 다음과 같은 재미있는 질문이 생길 수 있습니다.

  • 만약 edits에 대한 배치작업이 하나의 서버에는 보냈지만, 다른 서버들에 보내지 않았을 때, 그리고 그때 NameNode 가 장애가 나면 어떻게 될까?
  • “Spit Brain” 시나리오에서는 무슨 일이 벌어질까? 양쪽에 모두 쓰려고 할까?
  • 시작시에 불일치로 부터 어떻게 복구하게 될까? edits 가 메모리에 있는 상황에서 몇몇 노드가 장애가 나면 어떻게 될까?

해당 질문들에 대한 자세한 설명은 해당 블로그 글에 담기에는 힘들지만, 짧게 말하자면 해당 시스템은 Paxos라는 잘 알려진 프로토콜의 구현체에 의존하고 있습니다. 해당 프로토콜은 클러스터의 여러개의 노드들끼리 데이터가 일치하다는 것을 확신할 수 있는 정확한 방법을 제공합니다. 이 시스템에서, Mutli-Paxos 의 구현체를 edits 의 각각의 작업을 커밋하기 위해서 사용하고 있습니다. 추가적으로 복구를 위해서 failover 후에 standby NameNode들이 지연된 edit를 지우기 위해서도 사용됩니다. 해당 내용에 대한 자세한 내용과 알고리즘은  HDFS-3077 design documentThe 를 참고하시기 바랍니다.

Fencing and Epoch Numbers

이 글의 앞에서 소개된 시스템의 주요 요구사항 중에 하나는, 특별한 장비나 소프트웨어를 이용한 어떠한 fencing 이든지 회피하는 것입니다. Fencing은 failover 후에 새로운 Active NameNode가 이전 Active 노드가 더 이상 시스템의 메타데이터에 변경을 가하지 않는 것을 확신하는 것입니다. 다른 말로, fencing은 “Split Brain Syndrome”의 치료제입니다. “Split Brain Syndrome”은 두 개의 노드가 Active NameNode라고 생각하고, 네임스페이스에서 서로 다른 변경을 통해 충돌을 만드는 잠재적인 시나리오를 말합니다. 그럼 QuorumJournalManager는 fencing을 어떻게 구현했을까요?

QuorumJournalManager 에서 fencing을 위한 핵심은 Epoch Number 라는 개념입니다. NameNode가 active가 될 때마다, 처음에 Epoch Number를 생성하는 것이 요구됩니다. 이것은 계속 증가하는 정수형태로 할당될 때 마다 유일한 값이 생성됩니다.ㅣ 최초의 Active NameNode는 네임스페이스를 초기화한 다음에 epoch number 1로 시작하게 됩니다. 그리고 failover 나 재시작하게 되면 증가된 epoch number를 가지게 됩니다. 즉, epoch number는 두 개의 NameNode 사이에 순서를 정해주게 됩니다. 더 높은 epoch number를 가진 NameNode가 “더 최신” 이 되고, 다른 NameNode 들은 더 이전 epoch number 값을 가지게 됩니다. NameNode는 epoch number 를 한번 주어진 epoch number를 두 번 이상 만들지 않는, 항상 유일한 값을 만들어내는 간단한 알고리즘을 이용합니다. 해당 알고리즘의 자세한 내용은 위에서 언급한 디자인 문서를 참고하시기 바랍니다.

두 대의 NameNode 가 주어져 있고, 두 대 모두 자기가 Active 라고 생각하는 상황에서, 각각 자신의 유일한 epoch number를 가지고 있을대, 어떻게 Split Brain Syndrome을 회피할 수 있을까요? 그 대답은 놀랍게도 매우 간단합니다. 그리고매우 우아합니다. 하나의 NameNode 가 하나의 JournalNode로 어떠 메시지(또는 RPC 호출할때)를 보낼 때, 요청의 일부로 epoch number가 포함되어 있습니다.  JounalNode 가 해당 메시지를 받으면, 로컬에 저장된 promised epoch 과 epoch number를 비교하게 됩니다. 만약 요청이 더 최신의 epoch number를 가지고 있으면, 새로운 epoch number를 로컬에 promised epoch이라고 불리는 값으로 저장하게 됩니다. 만약 더 이전의 epoch number가 요청에 포함되어 있으면,  해당 요청을 거부하게 됩니다. split-brain을 피하기 위한 간단한 정책은 다음과 같습니다.

  • 어떤 NameNode라고 edits를 성공적으로 쓰기 위해서는 과반수의 노드들이 쓰기에 성공해야 한다. 이것은 과반수 이상의 노드들이 해당 epoch number를 최신이라고 인정해야 한다는 뜻입니다.
  • 새로운 NameNode가 active 가 되었을 때, 이전의 다른 NameNode의 epoch number 보다 더 높아야 합니다. 이것은 JournalNode 의 epoch number를 증가하게 함으로써, 모든 JournalNode를 호출하는 것을 간단하게 만들어줍니다. 이것이 과반수 이상으로 성공하면, 그것은 새로운  epoch 으로 인정받게 됩니다.
  • 두 개 모두 과반수 이상의 노드로 부터 인정받아야 하기 때문에, 이것은 이전 NameNode 가 active 라고 생각함에도 불구하고, 더 이상 과반수로 부터 성공적인 쓰기를 요청할 수 없다는 것을 의미합니다. 그로 인해 네임스페이스 변경이 일어나는 것을 방지합니다.

Testing

Paxos 가 논문에는 간단하고, 정확성을 보장하지만, 올바르게 구현하는 것은 어렵기로 악명높습니다. 그러므로 이 시스템을 개발하는 동안, 절반 이상의 시간을, 테스팅하고 검증하는데 소모했습니다. 특별히 몇 가지 테크닉이 중요하다는 것을 발견했습니다.

  • MiniCluster testing – 초기부터, 같은 JVM위에서 여러 개의 JournalNode를 실행하는MiniJournalcluster 라고 불리는 작은 클래스를 작성했습니다. 이것으로 분산 시나리오에 대한 테스트를 JUnit 기능 테스트 케이스 내에서 자동화 할 수 있었습니다.
  • Mock/spy testing – Mockito를 이용해서 같은 JVM내의 QuorumJournalManager Client 와 JournalNode 에 Spy를 삽입하는 많은 수의 unit tests를 작성했습니다. 예를 들어, MOckito Spy는 매칭되는 특정 구문에서 쉽게 IOException을 던지는 것을 지시할 수 있습니다. 디자인 토론 중에 많은 수의 다른 장애 상황과 시나리오를 확인하는 deterministic tests를 위해서 이것을 사용하였습니다.
  • Randomized fault testing – 여러가지 다른 장애 시나리오를 위해, 손으로 수십가지 테스트를 작성할 수 있었지만, 이 테스트들은 우리가 쉽게 생각할 수 있는 것들로 제한이 됩니다. 분산 시스템을 구축했던 경험에 따르면, 쉽게 인식하지 못하는 경우가 훨씬 더 염려스럽습니다. 그래서 deterministic seeds에 기반한 랜덤 장애 테스트를 도입했습니다. 주어진 랜덤 seed 에 의해서, 완전히 결정된 프로토콜에 따른 일련의 장해를 일으키는 테스트 케이스가 수행됩니다. 예를 들어, 주어진 seed 는 장애를 만들기 위해, 두번째, 세번째, 8번째, 그리고 45번째 RPC 를 NameNode 에서 두번째 JournalNode로 전달합니다. 해당 테스트는 장애가 주입되는 동안에 수백개의 Failover를 시물레이션 하고, 동시에 커밋된 트랜잭션이 사라지지 않았는지 검증합니다.

추가적으로, 위에서 수행되는 테스트들 외에도, MapReduce 클러스터에서 돌아가는 랜덤 장애 테스트 셋도 작성했습니다. 해당 테스트들은 몇분 동안 랜덤 장애 테스트를 수행하는 Hadoop Streaming 작업입니다. 이 때, 결과물은 해당 테스트 로그로 HDFS에 저장됩니다. 입력으로는 random seed를 가지고 있는 5000 줄 짜리 파일이 들어갑니다. NLineInputFormat을 이용해서, 각각의 seed를 개별적인 태스크에 전달합니다. 그 결과, 큰 클러스터에서 동시에 쉽게 5000개의 인스턴스가 수행될 수 있습니다.  해당 잡이 끝나면, 두 번째 스트리밍 잡이 해당 결과에 대해서 테스트 실패나 기대하지 않은 메시지(AssertionError, NullPointerException)들을 찾기 위해 grep을 수행합니다.

해당 테스트 셋을 이용해서, 수백만개의 failover 시나리오를 테스트 할 수 있었고 여러가지 버그를 발견할 수 있엇습니다. 해당 테스트는 사실상 매우 종합적이었고, Hadoop에서 내부적으로 사용하는 Jetty의 새로운 버그 두개를 발견할 수 있었습니다. Jetty의 버그를 수정한 것 역시 CDH4.1 에 추가되었습니다.

Summary

이 글에서 설명한 내용은 CDH4.1 에서 사용이 가능합니다. 그리고 많이 고생한 Cloudera Manager Team 에 CM4.1 에서는 몇번의 마우스 클릭만으로 배포하고 모니터링 하는 것이 매우 쉽습니다. 다른 HDFS 개발 제품처럼, Apache Software Foundation Repositories 에 올라가 있습니다. 그리고 ASF Jira  HDFS-3077 에서 확인할 수 있습니다. 새로운 코드는 Apache trunk에 머지되었고, 가까운 후에 Apache HDFS release에 포함될 것입니다.

Acknowledgements

해당 프로젝트에 공헌한 분들의 호의에 감사합니다.

  • Aaron T. Myers and Eli Collins for code reviews and contributions around security, configuration, and docs
  • Sanjay Radia, Suresh Srinivas, Aaron Myers, Eli Collins, Henry Robinson, Patrick Hunt, Ivan Kelly, Andrew Purtell, Flavio Junqueira, Ben Reed, Nicholas Sze, Bikas Saha, and Chao Shi for design discussions
  • Brandon Li and Hari Mankude for their work on the HDFS-3092 branch which formed some of the early building blocks for the JournalNode
  • Stephen Chu and Andrew Purtell for their help with cluster testing
  • Vinithra Varadharajan, Chris Leroy, and the Cloudera Manager team for help with integration testing, metrics and configuration

[발 번역] HA Namenode for HDFS with Hadoop 1.0 – Part 1

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

해당 글은 http://hortonworks.com/blog/ha-namenode-for-hdfs-with-hadoop-1-0-part-1/ 을 발 번역한 것입니다. 이전까지 하둡의 가장 큰 문제점은 NameNode의 SPOF였습니다. 쉽게 장애가 나지는 않지만, 장애가 나면, 그걸로 복구가 될 때까지는 서비스가 완전히 중단이 되어버리는 문제가 있습니다. 그래서 페이스북의 아바타 노드라든지(이것도 중간의 NFS 계층등에서 문제의 SPOF가 여전히 증가하는…) 이런 이슈들이 있습니다. 사실 Hadoop 1.0에서 추가된 HA라는게 아바타 노드랑 거의 동일한 기능이라 이걸 아시는 분들은 크게 관심을 안가지셔도 될듯 합니다. 그럼 오역에 주의하세요.

HA Namenode for HDFS with Hadoop 1.0 – Part 1

August 28th, 2012

Introduction

HDFS를 위한 HA NameNode 는 작년 부터 개발중이었습니다. 그리고 그 노력은 주로 하둡 2.0의 NameNode의 자동 Failover에 주로 집중되었습니다. 그 기간동안 우리는 두 가지를 깨달았습니다.

첫번째로, HA 문제에 대해서 외부에서 내부로의 접근 방법을 이용할 수 있다는 것입니다. 전체적인 하둡 시스템의 HA 디자인으로 부터 시작하고, 그리고 개별 컴포넌트의 기능에 대해서 집중하는 것입니다. 해당 노력은 Full Stack HA Architecture 로 이어졌습니다.

두번째로, Linux HA 와 vSphere 같은 이미 필드에서 검증된 솔루션을 이용해서 하둡 1.0에 NameNode의 HA를 구축할 수 있다는 것입니다. 이것은 하둡 2에서 HDFS가 겨우 베타 테스트 단계인 것에 비해서 하둡 1의 HDFS는 안정적이고 신뢰할 만하다는 것이 이미 검증되었다는 면에서 중요합니다. 해당 포스트에서는 하둡 1에서의 HDFS NameNode HA 의 몇 가지 기술적인 상세한 부분에 대해서 설명합니다. 차후에는 Full Stack HA 의 좀 더 상세한 부분에 대해서 논의하도록 하겠습니다.

사용자들에게 가장 중요한 질문은 “하둡 1과 하둡 2의 HA 는 무엇이 다른가?” 입니다. 동료 Suresh 와 나는 하둡 2를 위한 기본 디자인을 작성했습니다. 그리고 구현에 대해서 커뮤니티를 통해 가깝게 일했습니다. 하둡 1에서의 HA는 해당 작업 동안의 우리의 경험의 직접적인 결과물입니다.

하둡 2 HA에서는 다음 세 가지에 초점을 맞추고 있습니다.

  • Hot failover: Failover 동안에 몇가지 작은 차이점이 있습니다. 작은 규모와 중간 규모의 클러스터를 위해서 cold 와 hot failover 가 있는데, 하둡 1에서는 cold Failover를 사용합니다.
  • Automatic failover: 하둡 2에서 Failover 컨트롤러를 사용하는 반면에 하둡 1에서는 이미 필드에서 검증된 HA 프레임워크를 이용합니다. 아래 그림에서 설명되듯이, 하둡 1에서의 NameNode HA 는 Linux HA를 사용합니다.
  • Remove dependency on shared storage: 이 부분은 trunk[6]의 Journal 데몬을 위해서 작업 중입니다. 하둡 1과 하둡 2 모두에서 공유 스토리지를 사용합니다.

요약하면, 하둡 1 HA는 cold failover 이고, 표준적인 HA 프레임워크들을 이용합니다. 이 차이점들에 대해서 자세히 살펴보기로 하겠습니다.

Failover Times and Cold versus Hot Failover

Active-Passive failover 형태의 HA 시스템에서의 Failover 동안에는 Active 서비스가 장애라는 것을 발견하는 시간이 들어가고, 리더를 선출하거나, failover를 결정하고 다른 것들과 커뮤니케이션 하는 시간도 들어가며, 대기중인 서비스를 active로 변환하는 시간도 필요합니다.

첫번째나, 두번째 항목은 cold나 hot failover 에서 공통적으로 필요합니다. 둘 다 heartbeat 타임아웃에 의존해서, 타임아웃을 모니터링 하거나등의 방법을 이용합니다. 장애 감지를 위한 시간과 장애의 종류에 따라서 Active 서버나 서버의 운영체제에 장애가 있을 때 일반적으로 30초 부터 2.5분 까지 다양한 리더 선출 과정 시간을 관찰했습니다.  행이 걸린 프로세스는 가비지 콜렉션에 의해서 블록된 것이 아닌지에 대한 확인할 수 있는 시간이 필요하므로 더욱 더 시간이 걸립니다.

세번째 항목의 경우, standby 에서 active 로 넘어가는 시간은 하둡 1에서는 세컨드 NameNode를 실행하고 NameNode가 safe mode에서 빠져나오는데 걸리는 시간입니다. 경험상 다음과 같은 시간이 걸렸습니다.

  • 300TB의 스토리지를 사용하고 6백만 개의 블럭을 가지고 십만개의 파일을 가지는 60개의 노드로 구성된 클러스터에서 30초가 걸렸습니다. 그리고 총 Failover 시간은 1~3분 정도 걸렸습니다.
  • 2천만개의 블러과 1PB의 스토리지 백만개의 파일을 가진 200 노드로 구성된 클러스터에서는 110초가 걸렸습니다. 그래서 총 Failover 시간은 4.5분 정도 였습니다.

Industry Standard HA Frameworks

하둡 HDFS NameNode HA 디자인 문서에서 얘기했듯이,  NameNode 외부에 Failover 컨트롤러를 가진다는 아이디어는Linux HA[1] 와 RedHat HA[2], 그리고 Veritas Cluster[4,5] 등의 프레임워크 같은 것들로 부터 영향을 받았습니다. 하둡 커뮤니티의 결정의 일부로, 하둡 외부에서 솔루션 형태로 제공하는 것이 유용하다고 느껴기 때문에 자체 Failover 컨트롤러를 만들기로 했습니다. Linux HA는 GPL이 되어야 했기 때문에, 사용할 수 없었습니다.

하둡 1에는 trunk 로 부터 failover 컨트롤러를 백포트 하지 않기로 결정했습니다. 대신에 필드에서 표준적인 솔루션을 쓰기로 했습니다. 왜일까요?

가능한한 위험이 없는 방식으로 현재 안정적인 하둡에 HA를 추가하길 바랬기 때문에, 모니터링 타임아웃, 서비스 시작 타임아웃, 종료 타임 아웃, 반복되는 장애를 다루는 검증되고 안전한 방식을 사용했습니다. 전원 관련 솔루션을 포함해서 여러가지 대안 솔루션을 제공했습니다.

이 같은 프레임워크는 Job-Tracker 같은 다른 하둡 서비스의 Failover에도 사용될 수 있습니다. 이미 HA Job-Tracker 를 만드는 작업을 시작했고, HA NameNode 를 위한 장비들을 위한 공통 pool로 공유될 수 있는 기능을 제공했습니다. JobTracker 와 다른 마스터 데몬들은 N-N, N-on-N, N+K Failover를 허용합니다. 최종적으로 수동으로 전환할 수 있는 기능을 제공했고, NameNode 중에 하나가 다운되거나 정지하도록 조정가능합니다.

많은 고객들은 이미 이런 HA 프레임워크를 경험했습니다. Namenode IP 주소를 일정하게 유지하는 Failover 솔루션을 이용해서 사용자와 webHDFS를 통해 어플리케이션도 웹 인터페이스를 통해서 Failover 를 보장합니다. 서비스가 어디서 동작하는지에 상관없이 URL은 서비스에게 맞게 적용될 것입니다. 성숙한 IP failover 기반 솔루션을 사용하는 것은 Failover 솔루션의 복잡도를 줄여주고, 하둡 Core에 적은 수정과 위험만을 가지고 안정적인 하둡 1.0에 HA를 구현하는 것을 가능하게 만들어주었습니다.

최근에, Symantec 에서 독립적으로 Veritas Cluster[5]를 이용해서 NameNode를 어떻게 HA 하도록 만들 것인가에 대해서 발표했습니다. 위에서 하둡 1에서의 LinuxHA를 이용한 NameNode HA를 설명했고 vSphere HA를 이용한 유사한 솔루션이 사용가능할 것입니다.

FAQ

    • cold failover만 이용하므로 실용적이지 못해요.

HDFS 2.0 HA 디자인은 야후나 페이스북등의 매우 큰 클러스터의 필요성에 의해서 나오게 되었습니다. 중소규모의 클러스터의 경우 cold failover는 위에서 얘기한 것과 같이 30에서 120초 가량 느립니다.

    • Linux HA를 이용해서 Failover 하는 것이 그렇게 쉽다면, 왜  HDFS 커뮤니티는 좀 더일찍 Linux HA나 다른 툴을 이용해서 Failover 작업을 하지 않았나요?

이것은 원래 HDFS 팀에서 cold failover 가 실용적이지 못한 매우 큰 규모의 클러스터에만 집중해서 그렇습니다. 하둡에 자체적인 솔루션이 있어야 한다고 생각했고, 해당 기술만 개발 하였습니다.  그러나, 고객들은 직접적으로 HA 솔루션은 복잡하고, 고객들은 이미 존재하고 잘 이해할 수 있는 솔루션을 선호한다고 말해주었습니다.

    • 하둡 2의 HA에서는 다른 방법을 사용하지 않나요?

사실이 아닙니다. 둘 다 같은 디자인 원칙에 기반하고 있습니다. 단지 차이는 warm failover 대신에 cold failover에 초점을 맞찬다는 것 뿐입니다. 게다가, 해당 작업은 무료입니다. 하둡 1.0 코드의 모든 작업은 하둡 2.0 코드에 역시 반영되었습니다.

    • Linux HA 나 다른 프레임워크를 사용해보고 싶은데, 그거 어려운가요?

대다수의 하둡 상요자들은 이미 Linux HA, RedHat HA, Veritas Cluster 나 vSphere HA등의 솔루션을 그 들의 데이터 센터 안에서 사용하고 있습니다. Linux HA는 공짜로 이용가능하고, RedHat의 HA 솔루션은 가격이 쌉니다.

    • Full Stack HA는 오직 하둡 1의 일부분인건가요?

아닙니다. Full Stack HA는 NameNode나 JobTracker(this post) 등의 특정 컴포넌트의 Failover를 지원하기 위한 것입니다. Stack의 나머지 부분을 일시적인 장애에 안정적으로 만드는 것은 Stack 전체를 발전시킵니다. 다음번 포스트에서 Full Stack HA에 대해서 더욱 상세하게 다루도록 하겠습니다.

    • vSphere HA는 서비스 장애가 아닌 VM 장애를 다루기 위한 것 아닌가요?

vSphere는 어플리케이션 레벨의 헬쓰 체크도 지원합니다. NameNode를 위한 어플리케이션 레벨의 모니터를 추가하면 됩니다. 비슷하게 JobTracker 를 위한 모니터도 금방 이용할 수 있을 것입니다.

    •  NameNode 와 Job Tracker를 vSphere VM 에서 사용하는 것은 성능이나 확장에 제한을 주지 않나요?

소규모 클러스터에서, vSphere VM 에 마스터 서비스를 운영하는 것은 매우 효율적인 디자인입니다. vSphere 는 각각의 VM을 독립적으로 모니터링 하고 관리하기 때문에, vSphere 서버는 NameNode, JobTacker 다른 마스터 서비스들을 독립적으로 운영할 수 있습니다. 만약 하나의 서비스가 장애가 나면, 다른 VM들이 중단되지 않고 진행되는 동안에, 장애난 VM만 종료되고 재시작됩니다. VM이 제공하는 롤백과 유지의 편이성을 얻을 수 있습니다.

Status

모든 패치가 Apache Hadoop trunk 와 1.1 브랜치의 core hadoop에 적용되었고, Hortonworks HDP 1과 HDP 1.1에도 포함되어 있습니다. 이것들은 Hadoop 2-alpha에도 적용될 계획입니다.

모니터링 코드는 아직 인큐베이팅 중인 Ambari project 에 포함되는 것을 목표로 하고 있고, 패치[8] 는 이미 제출되었습니다.

vSphere 와 RedHat HA 에서 하둡 1 설정을 위한 문서는 웹사이트에서 이용가능합니다.

Future Outlook

현재 베타 테스팅에 들어가 있고, 하둡 2의 HA(Hot Failover, failover controller 등등) 에 들어갈 HDFS2 를 안정화하기 위한 작업은 계속 진행중입니다. 다른 하둡 컴포넌트에 Failover를 제공하기 위한 노력도 계속 진행중입니다.(예를 들어, 하둡 1의 JobTracker)

마지막으로, 잘 관리되는 하둡 클러스터에서는 어떤 종류의 마스터 장애라도 잘 발생하지 않는 다는 것을 기억해둘만한 가치가 있습니다. 정기적인 시스템 유지보수는 클러스터를 안정적으로 컨트롤 할 수 있는 방법이기 때문에, 정기적으로 클러스터를 오프라인으로 만들어서 점검하고 있습니다.

References

[발 번역] 하둡 파일 시스템(HDFS)를 위한 고가용성

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

해당 글은 Cloudea의 http://www.cloudera.com/blog/2012/03/high-availability-for-the-hadoop-distributed-file-system-hdfs/ 라는 글을 발 번역 한 것입니다. 다들 아시는 것 처럼 HDFS의 주요 문제점 중 하나는 Master Node의 SPOF(Single Point of Failure) 입니다. 이를 위한 페이스북 등에서 나온 것이 Avatar Node 라고 해서 실제 중요 데이터를 NFS 등의 공유 데이터 스토어에 저장해두고, 장애시 Standby Master Node를 이용해서 복구하자는 것입니다. 복구가 될 때 실제 블럭 리포트를 재구성 하는데 시간이 많이 걸리는데, 이를 Active와 Standby에 모두 보내서 실제로 장애시에 빠른 시간내에 서비스를 할 수 있도록 하는 것이 Avatar Node의 요지입니다. 다만, 페이스북의 경우 장애시 실제로 자동 복구는 하지 않고, 사람의 힘을 빌려서 판단한다고 하네요. ( 그리고 hadoop 2.0으로 넘어가면서 실제로 여러 마스터 노드에서 파일들을 나눠서 관리하고 이를 클라이언트 라이브러리에서 판단해서 하나나 전체의 파일을 가져가는 형태로 바뀌었습니다. 이 형태의 경우, Master Node의 장애가 있더라도 피해를 일부 지역으로 국소화 시킬 수 있습니다. 이 부분에 대한 내용은 해당 포스트에는 없고,  Avatar 노드에 대한 것뿐이긴 합니다. ) 이런 큰 방향으로 바뀌는 것들에 대한 설명이 있으니, 주의 깊게 보시면 됩니다. 오역에 주의하시기 바랍니다.

Background

아파치 하둡은 큰 두 개의 컴포넌트 HDFS와 MapReduce로 구성되어 있습니다. 하둡 분산 파일 시스템 HDFS는 하둡의 메인 스토리지 시스템입니다. 그리고 하둡에 저장되는 모든 파일을 서비스하고 저장하는 책임이 있습니다. MapReduce는 HDFS 에 저장된 데이터를 이용하도록 디자인된 분산 처리 프레임워크입니다.

HDFS는 강한 신뢰성을 가지는 파일 시스템으로 오랬동안 고려되어 왔습니다. 야후에 경험에 근거한 연구에 따르면, 야후에서는 2009년에 10개의 다른 클러스터에서 20,000대의 노드에서 아파치 하둡을 운영했습니다. HDFS는 오직 3억2천9백만개의 데이터 블럭 중에서 오직 650개의 블럭만 유실되었습니다. 유실된 블럭의 대부분은 버그에 의해서 발생했고, 해당 버그들은 오래전에 이미 수정되었습니다.

이정도로 높은 안정성 레벨에 비해서, HDFS는 예전부터 잘 알려진 HDFS의 가용성에 큰 영향을 주는 큰 단점(SPOF: Single Point of Failure) 을 가지고 있습니다. HDFS는 하나의 싱글 Name Node가 파일 시스템에 접근하는 것을 관리합니다. 대부분 ETL이나 batch 처리 workflow 로 사용되는 클러스터의 경우 HDFS의 약간의 중단은 즉각 회사에 큰 비지니스적 영향을 주지는 않습니다. 하지만, HDFS는 과거 몇년 동안 좀 더 상호작용적인 업무에 사용되기 시작하기 시작했고, HBase의 경우에는 실시간에 고객의 요구를 처리하고 있습니다. 이런 경우에, HDFS의 중단은 내부 유저의 생산성에 바로 영향을 주게됩니다. 그리고 외부 사용자에게도 영향이 미칠것입니다. 이런 이유로, HDFS Name Node에 고가용성(HA)을 추가하는 것은 HDFS 커뮤니티에서 제일 중요한 작업 중의 하나가 되었습니다.

해당 포스트에서는 “HA Name Node”라고 불리는 HDFS의 새로운 기능 구현에 대해서 얘기합니다. 하둡 전체의 가용성에 대해서 연관된 다른 이슈들에 대해서 자세히 얘기하고 싶다면, Eli Collins의 멋진 블로그 포스트를 살펴보시기 바랍니다.

High-level Architecture

HA Name Node 프로젝트의 목표는 Active/Passive 설정으로 두 대의 NameNode 를 배포하는 것을 추가하는 것입니다. 이것은 고가용성 분산 시스템에서 일반적인 설정입니다. 그리고 HDFS의 아키텍트는 이렇게 하기에 잘 디자인되어 있습니다. HA 설정이 아니더라도, HDFS는 이미 Name Node의 동작을 체크하는 비슷한 스펙의 다른 노드를 필요로 합니다. HA Name Node의 디자인은 그 체크하는 역할을 passive Name Node에 부여해서 HDFS에서 이미 필요로 하는 것들을 넘어서 다른 추가적인 하둡 서버 장비가 필요없도록 해야 합니다.(역자 주: 기존 시스템에서는 Secondary Namenode 또는 backup node라는 이름으로 HDFS의 NameNode의 메타정보를 백업해주는 프로세스들이 있습니다. 이것만으로는 SPOF를 피할 수 없기 때문에, 결국 한 쌍의 하둡 클러스터를 더 만들어서 트래픽을 같이 보내서 HA를 보장하는 방법을 이용하곤 했습니다.)

Hadoop Distributed File System High Available Name Node

HDFS Name Node는 두 종류의 파일시스템 메타데이터를 서비스 하는 주된 책임이 있습니다. 파일시스템의 네임스페이스와 블록 위치 정보입니다. HDFS의 아키텍처 때문에, 이것들은 개별적으로 처리되어야 합니다.

Namespace Information

파일 시스템 네임스페이스에 생기는 파일 이름 변경, 소유권한 변경, 파일 생성, 블럭 할당등의 모든 변경은 Name Node에 의해서 클라이언트의 요청에 성공이라는 응답을 주기 전에, Write-ahead log(WAL) 에 영구적으로 저장됩니다.  게다가, 파일 시스템에 정기적으로 체크포인트를 만드는 fsimage 와 edit log는 Name Node에 생성되고, 디스크에 저장됩니다. 반면에 블럭 위치 정보는 메모리에 저장됩니다. 모든 블록의 위치 정보는 “block reports” 를 통해서 Data Node로 부터 Name Node가 시작할 때 받게 됩니다.(역자 주, 정확하게 말하면 Memory에 전체 파일 블럭 정보가 있고, 이 내용을 정기적으로 fsimage로 만듭니다. 그리고 그 사이의 변경은 edits 라고 하는 파일에 저장됩니다. 기본 설정은 5분으로 되어있고, 5분마다, 현재의 fsimage에 edits를 merge 합니다. 그래서, 만약 Name Node 장애가 났다면, 해당 edits 도 필요합니다.)

HA Name Node 의 목표는 다운타임 없이 Active Name Node의 역할을 대체할 수 있는 미리 준비된 standby Name Node를 제공하는 것입니다.  이런 기능을 제공하기 위해서, 거의 대부분 완전하게 최신 파일 시스템의 상태를 가능한 메모리에 가지고 있는 것이 매우 중요합니다. 경험적으로 cold 상태에 있던 Name Node를 시작하는데는 namespace 정보를 디스크로 부터 읽기 위해서 수십분이 걸립니다.(fsimage 와 edit log) 그리고 큰 클러스터에서 필요한 블럭 위치 정보를 데이터 노드로 모두 받기 위해서 한 시간 이상 걸립니다.

Name Node는 변경 로그들을 다수의 신뢰성 있는 로컬 디렉토리에 저장해오고 있습니다. active 와 standby Name Node 들 사이에 해당 정보를 공유하기 위해서, HA Name Node 설정을 위한 기능 중에 edits 디렉토리를 공유하는 것을 설정하는 기능이 있습니다. 해당 디렉토리는 네트웤 파일 시스템을 이용해서 이용 가능해야 합니다. 그리고 반드시, 두 NameNode 모두에서 읽고 쓰기가 가능해야 합니다. 해당 디렉토리는 active 네임 노드에서는 필수로 다뤄지게 되고,  해당 디스크의 edit log에 파일 시스템의 변경이 쓰여지기 전까지는 클라이언트에 성공 메시지는 전달되지 않습니다. standby Name Node는 자주 공유된 edits 디렉토리에 접근해서, active Name Node 에 의해서 쓰여진 새로운 변경 정보를 확인합니다. 그리고 해당 변경 정보들을 읽어서 자신의 메모리의 파일 시스템 상태에 반영합니다.

하나의 공유 edits 디렉토리를 요구하는 것이 새로운 SPOF를 의미하지는 않습니다. 하지만, 이 공유 디렉토리는 스스로 HA, 고가용성을 제공해야 합니다. 그리고 Name Node들 간에 이 공유 디렉토리에 접근할 수 있는 다수의 네트웍 접근 루트가 있어야 합니다. (역자 주: 예를 들어, 네트웍 공유 디렉토리 장비쪽의 스위치가 장애가 날 수도 있고, 네트웍 카드가 문제가 될 수도 있습니다. 이럴 경우, 네트웍 카드도 여러 개, 앞 단의 스위치도 여러 개로 해서, 네트웍 공유 디렉토리 자체의 고가용성이 확보되어야 한다는 것입니다.)

해당 상황을 개선할 방법에 대해서는 아래에서 다시 얘기하도록 하겠습니다.

Block Locations

standby Name Node를 미리 준비된 상태로 유지해야하는 다른 부분은 블럭 위치 정보를 항상 최신으로 유지하는 것입니다. 블럭 위치 정보가 Name Node의 변경 로그에 쓰여지지 않으면, 공유 edits 디렉토리부터 읽는 것만으로는 파일 시스템 메타데이터를 Name Node들 간에 공유하기에 불충분합니다.  해당 문제를 처리하기 위해서 HA가 동작될 때, 클러스터의 모든 데이터 노드가 두 대의 Name Node의 네트웍 주소가 설정되어 있어야 합니다. Data Node는 모든 block report를 보내고 와 블럭의 위치 정보를 업데이트 합니다. 그리고 두 대의 Name Node에 대해서 정기적으로 상태를 체크합니다. 그러나 모든 Data Node들은 모든 블럭 관련 명령은 현재의 active Name Node로만 보고합니다.

Namespace 정보와 블럭 위치 정보 모두를 standby Name Node에서 유지하면, delay 없이 Active Name Node에서 Standby Name Node로 failover 가 가능합니다.

Client Failover

여러 데몬들이 Active Name Node로써 단일 클러스터에서 서비스를 할 수 있기 때문에, HDFS 클라이언트들은 해당 시점에 어떤 Name Node와 통신해야 하는지 알 수 있어야 합니다. Active-Active 설정은 HA Name Node 기능에서  제공하지 않습니다. 그래서 모든 클라이언트는 서비스를 위해서 Active Name Node 로만 요청을 보내야 합니다.

해당 기능을 구현하기 위해서, HDFS 클라이언트는 HA Name Node 서비스를 총괄적으로 나타내기 위해서, 각 Name Node 를 위해서 다중 네트웍 주소의 설정을 제공해야 합니다. 해당 네임 서비스는 클라이언트 쪽 설정을 통해서 HA Name Node의 두 개의 네트웍 주소를 매핑한 하나의 논리적 URI로 표현됩니다. 이 주소들은 HDFS 클라이언트에 의해서 적절히 시도됩니다. 만약 클라이언트가 standby Name Node로 요청한다면, 다른 곳으로 다시 요청하라는 응답을 받게 됩니다. active Name Node가 발견될때 까지, 클라이언트는 설정된 주소로 적절히 요청을 보내게 됩니다.

요청을 처리중에 Active Name Node가 장애가 나는 사건이 발생하면,  클라이언트는 요청이 처리되었는지 알 수가 없습니다. 읽기나 멱등한 쓰기(퍼미션 셋팅, 시간 변경, 등등 ) 같은 많은 요청들은 문제가 없습니다.(역자 주: 멱등한(idempotent) 라는 것은 ADD A 1 과 같은 명령이 아니 SET A 1 처럼 몇번 발생하더라도 문제가 없는 명령의 형태를 말합니다. 물론, 시간등 다양하게 고려해야 할 상황들이 생기지만, SET A 1 이 장애로 인해서 여러번 처리된다고 해도 SET A 2 라는 다른 명령이 들어오지만 않으면 몇번이 반복되어도 문제가 없습니다.그런데 ADD A 1은 어떨까요? 실수로 5번 처리되면 값이 5증가된 상태로 바뀌겠죠?) 클라이언트는 failover가 완료된 후에 매우 쉽게 재시도 하면 됩니다. 다른 경우에는 해당 에러는 반드시 호출자가 오류를 바르게 처리할 수 있도록 알려주어야 합니다. HA 프로젝트 과정에, 특별한 표기법을 통해서 각 멱등한 동작들을 구분할 수 있도록 Hadoop IPC 시스템을 확장했습니다.

Current Status

HA Name Node 에 대한 실제 개발은 아파치 하둡 trunk의 branch로써, 2011년 8월 부터 시작되었습니다.  개발은 HDFS-1623 과 HADOOP-7454 밑에서 완료되었습니다. 지난주 금요일, 2012년 3월 2일에 해당 branch를 아파치 하둡 trunk에 머지하였습니다. 해당 기능을 개발하면서 170개의 개별 지라 작업을 종료했습니다. 해당 작업을 HDFS trunk에서 0.23 branch로 머지해서, 아파치 하둡 0.23 릴리즈에의 업데이트로써 릴리즈하는 것이 목표입니다. 해당 작업의 대부분은 이미 2012년 2월 13일에 배포된 CDH4 beta 1 에서 이용할 수 있습니다.

failover 가 시작될 때 잠시, active Name Node가 멈추고, standby Name Node가 시작되는 작업이 몇초 정도 걸립니다. 이것은 잠시, 또는 인식하지 못할 정도로, 서비스가 failover 과정중에 동작하지 않을 수 있습니다. 개인적으로 HA cluster에서 수 백개의 MR 작업을 실행시키는데, 어떤 작업의 실패없이 두 대의 HA Name Nodes 에서 교대로 failover를 수행했습니다.

HA Name Node 첫 구현은 오직 수동 failover 만 지원합니다. 즉, 시스템에 의해서 Name Node중의 하나의 장애를 아직 자동으로 판별할 수 없고, Name Node 간의 failover 시작시에 오퍼레이터가 개입을 필요로 합니다. 이런 명백한 제약 사항에도 불구하고, 해당 버전은 많은 경우의 예정된 HDFS 다운타임을 제거하는데 유용합니다. 예를 들어, Name Node 설정의 변경이나, Name Node 장비의 예정된 유지 보수 또는 Name Node의 OS 업그레이드 시입니다.

Next Up

HA Name Node 구현에서 가장 우선순위가 높은 기능은 자동으로 Active Name Node의 장애를 탐지하는 것과 Active가 더 이상 동작하지 않는다고 생각될 때, 자동적으로 failover를 시작하는 것을 제공하는 것입니다. HDFS-3042 와 그 하위 태스크로 해당 기능을 제공하기 위해서 열심히 일하고 있습니다.

HDFS 변경 로그를 위한 HA file들에 대한 의존은 빨리 해결하고 싶은 제약사항입니다. 다음과 같은 몇개의 옵션들이 해결방법으로 논의되고 있습니다.

  • BookKeeper – BookKeeper 는 고가용성 WAL 시스템입니다. 변경로그를 BookKeeper 에 쓰는 작업은 아직 HA Name Node와 함께 테스트되지는 않았지만, 이미 완료된 작업입니다.
  • Multiple, non-HA filers – HA Name Node는 현재 오직 하나의 공유 edits 디렉토리에만 로깅을 합니다. 현재 상황에서 아마 가장 쉬운 구현은 Name Node 가 로그를 여러 공유 디렉토리에 나믹도록 허용하고 모든 로그는 과반 수 이상의 공유 디렉토리에 쓰여지게 하는 것입니다. 이것은  HDFS-2782에서 제안되었습니다.
  • Stream edits to remote NNs – 로컬 파일 에 변경 사항을 쓰는 것 뿐만 아니라, 네트웍을 통해서 바로 변경 사항을 다른 Name Node로도 보내는 것입니다. Active Name Node 는 클라이언트에게 성공 응답을 주기 전에 과반 수 이상의 다른 Name Node로 부터 해당 변경에 대한 응답을 받아야 합니다.
  • Store edit logs in HDFS itself – HBase 같은 시스템은 이미 HDFS에 모든 변경을 저장하는 WAL 데이터를 저장하고 있습니다. 만약에 HDFS가 시작 정보의 일부를 조금 확장한다면, HDFS 변경 로그를 HDFS에 저장하는 것은 불가능 하지 않습니다. HDFS-2601 에서 제안되었습니다.

몇 주 안에, 모든 옵션을 테스트하고 그 중에 하나를 선택해서 구현할 것입니다.

현재 HA Name Node의 배포는 조금 힘듭니다. 오퍼레이터가 Name Node들 간의 디스크 메타데이터 정보를 수동으로 싱크해야 합니다. HDFS-2731 에서 두 번째 Name Node 가 자동적으로 첫 번째 Name Node와 싱크를 맞춤으로써 사용자의 배포 과정을 개선하는 것을 목표로 하고 있습니다.  해당 기능은 배포 과정을 더 빠르고 에러가 적도록 해 줄 것입니다.

Further Reading

CDH4 에서의 HA Name Node 의 자세한 설명을 원하시면 CDH4 docs 를 보시기 바랍니다.( 역자 주: 아직 까지는 CDH4는 실무에서 사용할 레벨은 아닙니다. CDH3를 이용하시길 권장합니다. )

Todd Lipcom이 올린 블로그 포스트를 기대하기 바랍니다. HA Name Node 기능들을 구현하는 동안에 맞닫드렸던 문제들과 이를 어떻게 해결했는지 상세히 올릴 것입니다.

Acknowledgments

해당 작업은 처음부터, 커뮤니티의 노력으로 시작했고,  많은 컨트리뷰터들의 작업을 대표하는 것입니다. 설계와 구현 모두 많은 사람들의 노력이 모인 것이고, Todd Lipcon, Eli Collins, Uma Maheswara Rao G, Bikas Saha, Suresh Srinivas, Jitendra Nath Pandey, Hari Mankude, Brandon Li, Sanjay Radia, Mingjie Lai, and Gregory Chanan 등의 컨트리뷰터 없이는 불가능 했을 것입니다. 또한 테스트에 유용한 설계 토론과 조언을 해준 Dhruba Borthakur, Konstantin Shvachko 에게도 감사합니다. Stephen Chu, Wing Yew Poon, Patrick Ramsey 에게도 도움에 감사합니다.