Hadoop 스케줄러 적용

LinuxBeginner
지금 연습하기

소개

고대 이집트에서 파라오의 궁전은 왕국의 힘과 번영을 웅장하게 보여 주는 건축물이었습니다. 하지만 화려한 겉모습 아래에서는 위기가 싹트고 있었습니다. 나일강의 풍요로운 산물로 가득 찬 파라오의 거대한 창고가 혼란에 빠진 것입니다. 자원 분배를 맡은 사제들은 백성의 요구를 감당하기 어려워했습니다.

이때 왕국의 자원 관리 질서를 바로잡는 임무를 맡은 총명한 젊은 사제 아멘호텝이 등장합니다. 그는 귀중한 물자를 공정하고 효율적으로 배분해 모든 백성이 정당한 몫을 받을 수 있는 시스템을 만들어야 했습니다.

아멘호텝의 지성과 헌신에 감명받은 파라오는 최신 기술의 결정체인 Hadoop YARN(Yet Another Resource Negotiator)을 사용할 수 있도록 허락했습니다. 이 강력한 도구를 손에 넣은 아멘호텝은 목표를 이루는 데 중요한 YARN 구성 요소인 스케줄러 적용 방법을 배우기 시작했습니다.

Hadoop YARN 스케줄러 이해하기

이 단계에서는 Hadoop YARN에서 사용할 수 있는 여러 스케줄링 정책을 살펴보고, 현재 실행 중인 스케줄러를 확인합니다.

먼저 Hadoop 사용자로 전환합니다. 이 실습의 모든 명령은 현재 터미널에서 실행합니다.

su - hadoop

구성 디렉터리를 명시적으로 지정합니다. 이 이미지에서는 Hadoop이 /home/hadoop/hadoop에 설치되어 있으며, /etc/hadoop/conf는 사용하지 않습니다.

export HADOOP_CONF_DIR=/home/hadoop/hadoop/etc/hadoop

Hadoop YARN은 Fair Scheduler와 Capacity Scheduler를 지원합니다. Fair Scheduler는 시간에 따라 애플리케이션 간에 리소스를 공유하며, 큐 가중치에 따라 큐별 상대 할당량이 달라집니다. Capacity Scheduler는 계층 구조의 큐에 보장된 용량을 할당하면서 사용하지 않는 리소스는 공유할 수 있도록 합니다.

Hadoop 3.3.6에는 yarn scheduler 하위 명령이 없습니다. 구성 파일이 적용되었다고 가정하지 말고, ResourceManager의 REST API를 조회해 실제로 실행 중인 스케줄러를 확인합니다. 응답을 파일에 저장합니다.

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-initial.json

현재 활성화된 스케줄러 유형을 표시합니다.

python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-initial.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
PY

새 실습 환경에서 예상되는 출력은 다음과 같습니다.

capacityScheduler

다음 단계를 위해 이 터미널을 열어 둡니다. Hadoop 구성 파일에서 각 스케줄러를 설정한 다음 ResourceManager를 다시 시작해 선택한 스케줄러 클래스를 불러옵니다.

Fair Scheduler 구성하기

이 단계에서는 citizens 큐와 priests 큐 간에 리소스를 공유하도록 Fair Scheduler를 구성합니다.

Hadoop 사용자로서 아래 블록 전체를 실행해 할당 파일을 만듭니다.

cat > /home/hadoop/fair-scheduler.xml <<'XML'
<?xml version="1.0"?>
<allocations>
  <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
  <queue name="root">
    <weight>1.0</weight>
    <queue name="citizens">
      <weight>1.0</weight>
      <minResources>1024 mb, 1 vcores</minResources>
    </queue>
    <queue name="priests">
      <weight>2.0</weight>
      <minResources>2048 mb, 2 vcores</minResources>
    </queue>
  </queue>
</allocations>
XML

citizens 큐의 가중치는 1이며, 최소 리소스는 메모리 1024MB와 vcore 1개입니다. priests 큐의 가중치는 2이며, 최소 리소스는 메모리 2048MB와 vcore 2개입니다. 최소 리소스는 클러스터에서 사용할 수 있는 리소스에 따라 충족되는 목표값입니다. 가중치는 남은 리소스를 큐 간에 공유하는 방식에 영향을 줍니다.

