YARN Scheduler Load Simulator
YARN Scheduler Load Simulator (SLS)
단일 머신에서 대규모 YARN 클러스터와 애플리케이션 부하를 시뮬레이션하는 YARN Scheduler Load Simulator (SLS) 를 설명하는 문서예요. 아키텍처, 사용법, 메트릭, 합성 부하 생성기, 입력 파일 형식을 다룹니다.
출처: 문서
본문
개요 (Overview)
개요
YARN 스케줄러는 Fifo, Capacity, Fair 스케줄러 같은 서로 다른 구현들이 있는 관심 영역입니다. 한편 다양한 시나리오와 워크로드에 대한 스케줄러 성능을 개선하려는 여러 최적화도 이루어져요. 각 스케줄러 알고리즘은 고유한 기능 집합을 가지며, 공정성, 용량 보장, 자원 가용성 등 여러 요인으로 스케줄링 결정을 이끕니다. 프로덕션 클러스터에 배포하기 전에 스케줄러 알고리즘을 잘 평가하는 것이 매우 중요합니다. 불행히도 현재 스케줄러 알고리즘을 평가하는 것은 사소하지 않아요. 실제 클러스터에서 평가하는 것은 항상 시간과 비용이 들고, 충분히 큰 클러스터를 찾기도 어렵습니다. 따라서 특정 워크로드에 스케줄러 알고리즘이 얼마나 잘 동작하는지 예측할 수 있는 시뮬레이터가 매우 유용할 것입니다.
YARN Scheduler Load Simulator(SLS)는 그러한 도구로, 단일 머신에서 대규모 YARN 클러스터와 애플리케이션 부하를 시뮬레이션할 수 있습니다. 이 시뮬레이터는 연구자와 개발자에게 새 스케줄러 기능을 프로토타입하고 비교적 높은 신뢰도로 동작과 성능을 예측할 도구를 제공해 YARN 발전에 매우 귀중할 것입니다. 시뮬레이터는 실제 YARN ResourceManager를 실행하며, 같은 JVM 안에서 NM/AM 하트비트 이벤트를 처리·파견해 NodeManagers와 ApplicationMasters를 시뮬레이션함으로써 네트워크 요인을 제거합니다. 스케줄러 동작과 성능을 계속 추적하기 위해 스케줄러 래퍼가 실제 스케줄러를 감쌉니다.
클러스터 크기와 애플리케이션 부하는 Apache Rumen을 채택해 작업 기록 파일에서 직접 생성한 구성 파일에서 로드할 수 있습니다.
시뮬레이터는 실행 중 실시간 메트릭을 생성합니다.
- 클러스터와 각 큐의 자원 사용. 클러스터·큐 용량을 구성하는 데 활용할 수 있어요.
- 상세 애플리케이션 실행 트레이스(시뮬레이션 시간 기준으로 기록). 스케줄러 동작을 이해·검증하는 데 분석할 수 있음(개별 작업 턴어라운드 시간, 처리량, 공정성, 용량 보장 등).
- 각 스케줄러 연산(allocate, handle 등)의 시간 비용 같은 스케줄러 알고리즘의 몇 가지 핵심 메트릭. Hadoop 개발자가 코드 지점과 확장성 한계를 찾는 데 활용할 수 있음.
목표 (Goals)
- 실제 클러스터 없이 실제 작업 트레이스를 사용해 스케줄러를 대규모로 실행합니다.
- 실제 워크로드를 시뮬레이션할 수 있어야 합니다.
아키텍처 (Architecture)
다음 그림은 시뮬레이터의 구현 아키텍처를 보여줍니다.
시뮬레이터는 워크로드 트레이스나 합성 부하 분포를 입력받아 클러스터와 애플리케이션 정보를 생성합니다. 각 NM과 AM에 대해 시뮬레이터는 실행을 시뮬레이션하는 시뮬레이터를 만듭니다. 모든 NM/AM 시뮬레이터는 스레드 풀에서 실행됩니다. 시뮬레이터는 YARN Resource Manager를 재사용하고 스케줄러 외부에 래퍼를 만듭니다. Scheduler Wrapper는 스케줄러 동작을 추적하고 시뮬레이터의 출력이며 더 분석될 수 있는 여러 로그를 생성합니다.
사용 사례 (Usecases)
- 엔지니어링 (Engineering)
- 부하 하에서 스케줄러 알고리즘의 정확성 검증
- 코드 핫스팟/임계 경로를 찾는 저렴하고 실용적인 방법
- 변경과 새 기능의 영향 검증
- 스케줄러 확장성 한계의 원인 파악
- QA
- "대규모" 클러스터와 여러 워크로드 프로파일에서 스케줄러 동작 검증
- 솔루션/영업 (Solutions/Sales)
- 사전 정의/일반 워크로드용 사이징 모델
- 실제 고객 데이터(작업 트레이스)를 사용한 클러스터 사이징 도구
- 특정 워크로드에서 최소 SLA 결정
사용법 (Usage)
이 절은 시뮬레이터 사용법을 보여줍니다. 여기서 $HADOOP_ROOT가 Hadoop 설치 디렉터리라고 합시다. Hadoop을 직접 빌드했다면 $HADOOP_ROOT는 hadoop-dist/target/hadoop-$VERSION입니다. 시뮬레이터는 $HADOOP_ROOT/share/hadoop/tools/sls에 있습니다. sls 폴더는 bin, html, sample-conf, sample-data의 네 개 디렉터리를 담습니다.
bin: 시뮬레이터 실행 스크립트.html: 사용자는 실시간 추적 차트를 오프라인 모드로 재현할 수도 있습니다.realtimetrack.json을$HADOOP_ROOT/share/hadoop/tools/sls/html/showSimulationTrace.html에 업로드하면 돼요. 브라우저 보안 문제로realtimetrack.json과showSimulationTrace.html파일을 같은 디렉터리에 두어야 합니다.sample-conf: 시뮬레이터 구성을 지정.sample-data: 시뮬레이터 입력 생성에 사용할 수 있는 예시 rumen trace를 제공.
다음 절은 시뮬레이터 사용법을 단계별로 설명합니다. 시작 전에 hadoop 명령이 $PATH 환경 파라미터에 포함되어 있는지 확인하세요.
Step 1: Hadoop과 시뮬레이터 구성
시작 전에 Hadoop과 시뮬레이터가 잘 구성됐는지 확인하세요. Hadoop과 시뮬레이터의 모든 구성 파일은 ResourceManager와 YARN 스케줄러가 구성을 로드하는 디렉터리 $HADOOP_ROOT/etc/hadoop에 배치해야 합니다. 디렉터리 $HADOOP_ROOT/share/hadoop/tools/sls/sample-conf/는 데모 시작에 사용할 수 있는 몇 가지 예시 구성을 제공합니다.
Hadoop과 YARN 스케줄러 구성은 YARN 웹사이트(http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/)를 참고하세요.
시뮬레이터는 파일 $HADOOP_ROOT/etc/hadoop/sls-runner.xml에서 구성 정보를 로드합니다.
여기서 각 구성 파라미터를 설명합니다. $HADOOP_ROOT/share/hadoop/tools/sls/sample-conf/sls-runner.xml은 이 구성 파라미터들의 모든 기본값을 포함합니다.
yarn.sls.runner.pool.size— 시뮬레이터는NM과AM실행을 시뮬레이션하기 위해 스레드 풀을 사용하며, 이 파라미터는 풀의 스레드 수를 지정.yarn.sls.nm.memory.mb— 각NMSimulator의 총 메모리.yarn.sls.nm.vcores— 각NMSimulator의 총 vCores.yarn.sls.nm.heartbeat.interval.ms— 각NMSimulator의 하트비트 간격.yarn.sls.am.heartbeat.interval.ms— 각AMSimulator의 하트비트 간격.yarn.sls.am.type.mapreduce— MapReduce류 애플리케이션의AMSimulator구현. 다른 유형의 애플리케이션 구현도 지정할 수 있음.yarn.sls.container.memory.mb— 각 컨테이너 시뮬레이터에 필요한 메모리.yarn.sls.container.vcores— 각 컨테이너 시뮬레이터에 필요한 vCores.yarn.sls.runner.metrics.switch— 시뮬레이터는 핵심 구성 요소·연산의 동작을 측정하기 위해 Metrics를 도입. 이 필드는 Metrics 실행을 열지(ON) 닫을지(OFF) 지정.yarn.sls.metrics.web.address.port— 시뮬레이터가 실시간 추적을 제공하는 데 사용하는 포트. 기본값 10001.org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler— Fifo Scheduler의 스케줄러 메트릭 구현.org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler— Fair Scheduler의 스케줄러 메트릭 구현.org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler— Capacity Scheduler의 스케줄러 메트릭 구현.
Step 2: 시뮬레이터 실행
시뮬레이터는 rumen 트레이스와 자체 입력 트레이스의 두 가지 입력 파일 유형을 지원합니다. 시뮬레이터 시작 스크립트는 slsrun.sh입니다.
$ cd $HADOOP_ROOT/share/hadoop/tools/sls
$ bin/slsrun.sh
Usage: slsrun.sh <OPTIONS>
--tracetype=<SYNTH | SLS | RUMEN>
--tracelocation=<FILE1,FILE2,...>
(deprecated --input-rumen=<FILE1,FILE2,...> | --input-sls=<FILE1,FILE2,...>)
--output-dir=<SLS_SIMULATION_OUTPUT_DIRECTORY>
[--nodes=<SLS_NODES_FILE>]
[--track-jobs=<JOBID1,JOBID2,...>]
[--print-simulation]
--input-rumen: 입력 rumen 트레이스 파일. 쉼표로 구분해 여러 파일을 입력할 수 있음. 예시 트레이스가$HADOOP_ROOT/share/hadoop/tools/sls/sample-data/2jobs2min-rumen-jh.json에 제공됨.--tracetype=RUMEN --tracelocation=<path_to_trace>와 동일.--input-sls: 시뮬레이터 자체 파일 형식. 시뮬레이터는 rumen 트레이스를 sls 트레이스로 변환하는 도구(rumen2sls.sh)도 제공. sls 입력 json 파일 예시는 부록 참고.--tracetype=SLS --tracelocation=<path_to_trace>와 동일.--tracetype: 트레이스 생성을 구성하는 새 방법. RUMEN, SLS, SYNTH 값을 취해 세 가지 유형의 부하 생성을 트리거.--tracelocation: 위 tracetype과 일치하는 입력 파일 경로.--output-dir: 생성된 실행 로그와 메트릭용 출력 디렉터리.--nodes: 클러스터 토폴로지. 기본적으로 시뮬레이터는 입력 json 파일에서 가져온 토폴로지를 사용. 이 파라미터로 새 토폴로지를 지정할 수 있음. 토폴로지 파일 형식은 부록 참고.--track-jobs: 시뮬레이터 실행 중 추적할 특정 작업, 쉼표로 구분.--print-simulation: 시뮬레이터 실행 전에 시뮬레이션 정보(노드 수, 애플리케이션, 작업 수, 각 애플리케이션 정보)를 출력할지 여부.
rumen 형식과 비교해 sls 형식은 훨씬 단순하고 사용자가 다양한 워크로드를 쉽게 생성할 수 있습니다. 시뮬레이터는 rumen 트레이스를 sls 트레이스로 변환하는 도구도 제공합니다.
$ bin/rumen2sls.sh
--rumen-file=<RUMEN_FILE>
--output-dir=<SLS_OUTPUT_DIRECTORY>
[--output-prefix=<SLS_FILE_PREFIX>]
--rumen-file: rumen 형식 파일. 예시 트레이스가sample-data디렉터리에 제공됨.--output-dir: 시뮬레이션 트레이스 출력 디렉터리. 모든 작업·작업 정보를 포함한 트레이스 파일 하나와 토폴로지 정보를 보여주는 파일 하나의 두 파일이 생성됨.--output-prefix: 생성 파일의 접두어. 기본값 "sls", 두 생성 파일은sls-jobs.json과sls-nodes.json.
메트릭 (Metrics)
YARN Scheduler Load Simulator는 실행 중 애플리케이션·컨테이너, 클러스터 가용 자원, 스케줄러 연산 시간 비용 등을 포함한 핵심 구성 요소·연산의 동작을 측정하기 위해 Metrics를 통합했습니다. yarn.sls.runner.metrics.switch가 ON으로 설정되면 Metrics가 실행되고 사용자가 지정한 --output-dir 디렉터리에 로그를 출력합니다. 사용자는 시뮬레이터 실행 중 이 정보를 추적하고, 실행 후 로그를 분석해 스케줄러 성능을 평가할 수 있어요.
실시간 추적 (Real-time Tracking)
시뮬레이터는 실시간 실행 추적 인터페이스를 제공합니다. 사용자는 http://host:port/simulate로 전체 실행을, http://host:port/track으로 특정 작업이나 큐를 추적할 수 있습니다. 여기서 host는 시뮬레이터를 실행한 곳이고 port는 yarn.sls.metrics.web.address.port가 구성한 값(기본 10001)입니다.
웹페이지에 보이는 각 차트를 설명합니다.
- 첫 번째 그림: 실행 중 애플리케이션 수와 컨테이너 수.
- 두 번째 그림: 클러스터의 할당·가용 자원(메모리).
- 세 번째 그림: 각 큐의 할당 자원. 여기에는 sls_queue_1, sls_queue_2, sls_queue_3의 세 큐가 있습니다. 처음 두 큐는 25% share, 마지막 큐는 50% share로 구성됩니다.
- 네 번째 그림: 각 스케줄러 연산의 시간 비용.
- 마지막으로 시뮬레이터가 사용하는 메모리 측정.
시뮬레이터는 특정 작업·큐를 추적하는 인터페이스도 제공합니다. http://<Host>:<Port>/track으로 이동해 정보를 얻으세요.
- 첫 번째 그림: 큐
SLS_Queue_1의 자원 사용 정보. - 두 번째 그림: 작업
job_1369942127770_0653의 자원 사용 정보.
오프라인 분석 (Offline Analysis)
시뮬레이터가 끝나면 모든 로그는 $HADOOP_ROOT/share/hadoop/tools/sls/bin/slsrun.sh의 --output-dir이 지정한 출력 디렉터리에 저장됩니다.
- 파일
realtimetrack.json: 매 1초마다 모든 실시간 추적 로그를 기록. - 파일
jobruntime.csv: 시뮬레이터의 모든 작업 시작·종료 시간 기록. - 폴더
metrics: Metrics가 생성한 로그.
사용자는 실시간 추적 차트를 오프라인 모드로 재현할 수도 있습니다. realtimetrack.json을 $HADOOP_ROOT/share/hadoop/tools/sls/html/showSimulationTrace.html에 업로드하세요. 브라우저 보안 문제로 realtimetrack.json과 showSimulationTrace.html을 같은 디렉터리에 두어야 합니다.
합성 부하 생성기 (Synthetic Load Generator)
Synthetic Load Generator는 분포 기반 부하 생성을 제공해 SLS 네이티브 및 RUMEN 트레이스의 광범위한 특성을 보완합니다. 부하 생성기는 JobStoryProducer(rumen과 호환, 따라서 이후 gridmix 통합 가능)로 구성됩니다. 결과가 무작위지만 결정적이도록 — 재현 가능하게 — 난수 생성기를 시드합니다. 생성되는 작업을 /workloads/job_class 계층 구조로 구성해서 비슷한 동작을 가진 작업들을 쉽게 그룹화·분류할 수 있습니다(예: 장기 실행 컨테이너가 있는 작업, maponly 계산 등). 사용자는 매퍼/리듀서 수, 매퍼/리듀서 지속시간, 컨테이너 크기(mem/cpu), 예약 확률 등 많은 중요 파라미터의 평균·표준편차를 제어할 수 있어요. 소수의 옵션 중 고를 때는 가중 무작위 샘플링을, 넓은 값 범위에서 고를 때는 LogNormal 분포(음수 값 피하기 위해)를 사용합니다 — LogNormal 분포 부록 참고.
SLS의 SYNTH 모드는 방대한 입력 파일 없이도 매우 큰 부하를 생성하기에 매우 편리합니다. 이로써 넓은 사용 사례(예: 10만 작업 시뮬레이션, 다른 실행에서는 매퍼 평균 수나 평균 작업 지속시간만 조정)를 효율적이고 간결하게 탐구할 수 있습니다.
SLS의 리소스 유형 (Resource Type in SLS)
이 절은 SLS에서 리소스 유형을 사용하는 방법을 설명합니다.
Resource Manager 구성
이것은 실제 클러스터에 리소스 유형을 구성하는 것과 같습니다. yarn-site.xml에 yarn.resource-types 항목을 다음 예시처럼 구성하세요.
<property>
<name>yarn.resource-types</name>
<value>resource-type1, resource-type2</value>
</property>
Node Manager 구성
다음 예시처럼 sls-runner.xml에 관련 항목을 추가해 각 노드의 리소스 크기를 지정합니다. 값은 SLS의 모든 노드에 적용됩니다. 메모리와 vcores 외 리소스의 기본값은 0입니다.
<property>
<name>yarn.sls.nm.resource-type1</name>
<value>10</value>
</property>
<property>
<name>yarn.sls.nm.resource-type2</name>
<value>10</value>
</property>
SLS JSON 입력에서 리소스 지정
Resource Type은 SLS JSON 입력 형식에서 지원되지만 다른 두 형식(SYNTH와 RUMEN)에서는 지원되지 않습니다. SLS JSON 입력 형식에서 동작하게 하려면 작업 컨테이너와 AM 컨테이너 모두의 리소스 크기를 지정할 수 있습니다. 예시:
{
"job.start.ms" : 0,
"am.memory-mb": 2048,
"am.vcores": 2,
"am.resource-type1": 2,
"am.resource-type2": 2,
"job.tasks" : [ {
"container.duration.ms": 5000
"container.memory-mb": 1024,
"container.vcores": 1,
"container.resource-type1": 1,
"container.resource-type2": 1
}
}
부록 (Appendix)
자원 (Resources)
YARN-1021은 YARN Scheduler Load Simulator를 Hadoop YARN 프로젝트에 도입한 주요 JIRA입니다. YARN-6363은 Synthetic Load Generator를 SLS에 도입한 주요 JIRA입니다.
SLS JSON 입력 파일 형식
2개 작업을 담은 sls json 파일의 예시 형식입니다. 첫 작업은 3개 map 작업, 두 번째는 2개 map 작업을 가집니다.
{
"num.nodes": 3, // total number of nodes in the cluster
"num.racks": 1 // total number of racks in the cluster, it divides num.nodes into the racks evenly, optional, the default value is 1
}
{
"am.type" : "mapreduce", // type of AM, optional, the default value is "mapreduce"
"job.start.ms" : 0, // job start time
"job.end.ms" : 95375, // job finish time, optional, the default value is 0
"job.queue.name" : "sls_queue_1", // the queue job will be submitted to
"job.id" : "job_1", // the job id used to track the job, optional. The default value, an zero-based integer increasing with number of jobs, is used if this is not specified or job.count > 1
"job.user" : "default", // user, optional, the default value is "default"
"job.count" : 1, // number of jobs, optional, the default value is 1
"job.tasks" : [ {
"count": 1, // number of tasks, optional, the default value is 1
"container.host" : "/default-rack/node1", // host the container asks for
"container.start.ms" : 6664, // container start time, optional
"container.end.ms" : 23707, // container finish time, optional
"container.duration.ms": 50000, // duration of the container, optional if start and end time is specified
"container.priority" : 20, // priority of the container, optional, the default value is 20
"container.type" : "map" // type of the container, could be "map" or "reduce", optional, the default value is "map"
}, {
"container.host" : "/default-rack/node3",
"container.start.ms" : 6665,
"container.end.ms" : 21593,
"container.priority" : 20,
"container.type" : "map"
}, {
"container.host" : "/default-rack/node2",
"container.start.ms" : 68770,
"container.end.ms" : 86613,
"container.priority" : 20,
"container.type" : "map"
} ]
}
{
"am.type" : "mapreduce",
"job.start.ms" : 105204,
"job.end.ms" : 197256,
"job.queue.name" : "sls_queue_2",
"job.id" : "job_2",
"job.user" : "default",
"job.tasks" : [ {
"container.host" : "/default-rack/node1",
"container.start.ms" : 111822,
"container.end.ms" : 133985,
"container.priority" : 20,
"container.type" : "map"
}, {
"container.host" : "/default-rack/node2",
"container.start.ms" : 111788,
"container.end.ms" : 131377,
"container.priority" : 20,
"container.type" : "map"
} ]
}
SYNTH JSON 입력 파일 형식
합성 생성기 json 파일의 예시 형식입니다. 각 파라미터의 용도를 설명하기 위해 (json 비준수) 인라인 주석을 사용합니다.
{
"description" : "tiny jobs workload", //description of the meaning of this collection of workloads
"num_nodes" : 10, //total nodes in the simulated cluster
"nodes_per_rack" : 4, //number of nodes in each simulated rack
"num_jobs" : 10, // total number of jobs being simulated
"rand_seed" : 2, //the random seed used for deterministic randomized runs
// a list of "workloads", each of which has job classes, and temporal properties
"workloads" : [
{
"workload_name" : "tiny-test", // name of the workload
"workload_weight": 0.5, // used for weighted random selection of which workload to sample from
"queue_name" : "sls_queue_1", //queue the job will be submitted to
//different classes of jobs for this workload
"job_classes" : [
{
"class_name" : "class_1", //name of the class
"class_weight" : 1.0, //used for weighted random selection of class within workload
//nextr group controls average and standard deviation of a LogNormal distribution that
//determines the number of mappers and reducers for thejob.
"mtasks_avg" : 5,
"mtasks_stddev" : 1,
"rtasks_avg" : 5,
"rtasks_stddev" : 1,
//averge and stdev input param of LogNormal distribution controlling job duration
"dur_avg" : 60,
"dur_stddev" : 5,
//averge and stdev input param of LogNormal distribution controlling mappers and reducers durations
"mtime_avg" : 10,
"mtime_stddev" : 2,
"rtime_avg" : 20,
"rtime_stddev" : 4,
//averge and stdev input param of LogNormal distribution controlling memory and cores for map and reduce
"map_max_memory_avg" : 1024,
"map_max_memory_stddev" : 0.001,
"reduce_max_memory_avg" : 2048,
"reduce_max_memory_stddev" : 0.001,
"map_max_vcores_avg" : 1,
"map_max_vcores_stddev" : 0.001,
"reduce_max_vcores_avg" : 2,
"reduce_max_vcores_stddev" : 0.001,
//probability of running this job with a reservation
"chance_of_reservation" : 0.5,
//input parameters of LogNormal distribution that determines the deadline slack (as a multiplier of job duration)
"deadline_factor_avg" : 10.0,
"deadline_factor_stddev" : 0.001,
}
],
// for each workload determines with what probability each time bucket is picked to choose the job starttime.
// In the example below the jobs have twice as much chance to start in the first minute than in the second minute
// of simulation, and then zero chance thereafter.
"time_distribution" : [
{ "time" : 1, "weight" : 66 },
{ "time" : 60, "weight" : 33 },
{ "time" : 120, "jobs" : 0 }
]
}
]
}
시뮬레이터 입력 토폴로지 파일 형식
1개 랙에 3개 노드가 구성된 예시 입력 토폴로지 파일입니다.
{
"rack" : "default-rack",
"nodes" : [ {
"node" : "node1"
}, {
"node" : "node2"
}, {
"node" : "node3"
}]
}
LogNormal 분포 참고 사항
LogNormal 분포는 실무에서 보는 많은 파라미터를 잘 표현합니다(예: 대부분의 작업은 적은 수의 매퍼를 가지지만 일부는 매우 크거나, 매우 작지만 0보다 큰 경우). 다만 분포가 한쪽 꼬리를 가지므로 평균이 보통 분포의 정점(가장 흔한 값) 오른쪽에 있어 사용이 까다로울 수 있음에 유의할 만합니다.
더 알아보기 (Learn more)
- 원문: 문서