하둡 완벽 가이드 책에서 HDFS 에 대해 공부 한 내용을 여기 적는다.
- HDFS 기본 block size 는 (20년 7월 29일 기준) 128mb 이다.
- 원본 데이터가 block size 보다 작아도 disk 에 block size만큼의 데이터를 사용하지 않는다.
예를 들어 block size 128mb, 원본 데이터가 1mb 일 때
디스크에서 사용되는 용량을 1mb 이다.
- block size 가 큰 이유는, 탐색 비용을 최소화하기 위함이다.
block size 가 크니까 block 의 시작점을 탐색하는 데 걸리는 시간을 줄일 수 있고
데이터 전송에 더 많은 시간을 할애할 수 있다.
- Name Node (NN) 은 파일 시스템의 네임스페이스를 관리한다.
파일 시스템 트리와 그 트리에 포함된 모든 파일과 디렉터리에 대한 메타데이터를 유지한다.
이는 namespace iamge 와 edit log 라는 두 종류의 파일로 로컬 디스크에 영구 저장된다.
데이터의 위치는 시스템이 재시작할 때 DataNode(DN)로부터 받기 때문에 영구 저장되지 않는다.
- HDFS Client 는 사용자를 대신해 NN와 DN 사이에서 통신하고 파일시스템에 접근한다.
- DN 는 파일시스템 Client 나 NN의 요청이 있을 때 블록을 저장하고 탐색하며,
저장하고 있는 블록의 목록을 주기적으로 NN에 보고한다.
- DN 가 자주 접근하는 블록은 off-heap 블록 캐시 (메모리)에 넣어 캐싱 가능하다.
- NN 는 filesystem 의 모든 파일과 각 블록에 대한 참조 정보를 메모리에서 관리한다.
HDFS 페더레이션을 사용하면 각 NN가 파일 시스템의 Namespace 일부를 나눠 관리하는 방식으로
새로운 NN를 추가 가능하다.
예를 들어 첫번째 NN는 /user 디렉터리 아래 모든 파일을 관리하고
두번째 NN 는 /share 디렉터리 아래 모든 파일을 관리한다.
HA 클러스터 참고 : https://eyeballs.tistory.com/251
- HA 클러스터 구성에서 standby 를 active 로 전환시키는 전환 작업은
failover controller(FC) 라는 새로운 객체로 관리된다.
다양한 방법으로 구현 가능하지만 기본 구현체는
'단 하나의 NN만 active 상태라는 것을 보장해주는' 주키퍼를 사용한다.
경량의 FC 들은 하트비트를 통해 각 NN의 장애를 감시하고 NN 장애가 발생하면 복구를 지시한다.
- 장애가 발생한 NN가 현재 실행되지 않고 있단 것을 확신하기 어렵다.
네트워크가 느려지거나 ,단절되어 장애 복구 작업이 시작된 상황에서도
기존의 active NN 는 여전히 실행되고 있고 자신이 아직 Active 라고 생각할 것이다.
기존의 active NN 가 시스템을 손상시키거나 망가뜨리지 않도록
기존 active NN를 확실하게 죽이기 위해 펜싱(fencing) 메소드를 제공한다고 한다.
- HDFS 는 기본적으로 보안이 비활성화된 상태로 실행되므로
클라이언트의 사용자 계정을 인증하지 않음.
- HDFS 로부터 파일을 읽는 절차
- HDFS client는 DistributedFileSystem 인스턴스인 Filesystem 객체의
open() 메소드를 호출하여 원하는 파일을 연다. (1단계)
- DistributedFileSystem 은 파일의 첫 번째 블록 위치를 파악하기 위해
RPC 를 이용하여 NN를 호출한다. (2단계)
- NN는 블록별로 해당 블록의 복제본을 갖는 DN 의 주소를 반환한다.
이때 client와 가까운 순으로 DN가 정렬된다.
(만약 client 자체가 DN 이고, 해당 블록의 복제본을 갖고 있다면 client 는 로컬 DN에서 데이터를 읽는다.)
- DistributedFileSystem 은 Client 가 데이터를 읽을 수 있도록 FSDataInputStream 을 반환한다.
FSDataInputStream 은 파일 탐색을 지원하는 입력 스트림이며,
DN 와 NN 의 IO를 관리하는 DFSInputStream 을 래핑한다.
- Client 는 스트림을 읽기 위해 read() 메소드를 호출 (3단계)
파일의 첫 번째 block 의 DN 주소를 저장하고 있는 DFSInputStream은
Client 와 가장 가까운 DN 와 연결
- 해당 스트림에 대해 read() 메서드를 반복적으로 호출하며 DN 에서 Client 로 모든 데이터 전송 (4단계)
- blcok의 끝에 도달하면 DFSInputStream 은 DN 의 연결을 닫고 다음 block 의 DN 를 찾음 (5단계)
Client 는 이러한 내부 과정 없이 연속적인 스트림을 읽는 것처럼 느낌.
- Client는 스트림을 통해 block 을 순서대로 하나씩 읽음.
이때 DFSInputStream 은 블록마다 DN 와 새로운 연결을 맺음
Client 는 다음 block 의 DN 위치를 얻기 위해 NN 호출
모든 block 읽기가 끝나면 Client 는 FSDataInputStream 의 close() 메소드를 호출 (6단계)
- 데이터를 읽는 중에 DN 와의 통신장애 발생시 DFSInputStream은 해당 블록을 저장하고 있는 다른 DN 와 연결 시도
이후 block 에 대한 불필요한 재시도 방지를 위해 장애 발생한 DN 기억
- DFSInputStream은 DN 로부터 전송된 데이터 체크섬도 검증
block 손상시 DFSInputStream 이 다른 DN 에 있는 block copy 읽으려 시도
물론 손상된 block 정보는 NN에 보고됨
- Client 가 데이터를 얻기 위해 DN 에 직접 접촉하고 NN는 각 블록에 적합한 DN 안내하는 것이 핵심
- 데이터 트래픽은 클러스터 내 모든 DN 에 고르게 분산
HDFS 는 동시 실행되는 Client 수를 크게 늘릴 수 있음
- NN는 효율적인 서비스를 위해 meta data를 메모리에 저장
단순히 block 위치 정보 요청만 처리
데이터 저장이나 전송 역할은 모두 DN 에게 넘김으로써 Client 증가에 따른 병목 현상이 거의 발생하지 않음
- HDFS 에 파일을 쓰는 절차
- 쓰기 진행 과정은 크게, 새로운 파일을 생성하고, 파일에 데이터를 쓰고, 파일을 닫는 순으로 진행됨
- HDFS Client 는 DistributedFileSystem 의 create() 를 호출하여 파일 생성 (1단계)
- DistributedFileSystem 은 파일시스템의 네임스페이스에 새로운 파일을 생성하기 위해 NN 에 RPC 요청 (2단계)
이땐 block 에 대한 정보는 보내지 않음.
- NN 는 요청한 파일과 동일한 파일이 이미 존재하는지, Client 가 파일 생성 권한을 갖고 있는 지 등의 검사를 수행
검사를 통과하면 NN 는 새로운 파일의 레코드를 만듦
검사에 실패하면 파일 생성은 실패하고 Client 에게 IOException 발생
- DistributedFileSystem 은 데이터를 쓸 수 있도록 Client 에 FSDataOutputStream을 반환
읽을 때와 마찬가지로, FSDataOutputStream 은 DN 와 NN 의 통신 처리를 하는 DFSOutputStream으로 래핑됨
- Client 가 데이터를 쓸 때 (3단계) DFSOutputStream은 데이터를 패킷으로 분리
데이터 큐 라 불리는 내부 큐로 패킷을 보냄
- DataStreamer 는 데이터 큐에 있는 패킷을 처리하기 위해 NN에 복제본을 저장할 DN 의 목록을 요청
DN 목록에 포함된 노드는 파이프라인을 형성하는데, 복제 수준이 3이면 3개의 노드가 파이프라인에 속하게 됨
- DataStreamer는 pipeline 의 첫 번째 DN 로 패킷 전송
첫 번째 DN 는 각 패킷을 저장한 후 그것을 pipeline 을 통해 두번째 DN 로 보냄
두 번쨰 DN 역시 각 패킷을 저장한 후 그것을 pipeline 을 통해 세번째 DN 로 보냄
새 번째 DN 역시 각 패킷을 저장 (4단계)
- DFSOutputStream 은 DN 의 승인 여부를 기다리는 ack 큐 라 불리는 내부 패킷 큐를 유지
ack 큐에 있는 패킷은 pipeline 의 모든 DN 로부터 ack 응답을 받아야 제거됨 (5단계)
- 데이터를 쓰는 중에 DN 에 장애 발생시 다음과 같은 장애 복구 작업이 시작됨.
- 먼저 pipeline 이 닫히고 ack 큐에 있는 모든 패킷은 데이터 큐 앞쪽에 다시 추가
이렇게 함으로써 다운스트림 노드가 실패해도 패킷이 하나도 유실되지 않음
- 정상 DN 는 NN 로부터 새로운 ID 다시 받음.
- 장애가 발생한 DN 가 나중에 다시 복구되면 불완전한 block 은 삭제가 됨
- 장애 DN 는 pipeline 에서 제거되고 정산인 나머지 두 DN 로 새로운 pipeline 이 구성됨
- 블록의 남은 데이터는 파이프라인의 정상 DN 로 전송
- NN는 해당 block 이 불완전 복제 라는 것을 인식하고 있으므로 나중에 다른 노드에 복제본이 생성되도록 조치를 취함
이어 후속 블록을 정상적으로 처리
- 두 대 이상의 DN 에서 장애가 발생할 확률은 극히 희박
- 데이터 쓰기 완료시 Client 는 스트림에 close() 메서드를 호출 (6단계)
이 메서드는 DN 파이프라인에 남아있는 모든 패킷을 flush 하고, 승인이 나기를 기다림
- 모든 패킷이 완전히 전송되면 NN 에 파일 완료 신호를 보냄 (7단계)
- NN는 DataStreamer 를 통해 블록 할당 요청을 받았기 때문에 파일의 블록이 어떻게 구성되어있는지 이미 알고 있음
최소한의 블록 복제가 완료되길 기다렸다가 최종적으로 성공 신호 반환
- NN가 복제본을 저장할 데이터노드 선택하는 방법
첫번째 복제본은 클라이언트와 같은 노드에 배치
그런데 Client 가 클러스터 외부에 있거나 데이터 노드가 아니면, 무작위로 노드를 선택.
(무작위긴 해도 너무 바쁘거나 파일이 많은 노드는 제외)
두번째 복제본은 첫번째 노드와 다른 랙의 노드 중 하나를 무작위로 선택
세번째 복제본은 두번째 노드와 같은 랙의 다른 노드에 배치
그 이상의 복제본은 클러스터에서 무작위로 선택
(물론 같은 랙에 너무 많은 복제본이 배치되지 않도록 잘 조절함)
'Hadoop' 카테고리의 다른 글
[Hadoop] 하둡 스트리밍에 대한 설명 링크 (0) | 2020.07.31 |
---|---|
[Hadoop] RPC 에 대한 간단한 설명 및 링크 (0) | 2020.07.29 |
[Hadoop] Block Size 와 Split Size (0) | 2020.07.29 |
[Hadoop] 하둡 완벽 가이드 필기 - YARN (0) | 2020.07.29 |
[YARN] 스케줄러 scheduler 설명 (0) | 2020.07.23 |