All Articles

YARN이 hadoop을 관리하는 방식

YARN의 정의

YARN은 하둡 클러스터 내에서 어떤 node에서 어떤 job을 처리할지 결정하는 역할을 한다. 개발은 용어가 중요하다. YARN은 Yet Another Resource Negotiator의 줄임말이다. Yet은 영단어로 만들려고 억지로 붙인 것 같고, Another는 처음에 도입 배경이 MapReduce를 관리할 수 있는 또다른 툴이기 때문에 붙인 것 같고, 중요한 것은 ResourceNegotiator이다. Resource는 하둡 클러스터에서 구동되는 다양한 application들이다. 그럼 뭘 협상하는가? 어떤 노드에서 일을 할 수 있을지를 해당 application과 협상한다.

YARN의 작동 방식

YARN은 다양한 요청을 처리할 수 있는 API를 제공하지만, 그 API는 잘 사용되지 않는다. 사용자들은 일반적으로 각 application들(저자는 distributed computing frameworks라고 표현함)의 higher-level API를 사용해서 YARN과 소통한다.

YARN의 코어는

  1. a resource manager
  2. node managers

로 구성되어 있다.

단어에서 유추할 수 있듯 resource manager는 하나이고, node managers는 여러개이다. resource manager는 하둡 클러스터 전반에서 resource를 관리하는 manager이다. 반면 node managers는 각 application이 구동되는 container들을 관리하는데, 이 node managers들이 resource manager와 소통해서 하둡 클러스터의 작업을 처리한다. container는 node 안에서 돌아간다고 보면 된다.

how-yarn-runs-an-application

위 그림을 순서대로 설명하자면,

  1. 하둡에서 무언가를 하고싶은 client는 우선 resource manager에게 요청을 보낸다.
  2. resource manager는 client가 구동하고자 하는 applicationmaster process를 구동할 수 있는 container를 찾는다.
  3. master는 client가 원하는 것을 바로 처리할수도 있고, 필요 시 resource manager에게 욫청해서 container를 추가 가동할 수 있다.
  4. container를 추가 구동한 경우 분산해서 병렬적으로 해당 작업을 처리한다.

Resource Requests

YARN은 resource 요청에 유연하게 대처한다. 요청은 일밙거으로 memory, CPU, locality등을 고려해서 처리된다. HDFS와 마찬가지로 YARN도 locality—가장 가까운 node에서 job을 처리—하는 것을 중요하게 생각한다. locality 가 보장되어야 bandwidth 효율을 고려해서 클러스터를 관리할 수 있기 때문이다. 따라서 resource를 요청하는 client는 이 locality를 구체적으로 명시해서 요청할 수 있다. 예를들면 어떤 클러스터의 어떤 랙에서 어떤 노드에 이걸 처리해달라 라는 식으로. locality 조건을 맞출 수 없다면, YARN은 해당 랙에있는 node에서 container구동을 시도한다.

Application Lifespan

lifespan은 제각각이다. 매우 짧을수도, 매우 길 수도 있다. 3가지 옵션이 있다.

  1. 사용자가 요청하는 하나의 job마다 application을 배정하는 것
  2. 사용자가 요청하는 job에서 각 세션마다 application을 배정하는 것
    • container가 다양한 job들 사이에서 재사용 될 수 있기 때문에 첫번째보다 효율적이다.
    • job들 사이에 공통적으로 필요한 것들은 필요 시 cache를 사용할 수도 있다.
  3. application을 길게 구동하고 다양한 사용자들이 공유하게 하는 것이다.
    • 새로 구동하는 시간을 아낄 수 있다는 장점이 있다.

YARN vs MapReduce1

YARN의 등장 배경이 MapReduce를 조금 더 효율적으로 관리하기 위함이기 때문에, 두가지를 비교해본다. MapReduce1에는 jobtrackertask trakers가 있다. 각각 YARNresource managernode managers라고 보면 된다. job tracker는 job을 관리하고, task trakers는 job 안에 task들을 관리한다. task trakers는 각 task의 진행상태를 job tracker에게 전달하고, 이를 통해 job tracker는 전체 job의 진행상태르르 관리한다. 만약 특정 task가 실패한 경우 job traker는 해당 trak를 다른 task tracker에 할애한다.

이처럼 MapReduce1에서는 job tracker가 scheduling과 task progress monitoring을 모두 담당했다. 반면 YARN에서는 resource managerapplication masterjob tracker의 일을 나누어하고, node managertask tracker의 일을 담당한다.

