하둡 완벽 가이드 - 11. 하둡 관리
본문 바로가기


Programmer/hadoop

하둡 완벽 가이드 - 11. 하둡 관리

사용자의 입장으로만 하둡을 바라보게 되어 깊이가 부족하다는 생각을 하게 되었다.
하둡 완벽 가이드를 읽고 이해한대로 정리한다.


11.1 HDFS

11.1.1 영속적인 데이터 구조

네임노드, 보조 네임노드, 데이터 노드가 영속적으로 사용하는 데이터를 디스크에 어떻게 구성하는지 알아보자.

네임노드 디렉터리 구조

    ${dfs.namenode.name.dir}/
    ├── current
    │   ├── VERSION
    │   ├── edits_0000000000000000001-0000000000000000019
    │   ├── edits_inprogress_0000000000000000020
    │   ├── fsimage_0000000000000000000
    │   ├── fsimage_0000000000000000000.md5
    │   ├── fsimage_0000000000000000019
    │   ├── fsimage_0000000000000000019.md5
    │   └── seen_txid
    └── in_use.lock
  • dfs.namenode.name.dir:  하둡 설정에서 지정한 디렉터리 목록으로, 여러개의 경로가 올 수 있다. 이 매커니즘을 통해 이 디렉터리 중 하나가 NFS 마운트로 구성되어있다면(권장!) 장애복구 능력을 제공한다.
  • VERSION: 자바 속성 파일로, 구동중인 HDFS 버전에 대한 정보를 포함한다 . 일반적으로 아래와 같다
    • 더보기
      • layoutVersion: HDFS의 영속적인 데이터 구조의 버전.
        • 하둡 배포판의 릴리즈 버전과는 관계 없이, 레이아웃이 변경될 때마다 버전 숫자가 줄어듦
          • 새로운 네임(데이터)노드의 저장소 레이아웃이 너무 오래되면 제대로 작동되지 않기 때문에, 레이아웃이 변경되면 HDFS를 업그레이드해야.  ( 뭔말이지?)
      • namespaceID: 파일시스템 네임스페이스의 유일한 식별자로, 네임노드를 처음 포맷할 때 생성된다. ( 뭘 분리하려고?)
      • clusterID: HDFS 클러스터 전체의 유일한 식별자
        • 특히 HDFS 페더레이션을 구성할 때 중요한 역할을 함.
        • HDFS 페더레이션을 사용하는 클러스터는 여러개의 네임스페이스로 구성되며, 각 네임스페이스는 하나의 네임노드가 관리. (???)
      • blockpoolID: 네임노드가 관리하는 네임스페이스의 모든 파일이 들어있는 블록 풀의 유일한 식별자
      • cTime: 네임노드 저장소의 생성시간.
        • 새롭게 포맷된 저장소는 항상 0
        • 파일시스템이 업그레이드 되면 갱신된 시점의 타임 스탬프로 변경됨
      • storageType: 해당 저장소의 디렉터리의 타입. 여기서는 네임노드
      #Mon Sep 29 09:54:36 BST 2014
      namespaceID=1342387246
      clusterID=CID-01b5c398-959c-4ea8-aae6-1e0d9bd8b142
      cTime=0
      storageType=NAME_NODE
      blockpoolID=BP-526805057-127.0.0.1-1411980876842
      layoutVersion=-57
  • in_use.lock: 네임노드가 저장소 디렉터리를 잠그는 데 사용하는 잠금 파일.
    • 다른 네임노드의 인스턴스가 동일한 저장소 디렉터리에서 사용되는 것(파일시스템의 손상)을 방지하는 역할(???)
    • 없으면??
  • edits: 파일시스템의 클라이언트가 쓰기 동작을 하면 네임노드가 내역을 기록하는 곳.
    • 네임노드는 파일시스템의 메타데이터를 인메모리(파일, 메모리 모두에 데이터 유지 방식)로 관리
    • 에디트 로그(파일)를 먼저 변경한 후 메모리상의 메타 데이터를 변경
    • 클라이언트의 읽기 요청에는 인메모리 메타데이터만 사용
    • 여러개의 파일로 관리되며, 각 파일을 세그먼트라고 부르고, 파일명은 edits_{트랜젝션ID}
    • 쓰기가 끝나면 에디트로그 플러시 후 클라이언트에 노티함
    • 네임노드가 여러개의 디렉터리에 에디트 로그를 기록할 수 있으므로, 모든 디렉터리에 동기화 후 성공을 노티함 (데이터 손실 방지!)
  • fsimage: 파일시스템 메타데이터의 완전하고 영속적인 체크포인트로, 파일시스템에 존재하는 모든 디렉터리와 피일의 아이노드 정보를 직렬화한 값이 저장되어 있음
    • 파일명의 접미사는 파일시스템 이미지의 마지막 트랜젝션
    • 블록이 실제 저장된 데이터노드에 대한 정보는 fsimage 파일에 저장되지 않는다 (데이터 노드가 네임노드에 알려주도록 설계되어있기 때문)
  • seen_txid: 체크포인트를 만들기 위해서 모든 저장소의 디렉토리를 순회하면서 어디까지 edits 로그를 봤는지 기록하는 파일
    • 마지막 체크포인트의 마지막 트랜잭션 ID 또는 현재 edits_inprogress의 마지막

