YARN architecture: ResourceManager, NodeManager, ApplicationMaster

YARN is the layer that turns a cluster into a pool of memory and CPU that many applications can share. This lesson takes it apart on a live cluster: the ResourceManager and its two halves, the NodeManagers on every worker, the per-job ApplicationMaster and the containers it asks for, with every number read from the running system.

Module 11 · YARN⏱ 30 minIntermediateLive cluster, real numbersArchitecture diagram + 2 animationsRuns in your browser (Python)8 practice problems
1 The story

Who decides where your code runs?

In Module 8 Riya ran MapReduce jobs and simply watched them finish. Today Kabir asks the question every operations engineer asks first: “When you typed hadoop jar, who decided that the first container goes to worker1, that each map gets 512 MB, and that no more than 12 tasks can run at once?” Riya has no idea. The answer is YARN, the layer between HDFS and every job.

Front desk = ResourceManager knows every free room, hands them out Tour group arrives = your job (hadoop jar) Tour leader = ApplicationMaster Floor 1 manager Floor 2 manager Floor 3 manager leader room room room room floor managers = NodeManagers · rooms = containers (memory + CPU) Our lab, mid-job: 5 rooms taken (2,560 of 6,144 MB), one of them for the tour leader on worker1. myphatshala.in
Riya

So the ResourceManager runs my map tasks?

Arjun Sir

No, and that is the key idea. The ResourceManager only hands out containers: “512 MB and 1 CPU on worker2, it's yours.” Each job gets its own manager, the ApplicationMaster, which asks for those containers and decides what to run in them. The NodeManager on each worker starts and watches the processes.

Kabir

Like a hotel front desk. It never carries your bags; it gives your tour leader the room keys.

Arjun Sir

Exactly. Today we look inside a live cluster: which Java process runs where, what each NodeManager offers, and how 5 containers and 2,560 MB were handed out for one job.

2 Definition

YARN: Yet Another Resource Negotiator

Formal definition (write this in exams)

YARN is Hadoop's cluster resource-management and job-scheduling layer, introduced in Hadoop 2. It separates resource management from application logic. A single ResourceManager (RM) per cluster arbitrates all resources; it consists mainly of the Scheduler, which allocates resources to applications according to capacities, queues and policies, and the ApplicationsManager, which accepts job submissions, starts each application's first container and restarts it on failure. A NodeManager (NM) on every worker launches and monitors containers, reports node health and resource use to the RM through heartbeats, and runs auxiliary services such as the MapReduce shuffle. Each application has its own ApplicationMaster (AM), which runs in a container, negotiates further containers from the Scheduler using resource requests (memory, virtual cores, locality, priority) and works with NodeManagers to execute and monitor its tasks. A container is an allocation of memory and CPU on one node in which one process runs.

In simple words

The ResourceManager is the cluster's bookkeeper of free memory and CPU. NodeManagers start and watch processes on each machine. Every job brings its own manager, the ApplicationMaster, which asks for “boxes” of memory and CPU (containers) and runs its tasks inside them.

Words you'll meet in this lesson

ResourceManager (RM)The YARN master: tracks free resources, grants containers. Web UI port 8088.
SchedulerPart of the RM that decides who gets which container (FIFO, Capacity, Fair: Lesson 11.3).
ApplicationsManagerPart of the RM that accepts submissions and starts (and restarts) each AM.
NodeManager (NM)YARN worker on each machine: launches, monitors and kills containers. UI port 8042.
ApplicationMaster (AM)One per application: asks for containers, runs and tracks tasks. For MapReduce: MRAppMaster.
ContainerMemory + vcores on one node, with one process inside (e.g. a YarnChild map task).
Resource requestWhat an AM asks for: how many containers, what size, where (node, rack, any), with what priority.
HeartbeatRegular report: NM → RM (node status, finished containers); AM → RM (allocate call).

From our lab (Hadoop 3.5.0, Module 8 cluster)

Daemonsjps: resourcemanager → ResourceManager · namenode → NameNode · historyserver → JobHistoryServer · worker1 → DataNode, NodeManager
Each NodeManagerConfigured Resources: <memory:2048, vCores:2> (set by yarn.nodemanager.resource.memory-mb and cpu-vcores)
Whole clusteractiveNodes 3 · totalMB 6144 · totalVirtualCores 6 (RM REST API /ws/v1/cluster/metrics)
During a 422 MB job5 containers, allocatedMB 2560 = AM 512 + 4 maps × 512 (each map asked for 384 MB; rounded up to a multiple of the 256 MB minimum). worker1 ran DataNode, NodeManager, MRAppMaster and a YarnChild
Per nodeworker1 1024 MB (AM + 1 map) · worker2 1024 MB (2 maps) · worker3 512 MB (1 map)

YARN at three levels

Pick your level. New to this? Start at Beginner and climb.

