YARN 의 노드 라벨(node label)은 노드에 이름표를 붙여 두고, 작업이 그 이름표가 붙은 노드에서만 컨테이너를 받도록 하는 기능이다. Capacity Scheduler 에서는 같은 것을 파티션이라고 부른다. 라벨을 붙이지 않은 노드는 모두 DEFAULT 파티션에 속한다.
라벨에는 배타(exclusive)와 비배타(non-exclusive) 두 성격이 있다. 배타 라벨이 붙은 노드는 그 라벨을 요구한 작업만 받는다. 비배타 라벨이 붙은 노드는 여유가 있을 때 DEFAULT 파티션 작업도 받는다. 특정 서버를 전용으로 떼어 두려는 목적이면 배타를 쓴다.
노드 하나에는 라벨 하나만 붙는다. 여러 라벨을 붙일 수는 없다.
yarn-site.xml 에서 노드 라벨 기능을 켜고 라벨 정보를 저장할 위치를 정한다. ResourceManager 재기동이 필요하다.
<property>
<name>yarn.node-labels.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.node-labels.fs-store.root-dir</name>
<value>hdfs://nameservice1/yarn/node-labels</value>
</property>
라벨을 등록하고 노드에 붙인다. 괄호 안이 배타 여부다.
yarn rmadmin -addToClusterNodeLabels "work3(exclusive=true)"
yarn rmadmin -replaceLabelsOnNode "work3.example.net:8041=work3"
노드 주소는 NodeManager 의 주소이고 포트는 yarn.nodemanager.address 의 포트(기본 8041)다. 포트를 생략하면 그 호스트의 모든 NodeManager 에 적용된다. 확인은 다음과 같다.
yarn cluster --list-node-labels
yarn node -list -all
라벨을 붙였다고 바로 쓸 수 있는 것은 아니다. Capacity Scheduler 에서 큐가 그 라벨에 접근할 수 있어야 하고, 라벨별 용량도 따로 정해야 한다. capacity-scheduler.xml 에서 설정한다.
# root 와 대상 큐가 접근할 수 있는 라벨
yarn.scheduler.capacity.root.accessible-node-labels=work3
yarn.scheduler.capacity.root.default.accessible-node-labels=work3
# 그 라벨 파티션 안에서의 용량
yarn.scheduler.capacity.root.accessible-node-labels.work3.capacity=100
yarn.scheduler.capacity.root.default.accessible-node-labels.work3.capacity=100
yarn.scheduler.capacity.root.default.accessible-node-labels.work3.maximum-capacity=100
# 이 큐로 들어온 작업의 기본 라벨
yarn.scheduler.capacity.root.default.default-node-label-expression=work3
한 파티션 안에서 형제 큐들의 capacity 합은 100 이어야 한다. DEFAULT 파티션의 용량 설정과는 별개로 관리된다.
마지막 줄이 실무에서 가장 중요하다. default-node-label-expression 을 큐에 걸어 두면 작업 쪽에서 라벨을 지정하지 않아도 그 큐로 들어온 작업이 자동으로 해당 파티션에만 배치된다. 애플리케이션마다 라벨 지정 방법이 제각각이므로, 큐에 걸어 두고 큐만 고르게 하는 구성이 가장 다루기 쉽다.
변경은 재기동 없이 반영할 수 있다.
yarn rmadmin -refreshQueues
큐에 기본 라벨을 걸지 않았다면 작업마다 지정한다. 엔진별로 속성 이름이 다르다.
MapReduce 는 큐와 라벨을 모두 받는다.
yarn jar hadoop-mapreduce-examples.jar pi \
-Dmapreduce.job.queuename=root.work3 \
-Dmapreduce.job.node-label-expression=work3 \
10 100
Spark on YARN 은 AM 과 executor 의 라벨을 따로 지정한다.
spark-submit --master yarn --deploy-mode cluster \
--queue root.work3 \
--conf spark.yarn.am.nodeLabelExpression=work3 \
--conf spark.yarn.executor.nodeLabelExpression=work3 \
job.py
Hive on MapReduce 는 세션 설정으로 넘긴다.
SET mapreduce.job.queuename=root.work3;
SET mapreduce.job.node-label-expression=work3;
Hive on Tez 는 큐만 고른다.
SET hive.execution.engine=tez;
SET tez.queue.name=root.work3;
Tez 에는 노드 라벨 표현식을 직접 넘기는 표준 설정이 없다. 따라서 Hive on Tez 에서 특정 노드만 쓰게 하려면 위의 default-node-label-expression 을 큐에 걸어 두고 그 큐를 고르는 방법을 쓴다. tez.am.node-label-expression 같은 이름은 Tez 의 표준 설정이 아니며, 배포판에 따라 자체 확장이 있을 수 있으나 일반적으로는 동작하지 않는다.
라벨이 실제로 적용됐는지는 제출 후 확인한다.
yarn application -list
yarn node -list -all
yarn cluster --list-node-labels
ResourceManager 웹 UI 의 스케줄러 화면에는 파티션별 탭이 나오고, 각 파티션에서 큐가 잡고 있는 자원이 보인다. 라벨을 걸었는데 작업이 ACCEPTED 에서 멈춰 있다면 대상 파티션에 큐 용량이 0 이거나 그 파티션에 살아 있는 NodeManager 가 없는 경우다.
간단한 검증은 셸 컨테이너를 띄워 보는 것으로 충분하다.
yarn jar hadoop-yarn-applications-distributedshell.jar \
-shell_command "sleep 300" -num_containers 2 -queue root.work3