YARN
은 하둡 클러스터 내에서 어떤 node에서 어떤 job을 처리할지 결정하는 역할을 한다. 개발은 용어가 중요하다. YARN은 Yet Another Resource Negotiator의 줄임말이다. Yet
은 영단어로 만들려고 억지로 붙인 것 같고, Another
는 처음에 도입 배경이 MapReduce
를 관리할 수 있는 또다른 툴이기 때문에 붙인 것 같고, 중요한 것은 Resource
와 Negotiator
이다. Resource
는 하둡 클러스터에서 구동되는 다양한 application들이다. 그럼 뭘 협상하는가? 어떤 노드에서 일을 할 수 있을지를 해당 application과 협상한다.
YARN
은 다양한 요청을 처리할 수 있는 API를 제공하지만, 그 API는 잘 사용되지 않는다. 사용자들은 일반적으로 각 application들(저자는 distributed computing frameworks라고 표현함)의 higher-level API
를 사용해서 YARN
과 소통한다.
YARN
의 코어는
로 구성되어 있다.
단어에서 유추할 수 있듯 resource manager
는 하나이고, node managers
는 여러개이다. resource manager
는 하둡 클러스터 전반에서 resource를 관리하는 manager이다. 반면 node managers
는 각 application이 구동되는 container
들을 관리하는데, 이 node managers
들이 resource manager
와 소통해서 하둡 클러스터의 작업을 처리한다. container는 node 안에서 돌아간다고 보면 된다.
위 그림을 순서대로 설명하자면,
resource manager
에게 요청을 보낸다.resource manager
는 client가 구동하고자 하는 application
의 master
process를 구동할 수 있는 container를 찾는다.master
는 client가 원하는 것을 바로 처리할수도 있고, 필요 시 resource manager
에게 욫청해서 container를 추가 가동할 수 있다.YARN
은 resource 요청에 유연하게 대처한다. 요청은 일밙거으로 memory, CPU, locality등을 고려해서 처리된다. HDFS와 마찬가지로 YARN
도 locality—가장 가까운 node에서 job을 처리—하는 것을 중요하게 생각한다. locality 가 보장되어야 bandwidth 효율을 고려해서 클러스터를 관리할 수 있기 때문이다. 따라서 resource를 요청하는 client는 이 locality를 구체적으로 명시해서 요청할 수 있다. 예를들면 어떤 클러스터의 어떤 랙에서 어떤 노드에 이걸 처리해달라 라는 식으로. locality 조건을 맞출 수 없다면, YARN은 해당 랙에있는 node에서 container구동을 시도한다.
lifespan은 제각각이다. 매우 짧을수도, 매우 길 수도 있다. 3가지 옵션이 있다.
YARN의 등장 배경이 MapReduce를 조금 더 효율적으로 관리하기 위함이기 때문에, 두가지를 비교해본다. MapReduce1
에는 jobtracker
와 task trakers
가 있다. 각각 YARN
의 resource manager
와 node 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 manager
와 application master
가 job tracker
의 일을 나누어하고, node manager
가 task tracker
의 일을 담당한다.
이에따라 YARN
은 MapReduce1
에 비해 비교우위에 있는데, 같은 시간내에 최대로 처리할 수 있는 node와 task의 갯수가 훨씬 많기 때문에 scalable하고, MapReduce1
에서 job tracker
하나가 담당하는 기능을 여러 곳으로 나눠두었기 때문에 high availability
측면에서도 유리하다. 또한 task manager
는 고정된 사이즈의 slot
만 담당하는 반면, node manager
는 다른 node에서 container를 올린다는 등의 방법으로 더 큰 공간을 사용할 수 있다.
YARN
이 scalable한 것은 맞지만 그래도 resource는 한정되어 있다. 따라서 YARN
에서 scheduling을 하는데는 3가지 정책이 있다.
FIFO Scheduler
Capacity Scheduler
Fair Scheduler
그림으로 보면 매우 쉽게 이해할 수 있다.
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
인 것을 확인할 수 있다. 예제에는 없지만 minimum
과 maximum
도 설정할 수 있다.
또한 Fair Scheduler는 하나의 queue가 할당된 양보다 많은 resource를 잡고 있을 때, preemption
이라는 기능을 통해서 해당 queue가 사용하는 container 들을 처리해서 resource를 free시키고 새로운 queue가 그 resource를 활용하도록 할 수 있다.
YARN
은 locality를 중시한다. 따라서 특정 queue가 마무리 되는 것을 기다리면 locality를 보장할 수 있는 경우, 해당 job을 바로 시작하지 않고, locality 를 보장할 수 있도록 기다린다. HDFS에서 datanode가 namenode로 heartbeat을 보내는 것처럼, YARN의 node managers들은 resource manager에게 진행상태를 알리는 heartbeat를 보내는데, resource manager는 이를 바탕으로 delay scheduling
을 할지 말지 결정한다. 기다렸다가 바로 시작하는 것이 아니고, 얼마나 기다릴지를 configuration에 작성할 수 있는데, 최대치로 기다려보고 locality가 보장되지 않는다면 가장 가까운 node에서 container를 가동한다.
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를 배정한다