Beginner The hotel

  • The front desk (ResourceManager) knows which rooms are free on every floor but carries no luggage.
  • Each floor manager (NodeManager) opens rooms, checks nobody is breaking the rules (using too much memory) and tells the desk every few moments what is free.
  • Every tour group brings a tour leader (ApplicationMaster). The leader gets a room first, then asks the desk for more rooms for the group and tells each member what to do.
  • A room is a container: a fixed amount of memory and CPU for one process.

Intermediate What each part does in a real job

  • Client: uploads the jar and configuration to HDFS and calls the RM on port 8032 (ClientRMService).
  • ApplicationsManager: accepts the application, asks the Scheduler for the AM's container and has a NodeManager start it.
  • ApplicationMaster: registers with the RM on port 8030, then calls allocate() repeatedly: “4 containers of 512 MB, preferably on the hosts that hold these blocks.” It also reports progress and finally unregisters.
  • Scheduler: on each NodeManager heartbeat (port 8031, ResourceTrackerService) it looks for a waiting request that fits the node's free space and grants a container.
  • NodeManager: receives the container launch from the AM, localizes the jar, starts the process (a YarnChild JVM), monitors it and reports when it exits.

Advanced Why the design scales

  • In Hadoop 1 one JobTracker did both: scheduling the cluster and tracking every task of every job. At around 4,000 nodes it became the bottleneck, and fixed map/reduce slots wasted capacity (Lesson 2.4).
  • YARN keeps the RM small: it tracks containers, not tasks. Task tracking, retries and speculation live in each AM, so the work spreads across the cluster.
  • Because the AM is application code, any framework can run on YARN: MapReduce, Spark, Tez (Hive), Flink, Hive LLAP. They share one cluster and one set of queues.
  • The RM can run in High Availability: an active and a standby RM with ZooKeeper for leader election, and running applications survive a failover (work-preserving restart).
  • The Scheduler is pluggable: FIFO, Capacity (default in Apache Hadoop) or Fair. Lesson 11.3 measures all three.

Exam tip: For “Explain YARN architecture”, draw the RM (Scheduler + ApplicationsManager), NodeManagers with containers, one ApplicationMaster per application, and number the steps: submit → AM container → AM registers and requests containers → NMs launch tasks → AM unregisters. Add one line: the RM manages resources, the AM manages the application.

3 Types and ways to use it

The parts of YARN, one by one

Architecture at a glance

Client hadoop jar · spark-submit ResourceManager (port 8088 UI) Scheduler who gets which container ApplicationsManager accepts jobs, starts AMs HDFS jar, input, output ① submit (8032) jar + job.xml go to HDFS worker1 · NodeManager worker2 · NodeManager worker3 · NodeManager AM containerMRAppMaster containermap (YarnChild) containermap containermap containermap free 1536 MB + DataNode · 2048 MB, 2 vcores + DataNode · 2048 MB, 2 vcores + DataNode · 2048 MB, 2 vcores ② start AM ③ register + allocate (8030) heartbeats (8031) ④ the AM asks each NodeManager to launch its tasks ApplicationMaster task container myphatshala.in

The picture is our lab during the 422 MB job: the AM and one map on worker1, two maps on worker2, one on worker3, and 1,536 MB still free on worker3.

ComponentHow manyRuns whereJobPorts (Hadoop 3)
ResourceManager1 active (+ standby with HA)Master nodeCluster-wide resource accounting and scheduling8088 UI/REST, 8032 clients, 8030 AMs, 8031 NMs, 8033 admin
NodeManager1 per workerEvery worker (next to a DataNode)Launch, monitor, kill containers; shuffle service; log aggregation8042 UI, 13562 shuffle
ApplicationMaster1 per applicationInside a container on any workerRequest containers, run and retry the app's tasksrandom
ContainerManyOn workersOne process with a memory and vcore limit-
JobHistory Server1Master nodeHistory of finished MapReduce jobs (not part of YARN itself)19888
Timeline Server0 or 1Master nodeGeneric history for all YARN apps (optional)8188

Not only MapReduce: the ApplicationMasters you'll meet

MRAppMaster

MapReduce's AM: one container for itself, then one per map and reduce task. Seen on worker1 in our lab.

MapReduce

Spark on YARN

In cluster mode the driver runs inside the AM container; executors are long-lived containers that run many tasks each.

Spark

Tez AM

Runs Hive queries as a graph of steps, reusing containers between them instead of one MapReduce job per step.

Hive

Flink / services

Long-running streaming jobs keep their containers for days; YARN restarts the AM if it dies.

streaming

Animated example: a 10 AM rush on a shared cluster

