안녕하세요. 이것은 빙입니다. Hadoop Yarn에 대한 블로그 글을 쓰는 것을 도와드리겠습니다. 다음은 제가 작성한 내용입니다. 각 문단별로 소제목을 달았습니다. 내용을 확인하고 수정하거나 추가하시기 바랍니다.
Hadoop Yarn이란 무엇인가?
Hadoop Yarn은 Hadoop 2.0에서 도입된 새로운 클러스터 관리 시스템입니다. Yarn은 Yet Another Resource Negotiator의 약자로, Hadoop 클러스터의 자원을 효율적으로 할당하고 관리하는 역할을 합니다. Yarn은 Hadoop의 기존 맵리듀스 프레임워크와 분리되어, 다양한 종류의 분산 애플리케이션을 지원할 수 있습니다.
Hadoop 1.0의 구조와 YARN의 등장 이유
Hadoop 1.0의 MRV1(MapReduce Version1)는 작업의 처리와 자원의 관리를 한번에 관리하였다.
즉, Single-Master 노드에 해당하는 job Tracker는 자원을 할당하고, 스케줄링 작업도 수행하며 처리중인 작업까지 모니터링을 하였다. 그리고 하위 노드에 해당하는 Task Tracker에 Map and Reduce 작업을 부여하였고, 하위 노드들은 주기적으로 그들의 진행상황을 Job Tracker에 보고하였다.
이러한 MRV1구조는 Task의 규모가 커짐에 따라, 하나 뿐인 Job Tracker에 부하가 걸리며 bottleneck이 발생할 뿐만 아니라 컴퓨터의 자원이 비효율적으로 사용된다는 것을 알게 되었다. 그리고 이러한 문제를 해결하기 위해 Hadoop 2.0에서는 YARN(Yet Another Resource Negotiator)을 추가하였는데, 자원관리 및 작업 스케줄링에 대한 책임을 Yarn에 인수하여 MapReduce이 경량화되었으며, MapReduce 이외의 작업을 Hadoop이 처리할 수 있게 해주었다.
Hadoop Yarn의 구성 요소
이렇게 MapReduce의 클러스터 구성 기능이 YARN으로 재 정의하면서 MapReduce의 구현도 변경되어야 했습니다. MapReduce는 컴퓨팅을 위한 프로그램만 제공하고 클러스터의 리소스 관리, 장애 관리 등은 YARN에 의해 관리되도록 변경되었습니다.
리소스 매니저(Resource Manager)
- 클러스터 전체의 자원을 관리하고, 애플리케이션의 요청에 따라 자원을 할당하는 중앙 집중식 컴포넌트입니다. 리소스 매니저는 스케줄러(Scheduler)와 애플리케이션 매니저(Application Manager)라는 두 가지 서브 컴포넌트로 구성됩니다.
- YARN 클러스터의 Master 서버로 하나 또는 이중화를 위해 두개의 서버에만 실행됨
- 클러스터 전체의 리소스를 관리
- YARN 클러스터의 리소스를 사용하고자 하는 다른 플랫롬으로부터 요청을 받아 리소스 할당(스케줄링)
- Resource Manager는 Resource Allocation에 대한 최상위 권위자로, 어디에 자원을 할당할지 결정하여 Cluster들의 활용을 최적화시킨다. 또한 일에 대한 처리 요청을 받으면, Request들의 일부를 해당하는 Node Manager로 전달한다. 이러한 역할을 수행하는 Resource Manager는 크게 2가지로 구성되는데, Scheduler와 Applications Manager이다.
1) Scheduler
Scheduler는 Capacities(용량), Queue(대기줄) 등의 제한조건에 따라 실행중인 다양한 Applications들에 자원을 할당한다. Resource Manager의 Scheduler는 Application의 상태를 추적하거나 모니터링하지 않는, 순수한 Scheduler이다. 또한 순수한 스케줄러이기 때문에 Hardware failures나 Application failures에 의한 재시작 역시 보장하지 않으며, Application들의 자원 요구에 기반하여 Scheduling 기능을 수행한다. 이것은 메모리, CPU, 디스크, 네트워크와 같은 요소들을 포함하는 (resource) Container를 기반으로 작동한다.
또한 Scheduler는 Plug-in Policy를 사용하는데, 현재는 Capacity Scheduler와 Fair Scheduler를 플러그인으로 사용한다. Capacity Scheduler는 Larger Cluster를 여러 사용자가 함께 사용하는 Multi-tenancy를 구현하여 할당된 용량의 제한하에 적시에 Application들에 응용을 할당할 수 있게 해준다. Fair Scheduler는 YARN으로 하여금 Larger Cluster들이 공평하게 자원을 공유할 수 있게 해준다.
2) Applications Manager
Applications Manager는 Job의 제출을 수락하고, Application Master를 실행하기 위한 첫번째 컨테이너를 설정하고 실패 시 Application Master의 Container를 재시작하게 해준다. Application Master는 Scheduler를 통해 적합한 Container를 선정하고, 그것을 Tracking하고 진행 상황을 모니터링하는 역할을 수행한다.
노드 매니저(Node Manager)
- 각 노드에서 실행되는 에이전트로, 리소스 매니저와 통신하면서 노드의 자원 상태를 보고하고, 할당된 자원에 따라 컨테이너(Container)를 생성하고 관리하는 역할을 합니다. 컨테이너는 애플리케이션의 실행 단위로, CPU, 메모리, 디스크, 네트워크 등의 자원을 포함합니다.
- YARN 클러스터의 Worker 서버로 ResourceManager를 제외한 모든 서버에 실행
- 사용자가 요청한 프로그램을 실행하는 Container를 fork 시키고 Container를 모니터링 Container 장애 상황 또는 Container가 요청한 리소스보다 많이 사용하고 있는지 감시(요청한 리소스보다 많이 사용하면 해당 Container를 kill 시킴)
- Node Manager는 개별 노드들을 관리하고 주어진 노드에서 사용자의 작업 및 Work Flow를 관리한다. Node Manger는 Resource Manager에 등록되며 노드의 상태를 판별하기 위한 heartbeats를 전송한다. 그 중에서 Node Manager의 가장 중요한 임무는 Resource Manager을 통해 할당받은 Container를 관리하는 것이다. Container의 자원 사용량을 감시하고, 이를 Resource Manager로 보내는데, 문제가 발생한 경우 Resource Manager로부터 Container를 Kill하라는 명령을 받아 수행하기도 한다.
이 두 종류의 서버는 외부로의 특별한 요청이 없으면 아무런 동작도 수행하지 않으며 NodeManager는 자신의 상태만 계속해서 ResourceManager로 보내고 ResourceManager 는 클러스터의 전체 리소스 상황에 대한 현황 관리만 수행합니다. 즉, YARN 자체만으로는 할 수 있는 것이 아무것도 없습니다. YARN을 사용하는 또 다른 무언가가 있어야 합니다. 이 또 다른 무언가에 해당하는 것이 MapReduce나 Spark 과 같은 분산 컴퓨팅 플랫폼이나 HBase 등과 같이 분산된 환경에서의 컴퓨팅 리소스(CPU, 메모리 등)가 필요한 클러스터 기반 시스템 들입니다
Application Master
- 개별적인 응용에서 필요로 하는 자원과 Job에 대한 lifecycle을 관리한다. 이것은 Node Manager와 함께 작동하며, 작업의 실행을 모니터링한다.
- Application단위로 존재하는 Application Master는 Resource Manager와 함께 자원을 협상하고, Task를 모니터링하고 실행하기 위해 Node Manager와 함께 작동한다.
- 여기서 말하는 Application은 프레임워크에 제출된 단일 작업을 의미하며, 각각의 단일 작업은 고유한 Application Master를 지니게 된다. Application Master는 클러스터에서 응용의 실행을 조정하고 오류를 관리한다. 또한 Node Manager와 함께 작동하여 Task를 실행시키고 모니터링하며 Resource Manger를 통해 자원을 협상한다. 자원을 협상한 후에는 Resource Manager로부터 적당한 Resource(conatiner)를 할당받고 그것들의 상태를 추적하고 모니터링한다. 한번 Application Master가 실행되면 주기적으로 Resource Manager에 heartbeats를 전송하여 상태를 확인시켜주고, 자원의 요구사항을 갱신한다.
YARN을 이용한 클러스터 자원 공유
이제 YARN의 구성과 MapReduce가 어떻게 YARN을 이용하는지 살펴 보았습니다. 이제 YARN을 만든 최초 요구사항인 서로 다른 컴퓨팅 플랫폼 간에 서버들의 리소스를 어떻게 공유하는지 감이 잡히시나요?
예를 들어 100대의 서버에 하나의 MapReduce 작업이 실행되고 있는 중에 Spark 작업 요청이 들어 왔습니다. YARN 이 없는 상황이라면 MapReduce 를 위해 서버 50대에 별도 클러스터를 구성하고 50대에 Spark 클러스터를 구성할 수 있습니다. 또는 100대 모두 MapReduce, Spark 클러스터를 구성할 수 있습니다. 두가지 경우 모두 문제가 될 수 있습니다.
- 50대, 50대 설치한 경우 특정 시점에 MapReduce 작업만 수행되고 Spark 작업이 수행되지 않으면 50대의 자원은 낭비
- 100대에 MapReduce, Spark 모두 설치한 경우 각 클러스터가 메모리를 모두 사용하도록 구성되면 두 작업이 동시에 수행되면 작업은 Fail 각 서버의 메모리를 50%씩 나누어 쓰게 구성하면 MapReduce 작업만 수행되거나 Spark 작업만 수행되면 자원 낭비
YARN이 있고 YARN내에서 리소스를 균등하게 사용할 수 있도록 스케줄링을 관리하는 기능이 있다면 다음과 같은 시나리오가 가능합니다.
- 100대에 YARN 만 설치
- MapReduce 작업 실행 시점에 100대의 서버에서 각 서버의 모든 자원을 활용하여 작업 실행
- 이 상태에서 Spark 작업을 실행하면 YARN은 50대의 서버에서 실행되던 MapReduce Task를 강제 종료시키고 Spark에 작업에 리소스를 할당
실제로는 이것보다는 조금 더 복잡한 방식으로 동작하지만 이해를 돕기 위해 시나리오를 만들어 봤습니다. 이렇게 동작하면 서로 다른 컴퓨팅 플랫폼에서 작업하는 작업들이 하나의 리소스 관리자에 의해 관리됨으로써 서버 리소스 낭비를 최소화할 수 있습니다. 이것이 YARN을 만든 목적이고 YARN의 최대 장점입니다.
이렇게 Resource를 유연하게 할당할 수 있도록 하는 기능이 YARN의 스케줄러인데 FIFO, Capacity, Fair 스케줄러를 제공하며 기본은 FIFO 입니다. FIFO를 사용할 경우 위와 같은 시나리오는 제한적으로 얻을 수 있습니다. 위와 같은 시나리오를 얻기 위해서는 Capacity, Fair를 사용하시면 됩니다.
Hadoop Yarn에서 애플리케이션 실행 절차
- 클라이언트가 리소스 매니저에게 애플리케이션 제출 요청을 보냅니다.
- 리소스 매니저는 애플리케이션 아이디를 생성하고, 애플리케이션 마스터(Application Master)를 실행할 노드를 선택합니다.
- 애플리케이션 마스터는 애플리케이션의 조정자로, 애플리케이션의 실행 상태를 모니터링하고, 필요한 자원을 요청하고, 컨테이너를 할당받아 애플리케이션 로직을 실행합니다.
- 애플리케이션 마스터는 스케줄러에게 자신의 자원 요구사항을 보내고, 스케줄러는 이를 바탕으로 컨테이너를 할당합니다.
- 애플리케이션 마스터는 할당받은 컨테이너에 대한 정보를 받고, 각 컨테이너에게 작업을 할당합니다.
- 각 컨테이너는 노드 매니저의 관리 하에 작업을 수행하고, 결과를 애플리케이션 마스터에게 보냅니다.
Hadoop Yarn의 장점
Hadoop Yarn은 Hadoop 1.x의 맵리듀스 프레임워크에 비해 다음과 같은 장점을 가집니다.
- 자원 관리와 작업 스케줄링을 분리하여, 더 유연하고 확장성 있는 아키텍처를 제공합니다. 리소스 매니저는 클러스터 전체의 자원을 효율적으로 관리하고, 애플리케이션 마스터는 애플리케이션 별로 자신의 로직을 수행할 수 있습니다.
- 맵리듀스 외에도 다양한 종류의 분산 애플리케이션을 지원합니다. 예를 들어, 스파크(Spark), 플링크(Flink), 스톰(Storm), 테즈(Tez) 등의 프레임워크를 Yarn 위에서 실행할 수 있습니다.
- 컨테이너라는 추상화 단위를 통해, 다양한 자원 요소(CPU, 메모리, 디스크, 네트워크 등)를 고려하여 자원을 할당할 수 있습니다. 또한, 노드 레이블(Node Label)이나 노드 속성(Node Attribute) 등의 기능을 통해, 특정 조건에 맞는 노드에만 자원을 할당할 수 있습니다.
- 리소스 예약 시스템(Reservation System)이라는 컴포넌트를 통해, 중요한 작업에 대해 자원을 미리 예약하고 보장받을 수 있습니다. 예약 시스템은 작업의 자원 프로파일과 시간 제약 조건을 고려하여 자원을 예약하고, 스케줄러에게 동적으로 지시하여 예약된 자원을 할당합니다.(^1^)
Hadoop Yarn의 단점
Hadoop Yarn은 많은 장점을 가지고 있지만, 다음과 같은 단점도 존재합니다.
- 복잡한 아키텍처와 컴포넌트로 인해, 구성과 관리가 어렵습니다. 예를 들어, 리소스 매니저와 애플리케이션 마스터 간의 통신 오버헤드가 발생하거나, 스케줄러의 정책과 파라미터를 적절하게 설정하는 것이 쉽지 않습니다.
- 맵리듀스와 호환성을 유지하기 위해, 맵리듀스 작업을 실행할 때에도 애플리케이션 마스터가 필요합니다. 이는 맵리듀스 작업에 대한 자원 낭비와 성능 저하를 초래할 수 있습니다.
- 다양한 종류의 애플리케이션을 지원하기 위해, 일반화된 인터페이스와 프로토콜을 사용합니다. 이는 특정 애플리케이션에 최
Source: Conversation with Bing, 2023. 3. 25.(1) Apache Hadoop 3.3.5 – Apache Hadoop YARN. https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html Accessed 2023. 3. 25..
(2) Apache Hadoop 3.3.5 – YARN Commands. https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YarnCommands.html Accessed 2023. 3. 25..
(3) What is Apache Hadoop YARN? | Definition from TechTarget. https://www.techtarget.com/searchdatamanagement/definition/Apache-Hadoop-YARN-Yet-Another-Resource-Negotiator Accessed 2023. 3. 25..
(4) What is Yarn in Hadoop | Architecture and Key Features of Yarn - EDUCBA. https://www.educba.com/what-is-yarn-in-hadoop/ Accessed 2023. 3. 25..
Hadoop Yarn의 활용 사례
Hadoop Yarn은 다양한 분야에서 활용될 수 있습니다. 예를 들어, 다음과 같은 사례들이 있습니다.
- 실시간 스트리밍 데이터 처리: 스파크 스트리밍(Spark Streaming)이나 플링크 스트리밍(Flink Streaming)과 같은 프레임워크를 Yarn 위에서 실행하여, 실시간으로 발생하는 대량의 데이터를 처리할 수 있습니다. 예를 들어, 웹 로그 분석, 사기 탐지, 센서 데이터 처리 등의 작업을 수행할 수 있습니다.
- 대화형 SQL 쿼리: 임팔라(Impala)나 프레스토(Presto)와 같은 프레임워크를 Yarn 위에서 실행하여, HDFS나 Hive에 저장된 데이터에 대해 대화형 SQL 쿼리를 수행할 수 있습니다. 예를 들어, 비즈니스 인텔리전스(BI)나 데이터 탐색 등의 작업을 수행할 수 있습니다.
- 머신러닝과 딥러닝: 테즈(Tez)나 스파크(Spark)와 같은 프레임워크를 Yarn 위에서 실행하여, 머신러닝과 딥러닝 알고리즘을 구현하고 실행할 수 있습니다. 예를 들어, 추천 시스템, 이미지 인식, 자연어 처리 등의 작업을 수행할 수 있습니다.
이 외에도 Yarn은 다양한 종류의 분산 애플리케이션을 지원하므로, 여러분의 목적에 맞게 활용할 수 있습니다.
Hadoop은 크게 두가지 컴포넌트로 구성되는데 하나는 파일을 저장할 수 있는 분산 파일 시스템인 HDFS(Hadoop Distributed File System)과 분산 컴퓨팅 환경을 제공하는 YARN(Yet Another Resource Negotiator) 입니다. Hadoop 을 처음 접하시는 분들은 HDFS에 대해서는 쉽게 이해하지만 YARN에 대해서는 개념을 잡기 어려워하시는 분들이 있습니다. 그 이유는 Hadoop하면 MapReduce를 많이 떠 올리시는데 MapReduce 따로 YARN 따로 있기 때문에 오는 혼선이 아닌가 생각합니다. 이 글에서는 YARN에 대한 간단한 개념 설명과 YARN에서 MapReduce를 사용하기 환경 설정은 어떻게 해야 하는지에 대해 살펴 보겠습니다.
YARN 과 MapReduce
Hadoop이 처음 나왔을 때에는 지금처럼 여러개의 서브 프로젝트로 구성되지 않았습니다. Hadoop 이라는 하나의 프로젝트 내에 hdfs와 mapreduce가 자바의 패키지로만 분리되어 있었습니다. 이런 구성에서 Hadoop이 많은 곳에 사용되어지고 하나의 클러스터가 수천대 이상으로 구성되면서 다음과 같은 추가 요구사항이 발생하게 됩니다.
- 하나의 Hadoop 클러스터는 다수의 서버로 구성되어 많은 컴퓨팅 리소스를 가지고 있는데 이것을 하나의 컴퓨팅 플랫폼(MapReduce) 에만 할당하는 것은 비효율적이다.
- MapReduce 이외에 Spark, Strom 등과 같은 다른 컴퓨팅 플랫폼이 출현하였고 이들을 사용하고자 하는 요구사항도 늘어 났음
- 여러 개의 컴퓨팅 플랫폼을 동시에 실행할 경우 각 서버의 리소스(주로 메모리)가 부족하여 정상적으로 수행되던 작업들이 다른 작업에 의해 문제가 발생하게 된다.
- MapReduce 이외에 다른 클러스터를 구성할 경우 클러스터 전체의 사용 효율이 떨어지는 경우가 많음
이런 요구사항을 해결하기 위해 Hadoop 프로젝트에서는 YARN이라는 새로운 서브 프로젝트를 만들게 되었습니다.
전통적인 MapReduce 시스템 구성
YARN에 대해 설명하기 전에 먼저 MapReduce에 대해 먼저 설명 드리겠습니다. MapReduce는 개념적으로 보면 크게 다음 세 부분으로 분리할 수 있습니다.
- MapReduce라는 프로그램 모델을 추상화시킨 라이브러리
- Mapper, Reducer 등 클래스로 별도 main() 메소드로 제공되는 클래스는 없음
- 분산된 서버에 사용자가 만든 MapReduce 프로그램을 실행시키는 Runtime 환경
- JobTracker, TaskTracker, TaskRunner 등과 같이 분산된 서버에 클러스터 환경을 구성
- 사용자의 MapReduce 프로그램을 이들 환경에서 실행시키고, 서버 장애 발생 시 수행되던 작업을 다른 서버에 재시작 시키는 등의 역할을 수행
- MapReduce 프로그램을 위한 중간 단계 데이터의 이동(Shuffle), 이동된 데이터의 정렬(Sort) 등의 작업을 수행
- MapReduce runtime 환경에 사용자가 만든 프로그램의 실행을 지원하는 라이브러리
- JobClient, JobConf 등 클래스과 유틸리티 클래스
- 사용자가 만든 main() 내에서 JobTracker로 작업을 실행하게 요청하거나 작업의 상태 정보 등을 확인하기 위한 유틸리티 클래스
이런 구성에서 MapReduce는 다음과 같은 절차로 프로그램이 실행되었습니다.
- MapReduce 클러스터 실행
한번 실행된 클러스터는 특별한 문제가 없으면 재시작 되지 않으며 여러 MapReduce 작업이 실행되어 있는 클러스터를 이용
- 사용자가 Mapper, Reducer 클래스를 개발
- MapReduce 작업에서 사용하는 Mapper Reducer 클래스에 대한 지정(1번에서 만든), 입력, 출력 디렉토리 설정, 작업 관련 다양한 옵션을 지정하는 Driver 프로그램 개발(Driver 프로그램이 자바의 main() 메소드를 가지고 있음)
- 사용자가 만든 Driver 프로그램 실행
Hadoop에서 제공해주는 명령어인 bin/mapred 명령어는 클래스패스 등을 설정해주는 부가 기능만 제공하며 실제 메인 클래스는 사용자가 만든 Driver 클래스
- Driver 프로그램 내에서는 Job 클래스를 이용하여 JobTracker에 작업 실행 요청
- JobTracker는 해당 작업의 환경 설정 정보와 입력 데이터의 HDFS 서버의 위치, TaskTracker의 상태 정보를 이용하여 작업 스케줄링
- TaskTracker는 자신에게 할당된 Task를 JobTracker에서 가져와 실행
- TaskTracker가 Task 실행 시 TaskTrasker의 쓰레드로 실행하지 않고 별도의 프로세스로 fork 시켜서 실행
Fork 시에는 main() 메소드를 포함하고 있는 클래스가 있어야 하는데 이때 사용되는 클래스가 MapRunner, ReduceRunner로 별도의 프로세스로 실행된 후 입력 데이터를 읽어 사용자가 개발한 map(), reduce() 함수를 호출해준다(MapReduce가 계속 변화되었기 때문에 MapRunner, ReduceRunner라는 클래스명은 정확하지 않을 수 있습니다.).
- Reduce는 Map 결과를 받기 위해 각가의 TaskTrasker로 Map Task의 결과 정보를 요청하여 이 데이터를 로컬 파일로 저장
- Reduce Task는 로컬에 저장된 Map 결과를 정렬한 후 reduce() 함수 실행
- 각 Task 가 종료될 때 마다 TaskTrakcer는 다음 Task를 JobTraker로 부터 가져와서 실행
- JobTracker는 특정 서버(TaskTracker) 장애시 또는 특정 Task 장애시 재 스케줄링 수행
YARN 이전에는 MapReduce 클러스터 내에서 이 기능이 모두 수행되었습니다. 따라서 Hadoop 클러스터의 서버에서 컴퓨팅에 필요한 리소스 상태(각 서버의 상태)는 MapReduce의 Master 서버 역할을 수행하는 JobTracker에 의해 관리되었습니다. 이렇게 JobTracker에 의해 리소스가 관리되기 때문에 Hadoop이 설치된 클러스터 서버들의 리소스를 사용하고자 하는 다른 컴퓨팅 클러스터와는 연동하기 어려운 문제가 있었습니다.
이 문제를 해결하기 위해 나온 것이 YARN이며 YARN은 기존 MapReduce 중에서 클러스터의 리소스를 관리하는 부분만 가져와서 다른 서비스에서도 사용 가능하도로 구성한 시스템입니다. 따라서 YARN 시스템은 기존 MapReduce 보다는 기능적으로는 간단하지만 범용적인 분산 리소스 관리 시스템이 되어야 했기 때문에 MapReduce의 클러스터 관리 체계 보다 더 복잡하고 다양한 기능을 제공하고 있습니다.
YARN에서 MapReduce 동작
YARN의 실제 동작 방식을 이해하기 위해서는 MapReduce가 YARN에서 어떻게 동작하는지를 이해하는 것이 가장 좋은 방법입니다. MapReduce가 최초로 YARN을 사용하는 시스템이었으며, 같은 Hadoop 프로젝트내에 엮여있기 때문에 가장 YARN을 가장 잘 사용하는 시스템이라고 할 수 있습니다. 다음은 YARN 기반에서 MapReduce 프로그램이 어떻게 동작하는지에 대한 설명입니다.
- 기존 MapReduce 프로그램과 동일하게 Mapper, Reducer, Driver 클래스 작성
- Driver 클래스 실행
main 프로그램이기 때문에 bin/mapred 명령어를 이용하여 실행
- Driver 클래스내에서 Job 클래스를 이용하여 MapReduce작업을 요청하는 것이 아니라 MapReduce 클러스터를 구성하는 작업을 먼저 수행
기존 MapReduce는 한번 구성된 클러스터를 영구적으로 사용하지만 YARN 환경에서는 Job 별로 클러스터를 구성
- MapReduce 클러스터를 구성하기 위해서는 기존의 JobTracker 역할을 수행하는 Master가 필요 이를 위해 YARN의 ResourceManager에게 리소스 요청
YARN에서는 각각의 컴퓨팅 클러스터를 Application이라고 하며 Application을 실행하기 위해 필요한 Master 서버를 ApplicationMaster 라고 한다. 따라서 기존의 JobTracker는 YARN 입장에서 보면 MapReduce 프로그램을 실행하기 위한 ApplicationMaster가 된다.
MapReduce의 Driver 프로그램은 내부적으로 MapReduce 클러스터 구성을 위해 ApplicationMaster를 먼저 요청한다. ApplicationMaster는 보통 1개로 구성되기 때문에 1개만 요청한다.
- YARN의 ResourceManager는 요청받은 ApplicationMaster를 자신이 관리하는 클러스터(여러개의 NodeManager) 중 하나의 서버를 선택하여 ApplicationMaster(JobTracker 역할)를 실행하고 이 서버를 클라이언트에게 알려준다.
ApplicationMaster는 각 컴퓨팅 플랫폼별로 다른데 MapReduce에 사용되는 ApplicationMaster는 MRAppMaster 이며 YARN 패키지가 아닌 MapReduce 패키지내에 존재한다.
- 클라이언트는 ResourceManager로 부터 받은 ApplicationMaster 서버에 MapReduce 작업 요청을 한다.
- MRAppMaster는 작업 요청을 받으면 사용자가 실행한 MapReduce 작업에 필요한 리소스를 다시 ResourceManager에게 요청한다.
- ResourceManager는 요청받은 리소스에 대해 NodeManager를 지정하고 Container를 실행한 후 Container 목록을 MRAppMaster에 준다.
- NodeManager에 의해 실행된 MapReduce Task를 위한 Container는 MRAppMaster와 통신을 하며 기존 방식의 JobTracker/TaskTracker에서 처리했던 방식과 유사한 방법으로 Task를 실행한다.
이 과정에서 MRAppMaster의 재활용, Task를 위해 실행된 Container의 재활용 등은 MapReduce와 YARN의 버전업에 따라 처리 방식이 조금씩 다르다.
버전에 따라 조금 다르고 제가 잘못알고 있는 부분도 있겠지만 큰 틀에서는 위와 같은 방식으로 동작합니다.
기존 JobTracker/TaskTracker 방식에 비해 더 복잡해지고 관리해야할 포인트도 더 많아졌습니다. 이것은 다른 플랫폼에서도 서버의 리소스를 공유하기 위해서는 어쩔수 없는 방식이라 생각합니다. 구성을 잘 보면 크게 달라진 것은 없습니다. MapReduce 작업을 위한 클러스터가 항상 실행되어 있지 않기 때문에 작업을 실행하기 전에 클러스터를 구성하는 단계가 추가 되었을 뿐입니다.
YARN에서 MapReduce를 위한 환경 설정
YARN에 작업을 실행시키기 위한 환경 설정은 처음 접하는 사용자에게는 쉽지 않습니다. 그 이유는 위에서 설명한 작업의 처리 흐름에 대한 개념과 리소스의 할당에 대한 개념때문입니다. 환경 설정을 가장 쉽게 이해하는 방법 중 하나는 YARN에서 MapReduce의 환경 설정을 이해하는 것입니다. MapReduce의 YARN 환경 설정은 다음과 같습니다.
yarn-site.xml
Shuffle 관련 설정: YARN 기반인 경우 NodeManager에 Task만 실행되고 중지되어 버리기 때문에 MapTask의 결과가 ReduceTask로 전달되기 위해서는 ReduceTask로부터의 Map 결과 데이터 전송 요청에 응답해서 데이터를 전송하는 데몬이 필요합니다. YARN에서는 이런 종류의 데몬을 위해 각 Application(JOB)별로 각 NodeManager에 하나씩 지정한 프로그램을 실행하는 기능을 제공하는데, 이런 서비스를 auxiliary service 라고 부릅니다.
아래 설정은 기본 설정 값으로 되어 있기 때문에 별도 설정은 필요 없지만 이와 유사한 서비스가 필요한 경우 아래와 같이 설정할 수 있습니다.
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property>
각 NodeManager는 Container 할당에 사용할 메모리 사이즈를 지정해야 합니다. 여기서 설정된 값은 컴퓨팅을 위해 할당된 메모리 이상으로 설정하지 않습니다. 예를 들어 장비의 메모리가 16GB이면 16GB 모두 할당하지 않고 12GB ~ 14GB 정도 할당합니다. 이유는 OS 자체 사용하는 메모리와 DataNode 등과 같은 다른 프로세스에서 사용하는 메모리를 고려해야 하기 때문입니다.
<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>8000</value> </property>
다음은 하나의 container에 할당할 수 있는 메모리 min/max 값을 설정합니다. 작업 요청 시 여기서 설정된 크기보다 작거나 큰 Container 할당 요청을 하면 에러가 발생하게 됩니다.
<property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>512</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>2048</value> </property>
YARN으로 실행 시 JobTracker가 없기 때문에 MR Job이 종료된 이후에도 작업 실행 정보와 로그 정보를 보기 위해서는 MR History Server를 실행해야 합니다. 이 서버를 실행한다고 해도 작업 목록이 보이지 않는데 다음과 같이 log aggregation 옵션을 true로 해야 합니다.
<property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property>
mapred-site.xml
JobTracker, TaskTracker는 없어졌지만 JobClient가 사용하는 환경설정을 해야 하는데 기존과 동일하게 mapred-site.xml 파일에 설정합니다.
처음 테스트 환경에 설치했을 때 가장 많은 어려움을 겪는 설정인데 Application Master에 대한 Container의 메모리 설정입니다. 기본값이 1536으로 1.5GB입니다. 이 설정 값과 “yarn.scheduler.maximum-allocation-mb” 설정이 맞지 않으면 다음과 같은 에러 메시지가 나타납니다.
Invalid resource request, requested memory < 0, or requested memory > max configured, requestedMemory=1536, maxMemory=512
이 메시지에서 requestedMemory의 의미는 MR Job을 위한 Application Master Container를 위한 메모리이고 maxMemory는 yarn.scheduler.maximum-allocation-mb 값입니다. 즉 yarn.app.mapreduce.am.resource.mb 설정 값은 반드시 yarn.scheduler.maximum-allocation-mb 값보다는 작아야 합니다. 1.5GB는 수백대 클러스터 규모에서는 다소 크기 때문에 저는 1GB 또는 그 이하로 할당을 합니다.
<property> <name>yarn.app.mapreduce.am.resource.mb</name> <value>512</value> </property>
기본 설정 값에서 Map/Reduce Task는 각각 1GB의 Container를 요청합니다. 작업에 따라 이 값이 너무 클수도 있고, 작을 수도 있는데 다음 설정 값으로 변경할 수 있습니다.
<property> <name>mapreduce.map.memory.mb</name> <value>512</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>512</value> </property>
테스트 환경에서는 메모리 크기가 크지 않기 때문에 메모리 사이즈 설정을 잘해야 하는데 가장 간단한 MapReduce를 실행하기 위해서는 Container 3개가 필요합니다. NodeManager의 yarn.nodemanager.resource.memory-mb 설정 값의 합이 yarn.app.mapreduce.am.resource.mb, mapreduce.map.memory.mb, mapreduce.reduce.memory.mb의 합보다 커야 합니다.
메모리 설정을 정확하게 잘 한 경우에도 작업 실행 중에 다음과 같은 에러 메시지를 볼 수 있습니다.
Current usage: 700 MB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.
주로 여기서 멘붕을 많이 겪으시는데 이 메시지의 의미는 할당된 다음과 같습니다.
- Container 는 1GB 까지 사용 가능한데 실제로는 700 MB 사용 있음. 여기는 문제가 안됨
- YARN은 Physical 메모리 뿐만 아니라 Virtual Memory 사용도 체크하는데 Virtual Memory의 제한 값은 Container 메모리 사이즈의 2.1 배이다. 따라서 위 메시지는 1GB Container는 2.1GB 까지 사용 가능한데 2.2GB 사용했기 때문에 이를 초과해서 발생한 문제이다.
위 문제를 해결하기 위해서는 두가지 방법이 있습니다. 첫번째는 다음 옵션을 통해 virtual memory 체크를 disable 하거나 rate 값을 더 크게 할 수 있습니다.
<property> <name>yarn.nodemanager.vmem-check-enable</name> <value>false</value> </property> <property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>2.1</value> </property>
virtual memory 설정은 disable 할 경우 어떤 문제가 발생하는지데 대해서는 아직 확인을 하지 못했습니다. 실제로 Virtual memory를 많이 사용한다고 해서 문제되는 것은 없다고 봅니다. Hadoop 개발자 커뮤니티 내에서도 default 값으로 disable 시키거나 ratio를 더 크게 하자는 주장도 있는 것으로 봐서 disable 해도 크게 문제될 것 같지는 않습니다. 다음 JIRA 이슈를 참고하세요.
두 번째 방법은 Map, Reduce Task의 Heap을 조절하는 방법입니다. Map, Reduce Task가 fork 될때 mapreduce.map.java.opts, mapreduce.reduce.java.opts 이 두 옵션 값에 설정된 정보를 이용하여 JVM을 실행합니다. 이 설정에 -Xmx 값을 mapreduce.map.memory.mb, mapreduce.reduce.memory.mb 에 설정된 값의 70 ~ 80% 정도만 설정합니다. 이 설정은 ApplicationMaster를 위한 Container에도 동일합니다.
<property> <name>yarn.app.mapreduce.am.resource.mb</name> <value>1024</value> </property> <property> <name>yarn.app.mapreduce.am.command-opts</name> <value>-Xmx768m</value> </property> <property> <name>mapreduce.map.memory.mb</name> <value>1024</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>1024</value> </property> <property> <name>mapreduce.map.java.opts</name> <value>-Xmx768m</value> </property> <property> <name>mapreduce.reduce.java.opts</name> <value>-Xmx768m</value> </property>
글을 마치며
지금까지 YARN이 왜 만들어 졌으며 MapReduce와의 관계, 간단한 동작 방식 등에 대해서 살펴 보았습니다. 최근에는 다양한 컴퓨팅 플랫폼이 등장하고 있으며 실제 서비스에도 하나 이상의 플랫폼을 사용하는 경우도 많이 있습니다. 이런 경우 현재까지는 YARN이 이들 컴퓨팅을 같은 서버에서 자원을 효과적으로 사용하는 요구사항에는 가장 앞서 있는 솔루션이라 할 수 있습니다. 국내에서 개발되는 오픈소스나 솔루션들도 YARN을 지원하는 솔루션이 늘어 났으면 하는 바램입니다.