edits, fsimage, seen_txid 파일을 이용하여 체크포인팅 작업을 하며, 절차는 다음과 같다.

  1. 보조 네임노드는 주 네임노드에 사용중인 edits 파일을 순환할 것을(거기까지만 쓰고 이제 새파일에 써) 요청한다. 그럼 주 네임노드가 seen_txid 파일을 업데이트한다.
  2. 보조 네임노드는 HTTP GET 방식으로 주 네임노드에 있는 최신 fsimage와 edits 파일을 가져온다.
  3. 보조 네임노드는 fsimage 파일을 메모리에 올리고 edits 파일의 각 변경 내역을 적용한다. 그리고 병합된 새로운 fsimage 파일을 생성한다.
  4. 보조 네임노드는 새로운 image 파일을 HTTP PUT 방식으로 주 네임노드에 전송하고, 주 네임노드는 받은 파일을 .ckpt 확장자 임시파일로 저장한다.
  5. 주 네임노드는 .ckpt 확장자 임시파일을 변경한다.

마지막 단계까지 끝나면 주 네임노드는 최신 fsimage 파일과 작은 edits 파일을 가지게 된다.

체크포인팅 절차는 두 개의 환경 설정 매개변수를 사용해서 제어한다.

  • dfs.namenode.checkpoint.period: 초단위로, 보조 네임노드가 해당 단위마다 체크포인트를 생성
  • dfs.namenode.checkpoint.check.period: 분단위로, 에디트 로그를 확인하고,
    dfs.namenode.checkpoint.txns: 마지막 체크포인트 이후에 기록된 변경 내역의 개수가 넘으면 새로운 체크포인트를 생성

보조 네임노드 디렉터리 구조

주 네임노드의 체크포인트 디렉터리와 동일하다. 해당 저장소 디렉터리를 새로운 네임노드에 복사하여 복구하거나, 보조 네임노드를 시작할 때 -importCheckpoint 옵션을 사용하여 새로운 주 네임노드 역할을 맡길 수도 있다. -importCheckpoint 옵션은 dfs.namenode.checkpoint.dir 속성으로 정의된 디렉터리에 있는 가장 최근의 체크포인트의 네임노드 메타데이터를 불러온다. 이 작업은 해당 디렉터리에 메타데이터가 없을때만 수행되므로, 덮어써질 위험은 없다.

데이터노드 디렉터리 구조

네임노드와 달리 데이터노드는 명시적으로 포맷할 필요가 없다. 각 머신에서 데이터노드가 처음 시작될 때 자동으로 저장소 디렉터리를 생성하기 때문이다. (왜징??)

${dfs.datanode.data.dir}/
├── current
│   ├── BP-526805057-127.0.0.1-1411980876842
│   │   └── current
│   │       ├── VERSION
│   │       ├── finalized
│   │       │   ├── blk_1073741825
│   │       │   ├── blk_1073741825_1001.meta
│   │       │   ├── blk_1073741826
│   │       │   └── blk_1073741826_1002.meta
│   │       └── rbw
│   └── VERSION
└── in_use.lock
  • blk_ : HDFS의 각 블록이 저장되는 파일.
    • 각 파일은 저장된 파일의 일부분을 원시 바이트 형태로 저장
    • .meta로 끝나는 연관 메타데이터 파일은 버전 및 타입 정보를 가진 헤더와 일련의 블록 구간별 체크섬으로 구성됨
    • 각 블록은 블록 ID(네임노드의 VERSION 파일에 있는 블록 풀 ID)로 된 저장소 디렉터리에 저장됨
    • 하나의 디렉터리에 저장된 블록의 수가 지정된 개수를 넘으면 새로운 서브 디렉터리를 생성 -> 넓은 부채꼴 형태의 트리 구조
      -> 단일 데렉터리에 대량의 파일(수만~수십만)을 저장할 때 발생하는 문제를 사전에 방지
  • dfs.datanode.data.dir: 다른 물리적 드라이브를 가진 다수의 디렉터리를 지정하면 라운드-로빈 방식으로 각 블록을 저장

11.1.2 안전 모드

네임노드가 일관된 파일시스템 메타데이터의 인메모리 이미지를 재구성하였다면 새로운 fsimage 파일과 빈 에디트 로그를 생성한다. 이 과정에서 안전모드로 동작되고, 읽기만 가능하다.

최소 복제 조건을 만족한 후 30초가 지나면 안전 모드가 해제된다. 최소 복제조건은 전체 파일시스템의 블록이 최소 복제수준(dfs.namenode.replication.min)의 99.9% 를 넘을 때를 말한다.

11.1.3 감사 로깅