IRCTC-style Tatkal analytics on YARN 6 steps
Animated example ResourceManager node 1 node 2 node 3 node 4 submit: tatkal-report 10:05 · bookings from 10:00–10:05 are in HDFS.An analyst submits a report job. AM 1 GB The ApplicationsManager starts the job's AMin a 1 GB container on node 1. need 6 × 2 GB, near data The AM counts 6 splits and asks the Schedulerfor 6 containers, preferring nodes with the blocks. mapmapmapmap Node heartbeats bring free space; the Schedulergrants 4 now. Node 4 is busy with the booking app. bookingservice (full) mapmap As the rush eases, node 4 frees memory:the last 2 containers are granted. 10:12 · report ready, AM unregistersall containers return to the pool for the next job myphatshala.in

YARN shares one cluster between very different workloads: a booking service's batch jobs, a fraud model's Spark job and an analyst's Hive query all ask the same ResourceManager. How it chooses between them (queues and schedulers) is Lesson 11.3.

4 Step by step

Looking inside a live YARN cluster

We use the Module 8 lab (NameNode, ResourceManager, JobHistory Server, three workers each running a DataNode and a NodeManager). All commands are in yarn_arch_lab.sh under “Run it on your PC”.

  1. Which Java processes run where?

    for c in resourcemanager namenode historyserver worker1; do
      echo "$c: $(docker exec lab8-$c-1 jps | awk '{print $2}' | grep -v Jps)"
    done
    resourcemanager: ResourceManager namenode: NameNode RunJar historyserver: JobHistoryServer worker1: DataNode NodeManager
    Every daemon is a separate JVM. Masters run one daemon each; a worker runs both a DataNode (storage) and a NodeManager (compute) so tasks can read local blocks. RunJar on the namenode was the client of a job that was still finishing when we looked.
  2. What does each NodeManager offer?

    docker exec lab8-resourcemanager-1 yarn node -list -showDetails
    worker2:40977 RUNNING worker2:8042 1 Configured Resources : <memory:2048, vCores:2> Allocated Resources : <memory:512, vCores:1> Resource Utilization by Node : PMem:5621 MB, VMem:5621 MB, VCores:1.6533333 Resource Utilization by Containers : PMem:466 MB, VMem:4334 MB, VCores:1.04 worker1:36427 RUNNING worker1:8042 0 Configured Resources : <memory:2048, vCores:2> Allocated Resources : <memory:0, vCores:0>
    “Configured” is what the NodeManager offers to YARN (from yarn-site.xml), not the machine's real RAM: the node itself was using 5.6 GB, mostly for the DataNode and other processes. One 512 MB container was still running on worker2.
  3. Ask the ResourceManager for cluster totals

    curl -s http://resourcemanager:8088/ws/v1/cluster/metrics
    activeNodes 3 totalMB 6144 totalVirtualCores 6 allocatedMB 512 appsRunning 1 appsCompleted 125 containersAllocated 1
    The RM's whole job is this bookkeeping: 3 × 2048 MB = 6144 MB and 3 × 2 = 6 vcores to hand out. The same numbers appear on the web UI at port 8088.
  4. Start a job and look again

    hadoop jar mr.jar ItemRevenue /user/hadoop/data/orders_x90.csv /out/yarn_arch &
    docker exec lab8-worker1-1 jps
    1 DataNode 1 MRAppMaster 1 NodeManager 1 YarnChild allocatedMB 2560 of 6144 | allocatedVirtualCores 5 | containersAllocated 5 | appsRunning 1
    Two new processes on worker1: the job's MRAppMaster and a YarnChild (a map task). Five containers hold 2,560 MB: the AM's 512 MB plus four maps. Each map asked for 384 MB, but YARN rounds every request up to a multiple of the minimum allocation (256 MB), so each got 512 MB.
  5. List the job's containers

    yarn applicationattempt -list application_1792643020992_0135
    yarn container -list appattempt_1792643020992_0135_000001
    container_1792643020992_0135_01_000001 RUNNING worker1:36427 container_1792643020992_0135_01_000005 RUNNING worker2:40977 container_1792643020992_0135_01_000004 RUNNING worker3:44495 container_1792643020992_0135_01_000003 RUNNING worker1:36427 container_1792643020992_0135_01_000002 RUNNING worker2:40977
    Container …_000001 is always the ApplicationMaster. The number in the middle (_01_) is the attempt: if the AM dies, YARN starts attempt 02 with new containers.
  6. Per-node usage

    curl -s http://resourcemanager:8088/ws/v1/cluster/nodes
    worker2 used 1024 MB / 2048 MB, 2 vcores used, 2 containers worker1 used 1024 MB / 2048 MB, 2 vcores used, 2 containers worker3 used 512 MB / 2048 MB, 1 vcores used, 1 containers Job:1765 - Job job_1792643020992_0135 completed successfully
    The Scheduler spread the containers as NodeManagers heartbeated in. In an earlier run in this session worker1 even showed “3 vcores used” on a 2-vcore node: the default resource calculator only counts memory. Lesson 11.4 switches that on.

