티스토리 뷰
반응형
1. 용어정리
- Job 잡 : 클라이언트가 수행하는 작업의 기본 단위
- 입력데이터, 맵리듀스 프로그램, 설정정보로 구성된다.
- "맵 태스크", "리듀스 태스크"로 나뉜다.
- 각 태스크는 YARN을 이용해 스케줄링 되고 클러스터의 여러 노드에서 실행된다.
- 특정 노드의 태스크 하나가 실패하면 자동으로 다른 노드를 재할당하여 다시 실행된다.
- Input split 입력 스플릿 : 잡의 입력에 해당된다. 입력데이터는 고정 크기 조각인 스플릿으로 분리된다.
- 스플릿마다 하나의 맵태스크를 생성하고, 스플릿의 각 레코드를 사용자 정의 맵 함수로 처리한다.
- 스플릿의 크기가 작을 수록 부하 분산에 더 좋은 효과를 낸다.
- 스플릿의 크기가 너무 작으면 스플릿 관리와 맵태스크 생성을 위한 오버헤드 때문에 잡의 실행시간이 증가하게 된다. 적절한 스플릿의 크기는 HDFS블록의 기본크기인 128MB이다.
- 스플릿의 크기가 HDFS 블록크기와 같은편이 좋은 이유 : 하나의 스플릿이 HDFS 두 블록에 걸쳐있을 때 두 블록 모두가 하나의 노드에 저장되있을 확률이 낮기 때문에 스플릿의 일부 데이터를 네트워크를 통해 맵태스크가 실행되는 노드로 가져와야한다. 이렇게 되면 맵태스크 전체가 로컬 데이터만 이용할 때 보다 느려지게 된다.
- 맵 태스크
- 맵태스크의 결과는 HDFS가 아닌 로컬 디스크에 저장된다.
- 맵의 결과는 리듀스가 최종결과를 생성하기위한 중간 결과물(temp file) 이고, 잡이 완료된 후 맵의 결과는 그냥 버려지기 때문이다. 따라서 맵의 결과를 HDFS에 저장하는 것은 내부 복제 과정을 추가하는 것이 되어 적절치 않다.
- 리듀스 태스크로 모든 결과를 보내기 전에 맵태스크가 실패한다면 하둡은 자동으로 해당 맵태스크를 다른 노드에 할당하여 맵의 출력을 다시 생성할 것이다.
- 리듀스 태스크
- 리듀스 태스크는 일반적으로 모든 매퍼의 출력 결과를 입력으로 받기 때문에 데이터 지역성의 장점이 없다. 모든 맵 태스크 결과는 정렬되어 로컬디스크에 저장된후 네트워크를 통해 리듀스 태스크가 실행중인 노드로 전송된다. 리듀스 태스크는 맵의 모든 결과를 병합한 후 사용자 정의 리듀스 함수로 전달해서 부분결과를 만든후 hdfs로 복제한다.
- 리듀스 태스크 수는 입력크기와 상관없이 독립적으로 지정할 수 있다. 리듀스가 여럿이면 맵태스크는 리듀스 수만큼 파티션을 생성하고 맵의 결과를 각 파티션에 분배한다. 하나의 맵태스크가 파티셔닝을 해서 여러 리듀스 태스크에게 동일한양의 데이터를 전송한다는 말.
- 각 파티션에는 여러키가 존재하지만 개별 키에 속한 모든 레코드는 여러 파티션 중 한곳에만 배치된다. 파티셔닝 알고리즘은 사용자 정의 파티셔닝 함수를 지원하지만 해시함수로 키를 분해 하는 기본 파티셔너를 주로 사용하며 매우 잘 작동한다.
- 리듀스 태스크가 아예 없을 수도 있다. 즉, 집계할 필요가 없는 완전 병렬처리가 가능한 경우 리듀스 태스크 수를 0으로 해도 된다.
- 컴바이너 함수
- 맵과 리듀스 태스크 사이의 데이터 전송을 최소화 하기위해 등장한 함수이다
- 컴바이너 함수의 출력이 결국 리듀스 함수의 입력이 된다.
- 예시 : 결과적으로 리듀스함수에서 max값을 집계해야하는 경우, 각각의 맵태스크 결과(맵태스크가 10개고 각태스크마다 결과값이 10개라면 총 100개의 데이터로우) 를 전부 보내서 리듀스 함수가 결과에서 max값을 집계하는 것보다, 맵태스크 자체에서 결과를 집계해서 그 결과만 리듀스 함수로 보내는것이 효율적일 것이다. 이때 맵태스크 내부 결과를 집계할 수 있는 것이 컴바이너 함수이다. (컴바이너를 적용하면 10개의 맵태스크가 있고, 각 태스크마다 결과값이 1개가 나올것이기때문에 리듀스 함수로 넘어가는 결과의 총 개수는 10개이다. 즉, 총 10개의 데이터가 네트워크를 타고 리듀서로 전송된다.)
- Reducer 클래스를 사용해서 정의한다. 즉, 리듀서 함수와 동일한 구현체를 사용한다. 차이점은 Job설정에 컴바이너 클래스를 추가로 지정해야 한다는 것 뿐이다.
2. HDFS 설계 특징
- 매우 큰 파일을 처리할 수 있게 설계되었다.
- 스트리밍 방식의 데이터 접근을 지원한다.
- 범용 하드웨어를 사용해서 구축할 수 있다. 비싼 하드웨어를 쓰지 않아도 된다.
- 빠른 데이터 응답 시간을 요구하는 일에 HDFS를 쓰는 것은 바람직하지 않다. (Hbase가 대안이 될 수 있다.)
- 수많은 작은 파일
- 네임노드는 파일 시스템의 메타데이터를 메모리에서 관리하기 때문에 저장할 수 있는 파일 수는 네임노드의 메모리 용량에 좌우된다. 경험상으로 파일, 디렉토리, 블록은 각각 150byte 정도의 메모리가 필요하다. 따라서 파일수가 백만개고 각 파일의 블록이 하나면 적어도 300mb의 메모리가 필요하다. 물론 수백만개의 파일은 괜찮겠지만 수십억 개의 파일은 하드웨어 용량을 넘어서게 된다. -> 네임노드를 확장할 수 있긴하다.
- 다중 라이터와 파일의 임의수정
- hdfs는 단일 라이터로 파일을 쓴다. 한번 쓰고 끝나거나 파일의 끝에 덧붙이는 것은 가능하지만 파일에서 임의 위치에 있는 내용을 수정하는 것은 허용하지 않으며 다중 라이터도 지원하지 않는다. (하둡 3.0부터는 다중 라이터를 지원한다.)
3. HDFS 개념
1) 블록
- 한번에 읽고 쓸 수 있는 데이터의 최대량
- 디스크 블록의 크기는 기본적으로 512byte. HDFS 의 블록은 기본적으로 128MB 이상.
- 블로크기가 128MB이고 저장할 데이터는 1MB인 경우 128MB의 디스크를 사용하는 것이 아니라 1MB의 디스크만 사용한다.
- 블록의 크기가 큰 이유 : 탐색비용을 줄이기 위해서. 블록의 크기가 크면 시작 지점을 찾는 탐색 비용을 줄일 수 있다.
- % hdfs fsck / -files -blocks : HDFS의 fsck 명령어로 블록을 관리할 수 있다. 이 명령어는 파일시스템에 있는 각 파일을 구성하는 블록의 목록이 출력된다.
2) 네임노드
- 파일 시스템의 네임스페이스 이미지( 파일시스템 트리와 그 트리에 포함된 모든 파일과 디렉터리에 대한 메타데이터 ) 와 에디트 로그 파일을 관리한다. 로컬디스크에 저장되어 있다.
- 파일에 속한 모든 블록인 어느 데이터노드에 있는지 파악하고 있다.
- 블록의 위치정보는 시스템이 시작할 때 모든 데이터노드로부터 받아서 재구성하기 때문에 디스크에 영속적으로 저장하지는 않는다.
3) 데이터노드
- 클라이언트나 네임노드의 요청이 있을 때 블록을 저장하고 탐색하며, 저장하고 있는 블록의 목록을 주기적으로 네임노드에 보고한다.
4) 네임노드의 장애복구
- 파일시스템의 메타데이터를 지속적인 상태로 보존하기 위해 파일로 백업.
- 보조네임노드를 운영한다.
- 에디트 로그가 너무 커지지 않도록 주기적으로 네임스페이스 이미지를 에디트 로그와 병합하여 새로운 네임스페이스 이미지를 만든다.
- 네임스페이스 이미지의 복제본을 보관한다.
- 대기 네임노드를 사용한다.
- 활성네임노드와 대기네임노드는 고가용성 공유 스토리지(NFS 필러 혹은 QJM) 반드시 사용해야한다.
- 대기 네임노드가 활성화되면, 먼저 기존 활성네임노드의 상태를 동기화 하기위해 공유 에디트 로그를 읽고 이어서 활성 네임노드에 새로 추가된 항목도 마저 읽는다.
- 데이터 노드는 블록 리포트를 두개의 네임노드에 보내야한다. 블록 매핑 정보는 디스크가 아닌 네임노드의 메모리에 보관되기 때문
- 클라이언트는 네임노드 장애를 사용자에게 투명한 방식으로 처리할 수 있도록 구성해야한다.
- 대기 네임노드는 보조 네임노드의 역할을 포함하고 있으며, 활성네임노드 네임스페이스의 체크포인트 작업을 주기적으로 수행한다.
반응형
'데이터 엔지니어 > Hadoop' 카테고리의 다른 글
[하둡 완벽 가이드] 하둡기초 (0) | 2020.06.01 |
---|