Fair Scheduler를 선택하고 yarn-site.xml에서 할당 파일을 지정합니다. 다음 명령은 기존 NodeManager 설정을 보존합니다.

python3 - <<'PY'
import os
import xml.etree.ElementTree as ET

path = os.path.join(os.environ['HADOOP_CONF_DIR'], 'yarn-site.xml')
tree = ET.parse(path)
root = tree.getroot()
settings = {
    'yarn.resourcemanager.scheduler.class':
        'org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler',
    'yarn.scheduler.fair.allocation.file': '/home/hadoop/fair-scheduler.xml',
}
for name, value in settings.items():
    prop = next((p for p in root.findall('property') if p.findtext('name') == name), None)
    if prop is None:
        prop = ET.SubElement(root, 'property')
        ET.SubElement(prop, 'name').text = name
        ET.SubElement(prop, 'value')
    prop.find('value').text = value
tree.write(path, encoding='UTF-8', xml_declaration=True)
PY

스케줄러 클래스를 변경하려면 ResourceManager를 다시 시작해야 합니다. 이 실습 클러스터에는 실행 중인 애플리케이션이 없습니다. ResourceManager만 중지했다가 시작합니다.

yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager

실행 중인 스케줄러를 다시 조회합니다. 재시도 옵션은 ResourceManager가 시작될 때까지 기다리도록 합니다. 시작 중에는 잠깐 연결 오류가 발생할 수 있습니다.

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-fair.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-fair.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['rootQueue']['childQueues']['queue']:
    if queue['queueName'] in ('root.citizens', 'root.priests'):
        resources = queue['minResources']
        print(queue['queueName'], resources['memory'], resources['vCores'])
PY

예상 출력은 다음과 같습니다. 큐 출력 순서는 달라질 수 있습니다.

fairScheduler
root.citizens 1024 1
root.priests 2048 2

3단계에서 스케줄러를 바꾸기 전에 이 단계의 확인을 완료합니다.

Capacity Scheduler 구성하기

이 단계에서는 Capacity Scheduler로 전환하고 각 큐에 클러스터 용량의 50%를 할당합니다.

Hadoop 사용자로서 capacity-scheduler.xml을 Hadoop 구성 디렉터리에 직접 작성합니다. /home/hadoop에만 있는 파일은 이 스케줄러가 불러오지 않습니다.

cat > /home/hadoop/hadoop/etc/hadoop/capacity-scheduler.xml <<'XML'
<?xml version="1.0"?>
<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>citizens,priests</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.citizens.capacity</name>
    <value>50</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.priests.capacity</name>
    <value>50</value>
  </property>
</configuration>
XML

하위 큐의 용량을 합하면 100%입니다. yarn-site.xml에서 Capacity Scheduler를 선택합니다.

sed -i 's/org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler/org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler/' /home/hadoop/hadoop/etc/hadoop/yarn-site.xml

새 스케줄러 클래스와 큐 구성을 불러오도록 ResourceManager를 다시 시작합니다.

yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager

활성 스케줄러와 큐를 확인합니다.

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-capacity.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-capacity.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['queues']['queue']:
    print(queue['queueName'], queue['capacity'])
PY

예상 출력은 다음과 같습니다. 큐 출력 순서는 달라질 수 있습니다.

capacityScheduler
citizens 50.0
priests 50.0

두 큐가 모두 리소스를 필요로 할 때 각 큐는 50%의 용량을 보장받습니다. 사용하지 않는 용량은 공유할 수 있으므로, 이 값 때문에 유휴 리소스가 계속 사용되지 않는 상태로 남지는 않습니다.

요약

이 실습에서는 Hadoop YARN에서 다양한 스케줄링 정책을 구성하고 적용해 리소스 할당을 효율적으로 관리하는 방법을 배웠습니다. Fair Scheduler와 Capacity Scheduler를 익히면 아멘호텝은 왕국의 백성에게 리소스를 공정하게 분배하고, 사제들이 수행하는 중요한 작업에 우선순위를 부여할 수 있습니다.

직접 실습하며 Hadoop YARN의 강력한 기능과 복잡한 환경에서 리소스를 관리하는 방법을 더 깊이 이해했습니다. 이 실습에서 배운 지식을 활용하면 조직의 구체적인 요구에 맞는 효율적이고 공정한 리소스 관리 시스템을 구축할 수 있습니다.