yarn.nodemanager.resource.memory-mb is a promise, not a measurement. If you offer YARN more memory than the machine can spare after the OS, DataNode and other services, containers will push the node into swapping or the kernel's OOM killer. Our lab offers only 2 GB per worker on purpose.

5 See it happen

From hadoop jar to five containers

Six steps of our 422 MB job, as the terminal shows them and as YARN handles them.

Containers on demand 6 steps
What you see hadoop@namenode : /tmp/mr $ hadoop jar mr.jar ItemRevenue …x90.csvConnecting to ResourceManager at resourcemanager:8032 Submitted application_…_0135$ yarn container -list ……_01_000001 RUNNING worker1 number of splits:4map 0% reduce 0% containersAllocated 5allocatedMB 2560 of 6144 $ docker exec lab8-worker1-1 jpsDataNode NodeManagerMRAppMaster YarnChild map 100% reduce 100%completed successfullyallocatedMB 0 (all released) myphatshala.in
Behind the screen ResourceManager free: 6144 MB of 6144free: 5632 MB of 6144free: 3584 MB of 6144free: 6144 MB of 6144 worker1 NM worker2 NM worker3 NM clientsubmit: jar and config already in HDFS AM 512 MB ApplicationsManager: start the AM on worker1 4 × 384 MB → 4 × 512AM registers, asks for 4 map containers map 512 MBmap 512 MBmap 512 MBmap 512 MB on each NM heartbeat the Scheduler grants a container YarnChild JVMsAM tells each NM to launch its task AM unregisters · containers releasedthe RM's free memory is back to 6144 MB myphatshala.in
6 Real-world use

YARN at work

Spark · Hive · MRone cluster

1. Bank: one cluster, many engines

An Indian bank runs nightly MapReduce reconciliation, Hive reports for branches and a Spark fraud-scoring job on the same nodes. YARN gives each its containers from one pool instead of three separate clusters.

MR + Hive + Spark→ResourceManager→Shared workers

2. Telecom: call records at month end

Billing jobs for crores of call records ask for thousands of containers once a month; during the rest of the month the same capacity runs network analytics.

CDRs in HDFS→Billing AM→Bills per customer
Flink AM

3. E-commerce: a streaming job that never ends

A clickstream job runs for weeks as a Flink or Spark Streaming application on YARN. If its AM dies, the ApplicationsManager restarts it in a new container.

Clicks (Kafka)→Long-running AM→Live dashboards
activestandby

4. Government data platform: RM high availability

A state e-governance analytics platform runs two ResourceManagers with ZooKeeper. When the active RM's server is patched, the standby takes over and running jobs continue.

RM1 active→ZooKeeper election→RM2 active
8088 / RESTcapacity report

5. University research cluster: fair use

An IIT-style research cluster reads the RM REST API every few minutes to show each department how many container-hours it used, the same /ws/v1/cluster/metrics data we read in the lab.

RM REST API→Usage script→Monthly report

Simplified, illustrative examples; organisations differ in tools and policies.

7 Run the code

Be the ResourceManager for one job

This model keeps the RM's books for our lab: three NodeManagers with 2,048 MB each, a 256 MB minimum allocation, one AM of 512 MB and four maps asking for 384 MB. Containers are granted as NodeManagers heartbeat in, one per heartbeat, in the order they arrived in our run.

import math
MIN_ALLOC = 256                                   # yarn.scheduler.minimum-allocation-mb
nodes = {"worker1": 2048, "worker2": 2048, "worker3": 2048}
used = {n: 0 for n in nodes}

def normalize(mb):                                # round UP to a multiple of the minimum
    return math.ceil(mb / MIN_ALLOC) * MIN_ALLOC

requests = [("AM", 512)] + [(f"map{i}", 384) for i in range(4)]
heartbeats = ["worker1", "worker2", "worker3", "worker1", "worker2"]   # who reported free space next

for (name, ask), node in zip(requests, heartbeats):
    size = normalize(ask)
    if used[node] + size <= nodes[node]:
        used[node] += size
        print(f"{name:5} asks {ask} MB -> gets {size} MB on {node}")

print("per node:", used)
print("allocated", sum(used.values()), "of", sum(nodes.values()), "MB in", len(requests), "containers")
AM asks 512 MB -> gets 512 MB on worker1 map0 asks 384 MB -> gets 512 MB on worker2 map1 asks 384 MB -> gets 512 MB on worker3 map2 asks 384 MB -> gets 512 MB on worker1 map3 asks 384 MB -> gets 512 MB on worker2 per node: {'worker1': 1024, 'worker2': 1024, 'worker3': 512} allocated 2560 of 6144 MB in 5 containers
  • return math.ceil(mb / MIN_ALLOC) * MIN_ALLOCThe Scheduler normalizes every request: 384 MB becomes 512 MB, which is why 4 maps + AM held 2,560 MB.
  • heartbeats = ["worker1", "worker2", "worker3", "worker1", "worker2"] # who reported free space nextThe Scheduler assigns containers when a NodeManager heartbeats and reports free space.
  • if used[node] + size <= nodes[node]:A container must fit entirely on one node: YARN never splits a container across machines.

