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.
So the ResourceManager runs my map tasks?
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.
Like a hotel front desk. It never carries your bags; it gives your tour leader the room keys.
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.
YARN: Yet Another Resource Negotiator
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.
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
From our lab (Hadoop 3.5.0, Module 8 cluster)
| Daemons | jps: resourcemanager → ResourceManager · namenode → NameNode · historyserver → JobHistoryServer · worker1 → DataNode, NodeManager |
|---|---|
| Each NodeManager | Configured Resources: <memory:2048, vCores:2> (set by yarn.nodemanager.resource.memory-mb and cpu-vcores) |
| Whole cluster | activeNodes 3 · totalMB 6144 · totalVirtualCores 6 (RM REST API /ws/v1/cluster/metrics) |
| During a 422 MB job | 5 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 node | worker1 1024 MB (AM + 1 map) · worker2 1024 MB (2 maps) · worker3 512 MB (1 map) |
YARN at three levels
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
YarnChildJVM), 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.
The parts of YARN, one by one
Architecture at a glance
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.
| Component | How many | Runs where | Job | Ports (Hadoop 3) |
|---|---|---|---|---|
| ResourceManager | 1 active (+ standby with HA) | Master node | Cluster-wide resource accounting and scheduling | 8088 UI/REST, 8032 clients, 8030 AMs, 8031 NMs, 8033 admin |
| NodeManager | 1 per worker | Every worker (next to a DataNode) | Launch, monitor, kill containers; shuffle service; log aggregation | 8042 UI, 13562 shuffle |
| ApplicationMaster | 1 per application | Inside a container on any worker | Request containers, run and retry the app's tasks | random |
| Container | Many | On workers | One process with a memory and vcore limit | - |
| JobHistory Server | 1 | Master node | History of finished MapReduce jobs (not part of YARN itself) | 19888 |
| Timeline Server | 0 or 1 | Master node | Generic 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.
MapReduceSpark on YARN
In cluster mode the driver runs inside the AM container; executors are long-lived containers that run many tasks each.
SparkTez AM
Runs Hive queries as a graph of steps, reusing containers between them instead of one MapReduce job per step.
HiveFlink / services
Long-running streaming jobs keep their containers for days; YARN restarts the AM if it dies.
streamingAnimated example: a 10 AM rush on a shared cluster
- 10:05: five minutes of Tatkal bookings are in HDFS; an analyst submits a report job to the ResourceManager.
- The ApplicationsManager picks a node with 1 GB free and has its NodeManager start the job's ApplicationMaster.
- The AM looks at its input, finds 6 splits and asks the Scheduler for 6 containers of 2 GB, preferably where the blocks are.
- Each NodeManager heartbeat reports free space; the Scheduler grants 4 containers. Node 4 is full with the booking service.
- When the booking traffic drops, node 4 frees memory and the last two containers are granted.
- 10:12: the report is ready. The AM unregisters and every container goes back to the pool. (Numbers illustrative.)
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.
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”.
Which Java processes run where?
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.for c in resourcemanager namenode historyserver worker1; do echo "$c: $(docker exec lab8-$c-1 jps | awk '{print $2}' | grep -v Jps)" doneresourcemanager: ResourceManager namenode: NameNode RunJar historyserver: JobHistoryServer worker1: DataNode NodeManagerRunJaron the namenode was the client of a job that was still finishing when we looked.What does each NodeManager offer?
“Configured” is what the NodeManager offers to YARN (fromdocker exec lab8-resourcemanager-1 yarn node -list -showDetailsworker2: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>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.Ask the ResourceManager for cluster totals
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.curl -s http://resourcemanager:8088/ws/v1/cluster/metricsactiveNodes 3 totalMB 6144 totalVirtualCores 6 allocatedMB 512 appsRunning 1 appsCompleted 125 containersAllocated 1Start a job and look again
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.hadoop jar mr.jar ItemRevenue /user/hadoop/data/orders_x90.csv /out/yarn_arch & docker exec lab8-worker1-1 jps1 DataNode 1 MRAppMaster 1 NodeManager 1 YarnChild allocatedMB 2560 of 6144 | allocatedVirtualCores 5 | containersAllocated 5 | appsRunning 1List the job's containers
Containeryarn applicationattempt -list application_1792643020992_0135 yarn container -list appattempt_1792643020992_0135_000001container_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…_000001is always the ApplicationMaster. The number in the middle (_01_) is the attempt: if the AM dies, YARN starts attempt 02 with new containers.Per-node usage
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.curl -s http://resourcemanager:8088/ws/v1/cluster/nodesworker2 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
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.
From hadoop jar to five containers
Six steps of our 422 MB job, as the terminal shows them and as YARN handles them.
- The client connects to the ResourceManager on port 8032.
- The application is accepted and its first container, the AM, runs on worker1.
- The AM computes 4 splits: 4 map tasks to place.
- Mid-job the cluster has 5 containers out, 2,560 MB of 6,144.
- On worker1, next to the DataNode and NodeManager: the AM and one map task.
- The job finishes and every container is released.
- The client calls the ResourceManager's ClientRMService. The RM manages 6,144 MB.
- The ApplicationsManager gets a container for the AM and the worker1 NodeManager starts it.
- The AM registers on port 8030 and requests 4 containers; each 384 MB request becomes 512 MB.
- As NodeManagers heartbeat, the Scheduler places the 4 maps on worker1, worker2 (two) and worker3.
- The AM contacts each NodeManager, which starts a YarnChild JVM for the map task.
- When all tasks are done the AM unregisters and all 2,560 MB return to the pool.
YARN at work
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.
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.
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.
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.
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.
Simplified, illustrative examples; organisations differ in tools and policies.
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")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.shReal 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.
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.
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)?
10 nodes × 32 GB · 50 maps × 2 GB · AM 2 GB
16 per node, 160 in the cluster, 159 for maps -> one wave: True
Approach
- Containers per node = node memory / container size.
- Cluster containers = per node × nodes.
- 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.
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?
400 × 1,100 MB · minimum 1,024 MB
each gets 2048 MB, waste 370 GB across 400 containers
Approach
- Normalized size = round up to a multiple of 1,024.
- Waste per container = normalized - asked.
- 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.
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?
heartbeat 1 s · expiry 600 s · 6 tasks × 4 min
RM marks the node LOST after 10 min; 24 task-minutes must be redone
Approach
- Detection by the RM = expiry interval.
- Lost work = tasks × minutes already run.
- 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.
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?
30 × (56 GB, 16 vcores) · Spark + MR
memory 766/1680 GB fits: True vcores 382/480 fits: True
Approach
- Total cluster memory and vcores.
- Sum both jobs' requests.
- 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.
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.
Cluster totals
Each of 3 NodeManagers offers 2,048 MB and 2 vcores. What are the cluster totals the RM reports?
3 × (2048 MB, 2 vcores)
6144 MB, 6 vcores
Show solution and explanation
print(3 * 2048, "MB,", 3 * 2, "vcores")How it works: 6,144 MB and 6 vcores: totalMB and totalVirtualCores in /ws/v1/cluster/metrics.
Explain 2,560 MB
Show how one AM of 512 MB and four maps asking 384 MB add up to 2,560 MB.
AM 512 · 4 × 384 → rounded
2560
Show solution and explanation
import math
map_size = math.ceil(384 / 256) * 256
print(512 + 4 * map_size)How it works: Each map is rounded to 512 MB: 512 + 4 × 512 = 2,560.
Share of the cluster
What percentage of the cluster's memory did the job hold?
2,560 of 6,144 MB
42%
Show solution and explanation
print(f"{2560 / 6144:.0%}")How it works: About 42%: the rest was free for other applications.
Round these requests
With a 256 MB minimum, what do requests of 100, 256, 300, 600 and 1,100 MB become?
5 requests
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)How it works: 256, 256, 512, 768 and 1,280 MB. Lesson 11.4 confirms these on the cluster.
Place on heartbeats
Free memory: w1 512, w2 2048, w3 1024. Heartbeats arrive w1, w2, w3, w2. Place four 1,024 MB containers.
3 nodes, 4 heartbeats
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)How it works: w1 has no room; w2, w3 and w2 again get one each; one request waits for the next heartbeat with space.
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?
2 RMs + 50 NMs
52 YARN daemons (plus one AM per running application)
Show solution and explanation
print(2 + 50, "YARN daemons (plus one AM per running application)")How it works: 52 long-running daemons; AMs and task containers come and go with applications.
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.
3 × 20 nodes at 30%
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")How it works: 60 nodes vs 30: sharing through YARN queues halves the hardware (illustrative; peak overlaps need planning, Lesson 11.3).
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?
6144 MB · 10% · 512 MB AMs
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)")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.
“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.
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.
“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).
“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.