이에따라 YARNMapReduce1에 비해 비교우위에 있는데, 같은 시간내에 최대로 처리할 수 있는 node와 task의 갯수가 훨씬 많기 때문에 scalable하고, MapReduce1에서 job tracker하나가 담당하는 기능을 여러 곳으로 나눠두었기 때문에 high availability측면에서도 유리하다. 또한 task manager는 고정된 사이즈의 slot만 담당하는 반면, node manager는 다른 node에서 container를 올린다는 등의 방법으로 더 큰 공간을 사용할 수 있다.

Scheduling in YARN

YARN이 scalable한 것은 맞지만 그래도 resource는 한정되어 있다. 따라서 YARN에서 scheduling을 하는데는 3가지 정책이 있다.

  1. FIFO Scheduler

    • First-in-First-out queue. 들어온 순서대로 처리한다.
    • 매우 간단하다
  2. Capacity Scheduler

    • 상대적으로 작은 규모의 job이 신규로 생성되면 바로 시작할 수 있도록 queue를 따로 관리한다
  3. Fair Scheduler

    • 큰 job이 많은 resource를 쓰다가, 작은 job이 들어오면 일부 할당해서 resource를 나눠준다.

그림으로 보면 매우 쉽게 이해할 수 있다.

how-yarn-schedules-jobs

Capicity Scheduler는 아래처럼 작성 가능하다. 하둡은 xml을 좋아하는 것 같다

<?xml version="1.0"?>
<configuration>
    <property>
        <name>yarn.scheduler.capacity.root.queues</name>
        <value>prod,dev</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.dev.queues</name>
        <value>eng,science</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.prod.capacity</name>
        <value>40</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.dev.capacity</name>
        <value>60</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.dev.maximum-capacity</name>
        <value>75</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.dev.eng.capacity</name>
        <value>50</value>
    </property>
    <property>
        <name>yarn.scheduler.capacity.root.dev.science.capacity</name>
        <value>50</value>
    </property>
</configuration>

capacity이기 때문에 각 job의 capacity를 수치로 나타낸다. prod.capacity, dev.capacity등의 설정해서 운영, 개발 모드의 capacity를 확인할 수 있고, max와 각 queue의 capacity도 따로 설정할 수 있다.

Fair Scheduler는 똑같이 xml을 사용하지만 조금 다르다.

<?xml version="1.0"?>
<allocations>
    <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
    <queue name="prod">
        <weight>40</weight>
        <schedulingPolicy>fifo</schedulingPolicy>
    </queue>
    <queue name="dev">
        <weight>60</weight>
        <queue name="eng" />
        <queue name="science" />
    </queue>
    <queuePlacementPolicy>
        <rule name="specified" create="false" />
        <rule name="primaryGroup" create="false" />
        <rule name="default" queue="dev.eng" />
    </queuePlacementPolicy>
</allocations>

nested level은 hierarchy를 나타낸다. 그리고 queue에서 사용되는 weight은 fair scheduler가 resource를 job들에게 나눠줄 때 사용된다. 그리고 각 queue 별로 policy를 다르게 할 수도 있는데, 위 예제에서는 전반적으로는 fair이지만 prod queue는 fifo인 것을 확인할 수 있다. 예제에는 없지만 minimummaximum도 설정할 수 있다. 또한 Fair Scheduler는 하나의 queue가 할당된 양보다 많은 resource를 잡고 있을 때, preemption이라는 기능을 통해서 해당 queue가 사용하는 container 들을 처리해서 resource를 free시키고 새로운 queue가 그 resource를 활용하도록 할 수 있다.

Delay Scheduling

YARN은 locality를 중시한다. 따라서 특정 queue가 마무리 되는 것을 기다리면 locality를 보장할 수 있는 경우, 해당 job을 바로 시작하지 않고, locality 를 보장할 수 있도록 기다린다. HDFS에서 datanode가 namenode로 heartbeat을 보내는 것처럼, YARN의 node managers들은 resource manager에게 진행상태를 알리는 heartbeat를 보내는데, resource manager는 이를 바탕으로 delay scheduling을 할지 말지 결정한다. 기다렸다가 바로 시작하는 것이 아니고, 얼마나 기다릴지를 configuration에 작성할 수 있는데, 최대치로 기다려보고 locality가 보장되지 않는다면 가장 가까운 node에서 container를 가동한다.

Dominant Resource Fairness(DRF)

client가 cluster에서 뭔가를 구동할 때, memory, CPU, locality등을 고려한다고 했다. 만약 특정 job이 high memory and low CPU를 필요로하고, 또 다른 job은 low memory and high CPU를 필요로 한다면, YARN은 high demand—dominant resource—를 고려해서 node를 배정한다. default로는 DRF는 꺼져있기 때문에, 별도로 설정하지 않는다면 CPU demand는 무시되고 memory만을 고려해서 resource를 배정한다

Oct 13, 2022

AI Enthusiast and a Software Engineer