Run it on your PC: look inside YARN

This uses the Module 8 lab (docker compose -p lab8 up -d in the mr-lab folder) and the mr.jar and orders_x90.csv from Lesson 8.1. Unlike most scripts in Module 8, this one runs on your PC in the mr-lab folder, because it looks at several containers with docker exec.

Daemons, NodeManagers, metrics and a running job

# yarn_arch_lab.sh: look at YARN's parts while a job runs (run on your PC, in the mr-lab folder)
echo "== 1. Java processes (daemons) on each machine"
for c in resourcemanager namenode historyserver worker1; do
  echo "$c: $(docker exec lab8-$c-1 jps 2>/dev/null | awk '{print $2}' | grep -v Jps | sort | tr '\n' ' ')"
done
echo "== 2. what the ResourceManager knows about its NodeManagers"
docker exec lab8-resourcemanager-1 yarn node -list -showDetails 2>/dev/null | grep -E "Node-Id|worker|Resource Utilization|Configured Resources|Allocated" | head -12
echo "== 3. cluster metrics (RM REST API)"
docker exec lab8-namenode-1 curl -s http://resourcemanager:8088/ws/v1/cluster/metrics | python3 -c '
import sys, json; m = json.load(sys.stdin)["clusterMetrics"]
for k in ["activeNodes", "totalMB", "totalVirtualCores", "allocatedMB", "appsRunning", "appsCompleted", "containersAllocated"]: print(f"  {k:20} {m[k]}")'
echo "== 4. start a job and look again while it runs"
docker exec -d lab8-namenode-1 bash -c 'cd /tmp/mr9; hdfs dfs -rm -r -f -skipTrash /out/yarn_arch >/dev/null 2>&1; hadoop jar /tmp/mr/mr.jar ItemRevenue /user/hadoop/data/orders_x90.csv /out/yarn_arch > /tmp/yarn_arch.log 2>&1'
sleep 20
echo "-- processes on worker1 now:"
docker exec lab8-worker1-1 jps 2>/dev/null | awk '{print $2}' | grep -v Jps | sort | uniq -c
docker exec lab8-namenode-1 curl -s http://resourcemanager:8088/ws/v1/cluster/metrics | python3 -c '
import sys, json; m = json.load(sys.stdin)["clusterMetrics"]
print("  allocatedMB", m["allocatedMB"], "of", m["totalMB"], "| allocatedVirtualCores", m["allocatedVirtualCores"], "| containersAllocated", m["containersAllocated"], "| appsRunning", m["appsRunning"])'
app=$(docker exec lab8-resourcemanager-1 yarn application -list 2>/dev/null | grep -o "application_[0-9_]*" | head -1)
att=$(docker exec lab8-resourcemanager-1 yarn applicationattempt -list $app 2>/dev/null | grep -o "appattempt_[0-9_]*" | head -1)
echo "-- containers of $att:"
docker exec lab8-resourcemanager-1 yarn container -list $att 2>/dev/null | grep "^container_" | awk -F'\t' '{print "  " $1, $4, $5}' | tr -s ' ' | head -8
echo "-- per-node view (RM REST /ws/v1/cluster/nodes)"
docker exec lab8-namenode-1 curl -s http://resourcemanager:8088/ws/v1/cluster/nodes | python3 -c '
import sys, json
for n in json.load(sys.stdin)["nodes"]["node"]:
    print("  %-8s used %4d MB / %d MB, %d vcores used, %d containers" % (n["nodeHostName"], n["usedMemoryMB"], n["usedMemoryMB"] + n["availMemoryMB"], n["usedVirtualCores"], n["numContainers"]))'
docker exec lab8-namenode-1 bash -c 'while ! grep -qE "completed|failed" /tmp/yarn_arch.log; do sleep 2; done; grep -E "completed|Launched map" /tmp/yarn_arch.log | sed -E "s/^[0-9-]+ [0-9:]+ INFO  //"'