HDFS는 모든 파일 시스템의 접근 요청을 기록할 수 있으며, 이런 기능은 조직에서 감사를 할 때 필요하다. 감사 로깅은 INFO 수준의 log4j를 이용해 구현되어있고, 기본적으로 비활성화 되어있으나, hadoop-env.sh에 설정을 추가해서 활성화 할 수 있다.

11.1.4 도구

  • dfsadmin: HDFS의 상태 정보를 확인하고 HDFS에서 다양한 관리 작업을 수행할 수 있는 다목적 도구. 슈퍼유저 권한이 필요하며 hdfs dfsadmin 명령으로 실행할 수 있다.
  • fsck: 저장된 파일의 상태 점검용 유틸리티. 적게 혹은 많이 복제된 블록뿐만 아니라 모든 데이터노드에서 사라진 블록을 찾을 수 있다.
  • 데이터노드 블록 스캐너: 모든 데이터노드가 데이터노드에 저장된 모든 블록을 주기적으로 점검하는 도구
    • 기본값으로 3주마다 전체 블록을 점검
  • 밸런서: 데이터노드 사이의 블록의 분포가 불균형 상태가 될 수 있으므로, 자주 사용되는 데이터노드의 블록을 사용률이 낮은 데이터노드로 옮기는 하둡 데몬.

11.2 모니터링

11.2.1 로깅

로깅을 위해 참고할 수 있는 정보는 아래와 같다.

  • 로그 수준 설정: 시스템의 특정 컴포넌트의 로그 수준을 각 데몬의 웹 UI의 /logLevel에서 임시로 변경할 수 있다.
  • 스택 트레이스: 하둡 데몬은 JVM에서 실행되는 모든 스레드에 대해 덤프를 생성할 수 있는 웹페이지를 제공한다. (웹 UI의 stacks)

11.2.2 메트릭과 JMX

  • 메트릭: 이벤트와 측정치에 대한 정보. (데이터노드의 기록된 바이트 수, 복제된 블록 수, 클라이언트의 읽기 요청 수(로컬 + 원격) 등..)
    • dfs, mapred, yarn, rpc등 여러 콘텍스트에 속해있다.
  • JMX: java mamagement extension으로, 모든 하둡 메트릭이 게재되는 방식.
    • JConsole과 같은 표준 JMX 도구를 사용해서 메트릭을 볼 수 있다.

11.3 유지 보수

11.3.1 일상적인 관리 절차

메타데이터 백업

% hdfs dfsadmin -fetchImage fsimage.backup

데이터 백업

HDFS는 데이터를 안전하게 저장하도록 설계되었지만 다른 저장소 시스템처럼 데이터 손실이 발생할 가능성이 있다!!
우선순위가 높은 데이터는 반드시 스냅숏을 생성하여 distcip 도구로 백업해두자.

파일시스템 점검

fsck를 통해 정기적으로(매일) 점검하자

파일시스템 밸런서

파일시스템의 데이터노드를 균등한 상태로 유지하기 위해 밸런서 도구를 정기적으로 실행하자

11.3.2 노드의 추가와 퇴역

이슈가 있는 노드는 퇴역시키고, 새 노드를 추가해야한다

hdfs-site.xml 파일에 네임노드를, yarn-site.xml 파일에 리소스 매니저를 지정하여 노드를 간단히 추가할 수 있다. 이때 보안을 위해 추가를 허용하는 노드 목록을 dfs.hosts 속성으로 명시해두어야한다.

클러스터에 새로운 노드를 추가하는 절차는 다음과 같다.

  1. include 파일에 새로운 노드의 네트워크 주소를 추가한다.
  2. hdfs dfsadmin -refreshNodes 명령어로 네임노드에 반영한다
  3. yarn rmadmin -refreshNodes 명령어로 리소스 매니저에 반영한다.
  4. 새로 추가된 노드를 slaves 파일에 반영하여 하둡 제어 스크립트가 새로 추가된 노드를 향후에 다룰 수 있도록 한다.
  5. 새로운 데이터노드와 노드 매니저를 시작한다.
  6. 새로운 데이터노드와 노드 매니저가 웹 UI에 표시되는지 본다.

오래된 노드를 퇴역시키는 절차는 다음과 같다.

  1. exclude 파일에 해제할 노드의 네트워크 주소를 추가한다. 아직 include 파일을 갱신하지 않는다.
  2. hdfs dfsadmin -refreshNodes 명령어로 네임노드에 반영한다
  3. yarn rmadmin -refreshNodes 명령어로 리소스 매니저에 반영한다.
  4. 웹 UI에 퇴역시킬 데이터노드의 관리 상태가 Decommission in Progress인지 본다. 해당 과정에서 대상 데이터노드는 자신의 블록을 클러스터의 다른 데이터노드로 복제한다
  5. 데이터 노드의 관리상태가 Decommissioned가 되면 모든 블록의 복제가 완료된 것이다. 이제 퇴역시킨 노드를 중단시킨다.
  6. include 파일을 갱신하고, hdfs dfsadmin -refreshNodes와 yarn rmadmin -refreshNodes 명령어를 수행한다.
  7. slaves 파일에서 노드를 삭제한다.