HDFS 구조(Architecture)
기본적으로 HDFS는 마스터 슬레이브 구조야
마스터 슬레이브 구조
마스터/슬레이브(Master/slave)는 장치나 프로세스(마스터)가 하나 이상의 다른 장치나 프로세스(슬레이브)를 통제하고 통신 허브 역할을 하는 비대칭 통신 및 제어 모델을 의미한다
아래의 그림처럼 분산처리 시스템이기 때문에 MapReduce와 HDFS는 기본적으로 Master와 Slave의 관점으로 구분이 돼. 쉽게 말하면, 분산되어져 있는 것들을 관리할 master가 필요하다고 생각하면 좋을 것 같아. 즉, 일을 시킬 컴퓨터가 하나는 있어야해.
MapReduce는 일을 어떻게 나눠서 수행하는지를 Master에서 관리하고, HDFS는 저장 시 어떻게 분산 저장할 지를 Master에서 관리하는거지.
HDFS는 마스터 슬레이브 구조로 하나의 네임노드와 여러 개의 데이터노드로 구성되어 있어. 네임노드는 메타데이터를 가지고 있고, 데이터는 블록 단위로 나누어 데이터노드에 저장돼. 데이터를 읽고 쓰려면 사용자는 메타데이터를 가지고 있는 네임노드를 이용하면 되는거지.
네임노드, 데이터노드, 블록에 대해 하나씩 알아보도록 하자.
네임노드는 분산 처리 시스템에서 Master를 담당하며, 메타데이터 관리와 데이터노드를 관리한다.
네임노드는 각 데이터노드에서 전달하는 메타데이터를 받은 후에 전체 노드의 메타데이터 정보와 파일 정보를 묶어서 관리해. 즉 파일 시스템을 유지하기 위해 메타데이터를 관리하는거지
데이터를 저장할 시에 기본적으로 블록단위로 들어오게 되는데, 이때 들어온 블록들을 어느 데이터노드에서 저장 할 지를 정해준다고 이해하자.
데이터노드는 실제로 데이터를 저장하는 컴퓨터기 때문에 에러가 날 수도 있어. 따라서 네임노드와 데이터 노드는 3초마다 하트비트(heartbeat)를 주고 받아.
쉽게 말하면 데이터 노드에서 살아있다고 네임노드에 문서를 보내 알려주는 것이야. 이러한 알림을 3초마다 보내기 때문에, 알림이 안오면 문제가 생겼다고 판단해. 이러한 문제가 생긴다면 다른 데이터 노드에 복제된 블럭을 가지고 와서 사용할 수 있어.
메타데이터는 전체적인 구조를 나타내. 그리고 메타데이터는 파일이름, 파일크기, 파일생성시간, 파일접근권한, 파일 소유자 및 그룹 소유자, 파일이 위치한 블록의 정보 등으로 구성돼. 저장위치는 사용자가 설정한 위치(dfs.name.dir)에 저장돼.
데이터노드는 데이터들이 저장되는 컴퓨터야. 데이터노드는 파일을 저장하는 역할을 하고, 이때 파일은 블록단위로 저장돼. 데이터노드는 주기적으로 네임노드에 하트비트와 블록리포트를 전달해.
하트비트 : 데이터노드의 동작여부를 판단하는데 이용되고, 네임노드에서는 하트비트가 전달되지 않는 데이터노드는 동작하지 않는 것으로 판단하여 더이상 데이터를 저장하지 않도록 설정한다.
블록리포트 : 블록의 변경사항을 체크하고, 네임노드의 메타데이터를 갱신한다. 블록파일은 사용자가 설정한 위치(dfs.data.dir)에 저장된다.
데이터노드는 상태를 나타내는 정보로 활성상태와 운영상태를 확인할 수 있어.
활성상태
데이터노드가 Live, Dead 상태인지를 나타낸다. 데이터노드가 하트비트를 통해 활성 상태가 확인이 되면 Live 상태이다. 만약 문제가 발생하여 지정 시간동안 하트비트를 받지 못하면 네임노드는 데이터 노드의 상태를 Stale 상태로 변경하고, 그 이후에도 지정한 시간동안 응답이 없으면 Dead 노드로 변경한다.
운영상태
운영 상태는 보통 데이터 노드의 업그레이드나 작업을 하기 위해 서비스를 잠시 멈추어야 할 경우 블록을 안전하게 보관하기 위해 설정한다. 운영상태의 종류에는 아래와 같다.
NORMAL 서비스 상태
DECOMMISSIONED 서비스 중단 상태
DECOMMISSION_INPROGRESS 서비스 중단 상태로 진행 중
IN_MAINTENANCE 정비 상태
ENTERING_MAINTENANCE 정비 상태로 진행 중
기본적으로 네임노드는 Fsimage와 Edits를 읽어서 작업을 처리해.
먼저 Fsimage를 읽어서 메모리에 적재한 후에 Edits 파일을 읽어와서 변경내역을 반영시키고, 현재의 메모리 상태를 반영하여 Fsimage 파일을 생성하는거지. 데이터 노드로부터 블록리포트를 수신하여 매핑정보를 생성하고 서비스를 시작할 수 있어.
HDFS의 파일에 대한 내용을 위에서 배웠다. 그렇다면, 내부의 파일을 사용하는 법에 대해 알아보자.
HDFS의 파일을 읽는 순서는 아래와 같다.
- open() 명령어를 통해 DistributedFileSystem에 있는 FileSystem의 파일을 연다
- RPC()를 NameNode를 호출하여 저장되어있는 블록이 저장된 DataNode의 주소를 받는다.
- DistributedFileSystem은 client가 데이터를 검색할 수 있도록 검색을 지원하는 입력 스트림인 FSDataInputStream를 client에게 준다. 그러면 그것을 통해 찾고자 하는 datanode와 DFSInputStream이 맵핑된다. 그리고 검색후 read() 명령어를 통해 호출을한다.
- datanode 주소가 저장된 DFSInputStream은 datanode와 연결되고, 데이터는 datanode에서 클라이언트로 가게된다. 이러한 형식으로 반복 read()가 호출하여 파일을 읽는다.
- 블록 끝에 도달하면 DFSInputStream은 데이터 노드에 대한 열결을 닫고, 다음 블록에 가장 접합한 데이터 노드를 찾는다.
- 읽기가 마치면 FSDataInputStram에서 close()를 호출한다.
RPC : remote procedure call, 은 별도의 원격 제어를 위한 코딩 없이 다른 주소공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술
Hadoop의 HDFS는 파일을 데이터 블록이라고 하는 작은 크기의 블록으로 나눠서 사용해.
HDFS는 지정한 크기의 블록으로 나누어 지고 각각 독립적으로 저장해.
만약 지정한 크기보다 작은 파일은 실제 파일 크기의 블록으로 저장되고, 지정 크기보다 크다면 나눠서 저장시켜.
따라서 파일의 모든 블록은 마지막 블록을 제외하고는 동일한 크기가 돼.
HDFS 데이터 블록은 기본적으로 검색 및 네트워크 트래픽 비용을 줄여준다. 기본적으로는 128MB의 크기의 덩이리이며, 크기는 재설정 가능하다.
HDFS Federation은 디렉토리 단위로 네임노드를 등록하여 사용하는 것으로, 파일이 많아짐에 따른 메모리 관리 문제를 해결하기 위해 하둡 v2 부터 지원됐어.
예를 들어 user, hadoop, tmp 세개의 디렉토리가 존재할 때, /user, /hadoop, /tmp 디렉토리 단위로 총 3개의 네임노드를 실행하여 파일을 관리하게 해. 각각 독립적으로 관리하기 때문에 하나의 문제가 발생하더라도, 다른 네임노드에 영향을 주지 않아.
네임노드에 문제가 발생하면 모든 작업이 중지되고, 파일을 읽거나 쓸 수 없게 돼. 하둡 v2에서 이 문제를 해결하기 위해서 HDFS High Availability을 제공하고 있어.
HDFS 고가용성(Hight Availability)은 이중화된 두대의 서버인 액티브(active) 네임노드와 스탠바이(standby) 네임노드를 이용하여 지원해. 액티브 네임노드와 스탠바이 네임노드는 데이터 노드로부터 블록 리포트와 하트비트를 모두 받아서 동일한 메타데이터를 유지하고, 공유 스토리지를 이용하여 에디트파일을 공유한다.
액티브 네임노드는 네임노드의 역할을 수행한다.
스탠바이 네임노드는 액티브 네임노드와 동일한 메타데이터 정보를 유지하다가, 액티브 네임노드에 문제가 발생하면 스탠바이 네임노드가 액티브 네임노드로 동작한다.
액티브 네임노드에 문제가 발생하는 것을 자동으로 확인하는 것이 어렵기 때문에 보통 주키퍼를 이용하여 장애 발생시 자동으로 스탠바이 네임노드로 변경될 수 있도록 하고 있어.
스탠바이 네임노드는 세컨더리 네임노드의 역할을 동일하게 수행하기 때문에, HDFS를 고가용성 모드로 설정하였을 때는 세컨더리 네임노드를 실행하지 않아도 괜찮아. 만약 고가용성 모드에서 세컨더리 네임노드를 실행하면 오류가 발생하게 돼.
safemode는 일기 전용 상태로 데이터 노드 수정이 불가능해서, 데이터의 추가, 수정, 복제가 일어나지 않는다. 보통 safemode는 노드에 문제가 생겼거나 서버 운영 정비를 위해 설정을 한다.
휴지통 기능이 설정되면 HDFS에서 삭제한 파일은 바로 삭제되지 않고, 각 사용자의 홈디렉토리 아래 휴지통 디렉토리(/user/유저명/.Trash)로 이동된다.