# Run on your PC, in the mr-lab folder:
#   bash yarn_arch_lab.sh
== 1. Java processes (daemons) on each machine resourcemanager: ResourceManager namenode: NameNode RunJar historyserver: JobHistoryServer worker1: DataNode NodeManager == 2. what the ResourceManager knows about its NodeManagers Node-Id Node-State Node-Http-Address Number-of-Running-Containers worker2:40977 RUNNING worker2:8042 1 Configured Resources : <memory:2048, vCores:2> Allocated Resources : <memory:512, vCores:1> Resource Utilization by Node : PMem:5621 MB, VMem:5621 MB, VCores:1.6533333 Resource Utilization by Containers : PMem:466 MB, VMem:4334 MB, VCores:1.04 worker1:36427 RUNNING worker1:8042 0 Configured Resources : <memory:2048, vCores:2> Allocated Resources : <memory:0, vCores:0> Resource Utilization by Node : PMem:5724 MB, VMem:5724 MB, VCores:1.3062313 Resource Utilization by Containers : PMem:0 MB, VMem:0 MB, VCores:0.0 worker3:44495 RUNNING worker3:8042 0 == 3. cluster metrics (RM REST API) activeNodes 3 totalMB 6144 totalVirtualCores 6 allocatedMB 512 appsRunning 1 appsCompleted 125 containersAllocated 1 == 4. start a job and look again while it runs -- processes on worker1 now: 1 DataNode 1 MRAppMaster 1 NodeManager 1 YarnChild allocatedMB 2560 of 6144 | allocatedVirtualCores 5 | containersAllocated 5 | appsRunning 1 -- containers of appattempt_1792643020992_0135_000001: container_1792643020992_0135_01_000001 RUNNING worker1:36427 container_1792643020992_0135_01_000005 RUNNING worker2:40977 container_1792643020992_0135_01_000004 RUNNING worker3:44495 container_1792643020992_0135_01_000003 RUNNING worker1:36427 container_1792643020992_0135_01_000002 RUNNING worker2:40977 -- per-node view (RM REST /ws/v1/cluster/nodes) worker2 used 1024 MB / 2048 MB, 2 vcores used, 2 containers worker1 used 1024 MB / 2048 MB, 2 vcores used, 2 containers worker3 used 512 MB / 2048 MB, 1 vcores used, 1 containers Job:1765 - Job job_1792643020992_0135 completed successfully Launched map tasks=6

Real output. When we ran it, the previous job (and its client, RunJar) was still finishing, which is why worker2 already held one 512 MB container in step 2 and appsRunning was 1. Your container placement and port numbers (worker1:36427) will differ; the 512 MB rounding and the 6144 MB total will not.

8 Line by line

The Scheduler on each heartbeat

Watch the waiting requests and each node's free memory as three heartbeats arrive. A request is only granted on a heartbeat from a node with enough free space.

Worked examples: real problems, solved and traced in memory

Four YARN sizing and design problems from different industries.

Example 1BeginnerHealthcare · capacity

Will a hospital chain's job run in one wave?

Problem statement

A hospital chain analyses scan metadata with a job of 50 map tasks of 2 GB each. Its YARN cluster has 10 NodeManagers offering 32 GB each. How many 2 GB containers fit at once, and does the job run in a single wave (keep one 2 GB container for the AM)?

Input
10 nodes × 32 GB · 50 maps × 2 GB · AM 2 GB
Expected output
16 per node, 160 in the cluster, 159 for maps -> one wave: True

Approach

  1. Containers per node = node memory / container size.
  2. Cluster containers = per node × nodes.
  3. Subtract the AM and compare with 50.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 2IntermediateE-commerce · rounding

The cost of an awkward container size

Problem statement

During a sale an e-commerce team runs 400 maps asking for 1,100 MB each on a cluster with a 1,024 MB minimum allocation. How much memory is reserved but never asked for? What request size wastes nothing?

Input
400 × 1,100 MB · minimum 1,024 MB
Expected output
each gets 2048 MB, waste 370 GB across 400 containers

Approach

  1. Normalized size = round up to a multiple of 1,024.
  2. Waste per container = normalized - asked.
  3. Multiply by 400.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 3IntermediateTelecom · failures

How long until YARN notices a dead node?

Problem statement

A telecom billing cluster: NodeManagers heartbeat every 1 s; the RM declares a node LOST after 600 s without heartbeats (yarn.nm.liveness-monitor.expiry-interval-ms). A node with 6 running map tasks loses power. When does the RM tell the AMs, and how much task time is lost if each task had run 4 minutes?

Input
heartbeat 1 s · expiry 600 s · 6 tasks × 4 min
Expected output
RM marks the node LOST after 10 min; 24 task-minutes must be redone

Approach

  1. Detection by the RM = expiry interval.
  2. Lost work = tasks × minutes already run.
  3. AMs often notice earlier: their tasks stop reporting progress.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 4AdvancedBanking · multi-tenant

Can Spark and MapReduce share the night?

Problem statement

A bank's 30 workers each give YARN 56 GB and 16 vcores. At 1 AM a Spark job needs a 4 GB driver/AM and 20 executors of 8 GB and 4 vcores. A MapReduce job needs a 1.5 GB AM (normalized to 2 GB with a 1 GB minimum) and 300 maps of 2 GB, 1 vcore. Do both fit at once by memory? By vcores?

Input
30 × (56 GB, 16 vcores) · Spark + MR
Expected output
memory 766/1680 GB fits: True
vcores 382/480 fits: True

Approach

  1. Total cluster memory and vcores.
  2. Sum both jobs' requests.
  3. Compare; vcores only matter with the DominantResourceCalculator.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

9 Quiz and revision

Check yourself

Quick revision

Lesson 11.1 in one screen

  • ResourceManager = Scheduler (who gets what) + ApplicationsManager (accept apps, start/restart AMs). One active per cluster; HA with ZooKeeper.
  • NodeManager per worker: launches and monitors containers, heartbeats to the RM, runs the shuffle service and log aggregation.
  • ApplicationMaster per application: requests containers (size, locality, priority), runs and retries tasks. MRAppMaster, Spark AM/driver, Tez AM.
  • Container = memory + vcores on one node, one process. Requests are rounded up to the minimum allocation.
  • Lab: 3 NMs × (2,048 MB, 2 vcores) = 6,144 MB, 6 vcores; one job held 5 containers, 2,560 MB (AM 512 + 4 × 512).
  • Ports: 8088 RM UI/REST, 8032 clients, 8030 AMs, 8031 NMs, 8042 NM UI.
  • YARN tracks containers, not tasks: that is why it scales and runs any framework.

Interview and viva questions

What are the main components of YARN?

The ResourceManager (with its Scheduler and ApplicationsManager), a NodeManager on every worker, one ApplicationMaster per application, and containers, which are allocations of memory and CPU on a node in which processes run. Optionally a Timeline Server stores application history.

What is the difference between the ResourceManager and the ApplicationMaster?

The ResourceManager is a single cluster-wide service that decides how much memory and CPU each application gets and where. The ApplicationMaster belongs to one application: it asks the ResourceManager for containers and decides which tasks run in them, tracks their progress and retries failures.

What is a container in YARN?

A container is a slice of one node's resources, a given amount of memory and virtual cores, granted by the ResourceManager to an application. The NodeManager starts one process in it (for example a map task JVM or a Spark executor) and enforces its limits.

Why was YARN introduced in Hadoop 2?

In Hadoop 1 the JobTracker both scheduled the cluster and tracked every task of every job, which limited clusters to around 4,000 nodes, and fixed map and reduce slots wasted resources. YARN moves per-job work to ApplicationMasters and replaces slots with flexible containers, so clusters scale further and can run frameworks other than MapReduce.

Can Spark run on YARN?

Yes. In cluster mode the Spark driver runs inside the ApplicationMaster container and executors run in other containers; in client mode the driver runs on the submitting machine and a small AM only requests executors. Hive on Tez, Flink and many other frameworks run on YARN the same way.

Practice problems

YARN architecture exercises using the real numbers from our cluster.

P1Easy

Cluster totals

Each of 3 NodeManagers offers 2,048 MB and 2 vcores. What are the cluster totals the RM reports?

Input
3 × (2048 MB, 2 vcores)
Expected output
6144 MB, 6 vcores
Show solution and explanation
print(3 * 2048, "MB,", 3 * 2, "vcores")
6144 MB, 6 vcores

How it works: 6,144 MB and 6 vcores: totalMB and totalVirtualCores in /ws/v1/cluster/metrics.

P2Easy

Explain 2,560 MB

Show how one AM of 512 MB and four maps asking 384 MB add up to 2,560 MB.

Input
AM 512 · 4 × 384 → rounded
Expected output
2560
Show solution and explanation
import math
map_size = math.ceil(384 / 256) * 256
print(512 + 4 * map_size)
2560

How it works: Each map is rounded to 512 MB: 512 + 4 × 512 = 2,560.

P3Easy

Share of the cluster

What percentage of the cluster's memory did the job hold?

Input
2,560 of 6,144 MB
Expected output
42%
Show solution and explanation
print(f"{2560 / 6144:.0%}")
42%

How it works: About 42%: the rest was free for other applications.

P4Medium

Round these requests

With a 256 MB minimum, what do requests of 100, 256, 300, 600 and 1,100 MB become?

Input
5 requests
Expected output
100 -> 256
256 -> 256
300 -> 512
600 -> 768
1100 -> 1280
Show solution and explanation
import math
for ask in [100, 256, 300, 600, 1100]:
    print(ask, "->", math.ceil(ask / 256) * 256)
100 -> 256 256 -> 256 300 -> 512 600 -> 768 1100 -> 1280

How it works: 256, 256, 512, 768 and 1,280 MB. Lesson 11.4 confirms these on the cluster.

P5Medium

Place on heartbeats

Free memory: w1 512, w2 2048, w3 1024. Heartbeats arrive w1, w2, w3, w2. Place four 1,024 MB containers.

Input
3 nodes, 4 heartbeats
Expected output
granted on w2
granted on w3
granted on w2
still waiting: 1 {'w1': 512, 'w2': 0, 'w3': 0}
Show solution and explanation
free = {"w1": 512, "w2": 2048, "w3": 1024}
waiting = 4
for node in ["w1", "w2", "w3", "w2"]:
    if waiting and free[node] >= 1024:
        free[node] -= 1024; waiting -= 1
        print("granted on", node)
print("still waiting:", waiting, free)
granted on w2 granted on w3 granted on w2 still waiting: 1 {'w1': 512, 'w2': 0, 'w3': 0}

How it works: w1 has no room; w2, w3 and w2 again get one each; one request waits for the next heartbeat with space.

P6Medium

Count the daemons

A cluster has 2 masters (RM + NameNode on one, standby RM on the other) and 50 workers. How many YARN daemons run?

Input
2 RMs + 50 NMs
Expected output
52 YARN daemons (plus one AM per running application)
Show solution and explanation
print(2 + 50, "YARN daemons (plus one AM per running application)")
52 YARN daemons (plus one AM per running application)

How it works: 52 long-running daemons; AMs and task containers come and go with applications.

P7Business problem

One cluster or three?

Three teams each want their own 20-node cluster, each busy about 30% of the time. With one shared 30-node YARN cluster, average demand is 3 × 20 × 0.3 nodes. Compare node counts.

Input
3 × 20 nodes at 30%
Expected output
separate: 60 nodes; shared average demand: 18 nodes -> a 30-node shared cluster leaves headroom
Show solution and explanation
separate = 3 * 20
avg_demand = 3 * 20 * 0.3
print(f"separate: {separate} nodes; shared average demand: {avg_demand:.0f} nodes -> a 30-node shared cluster leaves headroom")
separate: 60 nodes; shared average demand: 18 nodes -> a 30-node shared cluster leaves headroom

How it works: 60 nodes vs 30: sharing through YARN queues halves the hardware (illustrative; peak overlaps need planning, Lesson 11.3).

P8Advanced

Worst-case AM memory

maximum-am-resource-percent is 0.1 by default in the Capacity Scheduler. On our 6,144 MB cluster, how many 512 MB AMs can run at once, and what happens to more applications?

Input
6144 MB · 10% · 512 MB AMs
Expected output
AM limit 614 MB -> 1 AM(s) at once (YARN always allows at least one)
Show solution and explanation
limit = 6144 * 0.1
print(f"AM limit {limit:.0f} MB -> {int(limit // 512)} AM(s) at once (YARN always allows at least one)")
AM limit 614 MB -> 1 AM(s) at once (YARN always allows at least one)

How it works: Only one 512 MB AM fits under 614 MB; further applications stay ACCEPTED until it finishes. This protects clusters from filling up with AMs that have no room for tasks.

Real-world scenario questions (asked in company interviews)

YARN architecture questions come up in every Hadoop and Spark interview.

Architecture · basicsFresher

“Explain the YARN architecture”

Asked in almost every big data interview.

The interviewer is checking: the roles and how they talk.

Show a strong answer
  • ResourceManager (Scheduler + ApplicationsManager) manages cluster resources; NodeManagers run containers on each worker.
  • Each application has an ApplicationMaster that requests containers and manages its own tasks.
  • Flow: submit → AM container → AM registers and requests containers → NMs launch tasks → AM unregisters.
Operations · stuck jobsExperienced

Jobs stay in ACCEPTED and never start

The RM UI shows 15 applications ACCEPTED, cluster memory 40% used.

The interviewer is checking: AM limits and container sizing.

Show a strong answer
  • ACCEPTED means the AM container hasn't been allocated: check the queue's maximum-am-resource-percent and the queue's capacity, not just total free memory.
  • Check that the AM size fits on a single node (free memory may be fragmented across nodes) and is not above maximum-allocation-mb.
  • Look at the application's diagnostics in the RM UI; they name the limit that blocks it.
Design · sizingExperienced

“Our nodes have 128 GB RAM. What should yarn.nodemanager.resource.memory-mb be?”

A new cluster is being set up.

The interviewer is checking: leaving room for everything that isn't a container.

Show a strong answer
  • Subtract the OS, DataNode, NodeManager and other agents (often 8–16 GB), and any co-located services such as HBase.
  • Give the rest to YARN, e.g. about 100–112 GB, and set the minimum allocation so common container sizes divide it evenly.
  • Set vcores to the cores available to containers and use the DominantResourceCalculator if CPU matters (Lesson 11.4).
Reliability · failuresExperienced

“What happens if the ApplicationMaster or the ResourceManager dies?”

A follow-up after the architecture question.

The interviewer is checking: recovery at each level.

Show a strong answer
  • AM dies: the ApplicationsManager starts a new attempt (yarn.resourcemanager.am.max-attempts, default 2); the MapReduce AM can recover finished tasks from its history.
  • RM dies: with RM HA, the standby becomes active through ZooKeeper; with work-preserving recovery running containers continue.
  • NodeManager dies: after the liveness timeout its containers are reported lost and AMs rerun those tasks elsewhere.