Part III — Batch processing · Chapter 5

The Data Lake, YARN and Hadoop MapReduce

~35 min read6 interactive widgets4 plates

In this chapter

  1. The Big Data flow and the Data Lake
  2. Organising the lake: areas and medallions
  3. Why you need a resource negotiator
  4. YARN: the two daemons and the application master
  5. Data locality
  6. The YARN walkthrough
  7. YARN schedulers
  8. Hadoop MapReduce: the job
  9. MapReduce execution in detail
  10. Coping with node failures
  11. The limitations that produced Spark
  12. Test your knowledge

1. The Big Data flow and the Data Lake

Chapters 3 and 4 gave us a place to put bytes and a way to compute over them. This chapter is about everything in between: how the data is organised once it lands, and who decides where and when each task actually runs.

The deck opens with a map of the whole flow, and it is worth reading as a picture of the entire course. On the left, data enters either as near-real-time streams or through ETL. Streams pass through an event-driven service bus (e.g., Kafka) and a streaming engine (e.g., Spark Streaming, Storm) into real-time processing. In parallel, batch processing feeds analytics (e.g., Spark, Cloudera, Flink) and interactive applications (e.g., NoSQL, NewSQL). And underneath all of it, holding everything together, sits the Data Lake — a Distributed File System plus DBMSs.

Editor’s note

Use that picture as a table of contents for the rest of these notes. The batch branch is Chapters 5 to 9; the streaming branch, with Kafka and the event bus, is Chapter 10; the interactive branch with NoSQL and NewSQL is Chapter 11; and the governance question that this whole diagram raises — who keeps it from becoming a mess — is Chapter 12.

The original idea, and the swamp

The Data Lake started as a deliberately minimal proposal:

Key idea — the original definition

In the original idea, the Data Lake was just a central repository system for storage, processing and analysis of raw data, in which the data is kept in its original format and is processed to be queried only when needed.

The appeal is obvious: no schema to agree on before ingestion, no transformation cost paid for data nobody may ever query, no loss of information from an early normalisation. The catch is equally obvious in hindsight. Soon it became clear that — in the absence of organization and governance — the Data Lake could easily become a Swamp (Couto, Borges, Ruiz, Marczak, Prikladnicki, A mapping study about data lakes: An improved definition and possible architectures, Proc. SEKE, Lisbon, 2019).

A swamp is a lake in which the data is still all there and nobody can find, trust or interpret any of it. Deferring the schema does not delete the work of understanding the data; it just moves that work to the moment of the query, and multiplies it by the number of people who ask.

2. Organising the lake: areas and medallions

The remedy is structure. To facilitate data governance, the Data Lake can be partitioned into areas, representing the processing state of the data. Note the criterion carefully — the areas are not divided by subject or by owner, but by how far along the pipeline a dataset has travelled.

AreaWhat it contains
LandingWhere data are stored immediately after ingestion
WorkingTemporary tables and configuration data
HarborData (completely or partially) processed from the landing area
DiscoveryData created by data scientists for experimental purposes; it serves as a safe sandbox, where data is only taken from (and not published to) other areas
AccessData ready to be accessed by reporting and visualization tools

Francia, Gallinucci, Golfarelli, Leoni, Rizzi, Santolini, “Making data platforms smarter with MOSES”, Future Generation Computer Systems 125 (2021): 299–313.

The Discovery area is the interesting one. Its rule is a one-way valve: data scientists may read from any area, but what they produce stays inside Discovery and is never published back. That single constraint is what lets exploration be genuinely free without contaminating the datasets that reporting depends on — the experiment cannot leak into production by accident.

The medallion architecture

A common reference today is the medallion architecture, which compresses the same idea into three named layers:

LayerDefinition
BronzeWhere data are stored immediately after ingestion; a common practice here is to apply only minimal transformations on the data (e.g., type conversions)
SilverContains data processed from the bronze layer; it represents the point at which raw data is filtered, cleaned and “dressed up” (augmented) by joining across one or many other tables
GoldContains data ready to be accessed by reporting and visualization tools; it is purpose-built to solve explicit intended business goals

Strengholt, P., Building Medallion Architectures: Designing with Delta Lake and Spark, O’Reilly Media, 2025.

Data Lake areas and the medallion mapping On the left, the five data lake areas stacked from Landing at the bottom to Access at the top, with Working alongside and Discovery as a sandbox that only receives data. On the right, the three medallion layers Bronze, Silver and Gold, aligned with Landing, Harbor and Access. DATA LAKE AREAS MEDALLION Landing Area Working Harbor Access Area Discovery Area a sandbox: reads from everywhere, publishes to nowhere Bronze Silver Gold Landing = Bronze = Source layer  ·  Harbor = Silver = Reconciled layer  ·  Access = Gold = Warehouse layer
Plate 5.1 — The same pipeline named twice. Both schemes sort data by processing state, not by subject: raw at the bottom, business-ready at the top. The dashed vermilion box is the one structural idea neither scheme can do without — a place where experiments cannot contaminate anything downstream.

Is this just a data warehouse again?

The deck asks the question directly: is the medallion architecture just a “revamped” version of the 3-layer data warehouse architecture? The correspondence is exact:

Data Lake areaMedallion levelData warehouse layer
Raw areaBronzeSource layer
Harbor areaSilverReconciled layer
Access areaGoldWarehouse layer

Golfarelli, M. and Rizzi, S., Data Warehouse design: Modern principles and Methodologies, McGraw-Hill, New York, 2009.

And the answer the slides give is honest: “Perhaps. Ultimately, there is no universal number of areas/levels/layers.” The basic philosophy is common; then you specialize it based on the complexities within your organization and data pipelines.

For the exam

If asked to compare the Data Lake with the Data Warehouse, do not fall into the “lake = new, warehouse = old” trap. The layered organisation is the same idea in both: raw → reconciled → ready-to-serve. What genuinely differs is when the structure is imposed — the warehouse transforms on ingestion (schema-on-write), the lake keeps the original format and transforms on query (schema-on-read) — and the discipline required to stop the second one from becoming a swamp.

3. Why you need a resource negotiator

Chapter 4 described map and reduce tasks as though they simply happened. The deck now asks the three questions that were quietly postponed:

The answer is a component with a specific job description. The Resource Negotiator:

Apache YARN — Yet Another Resource Negotiator — is Hadoop’s cluster resource management. It was introduced in Hadoop 2 to improve the MapReduce implementation, and — this is the part that matters historically — it is general enough to support other distributed computing paradigms.

Key idea — why YARN outlived MapReduce

YARN provides APIs for requesting and working with cluster resources, and these APIs are typically used by distributed computing frameworks (e.g., MapReduce, Spark), NOT by user code. That single design decision is why Spark could later arrive and take over the computation layer without anyone having to replace the cluster underneath: YARN does not know what a map task is. It knows about containers with CPU and memory, and it will hand them to whoever asks.

4. YARN: the two daemons and the application master

YARN provides its core services via two types of long-running daemons:

DaemonScopeResponsibility
Resource Manager (RM) Global — one per cluster The ultimate authority that arbitrates resources among all the applications
Node Manager (NM) Per-node slave Responsible for containers. Monitors the resource usage of containers (e.g., CPU, memory) and reports them to the RM

A container is an abstract entity, used to execute an application-specific process with a constrained set of resources. It is the unit of everything in YARN: allocation, isolation, accounting and failure.

The application master process

Upon request from a client, the RM finds a NM that can launch the application master process (AMP) in a container. The AMP:

YARN daemons, containers and application masters A single Resource Manager above a grid of Node Managers. Two applications are colour-separated: each has one application master process running inside an ordinary container, plus several task containers spread over different nodes. Resource Manager one per cluster · arbitrates resources Node Manager Cont1 · AMP-A Cont2 · Task A1 Node Manager Cont1 · Task A2 Cont2 · Task B1 Node Manager Cont1 · AMP-B Cont2 · Task A3 Node Manager Cont1 · Task B2 (free capacity) Node Manager Cont1 · Task B3 Node Manager (free capacity) Node Manager Cont1 · Task A4 Node Manager (free capacity) application A: AMP-A requests and drives its own task containers application B: AMP-B does the same, independently note: an AMP is not a special machine — it is an ordinary container that happens to run the coordinator
Plate 5.2 — The Resource Manager hands out containers; everything else is containers. Each application gets its own application master, itself running in a container on some Node Manager, and that master — not the RM — negotiates and drives the containers of its own tasks. This is how one cluster runs many jobs without a central bottleneck.
For the exam

The most-missed point about YARN is why the AMP exists at all. If the RM scheduled every task of every job directly, it would become a bottleneck and a single point of failure for progress. Instead the RM does one coarse thing per application — start an AMP — and the per-application AMP does the fine-grained work of requesting, launching and monitoring containers. The RM arbitrates between applications; the AMP manages within one.

5. Data locality

Where a container is placed is not an arbitrary choice. YARN exploits cluster topology and data block replication to apply the data locality principle:

Key idea — the data locality principle

When computations involve a large set of data, it is cheaper (i.e. faster) to move code to data rather than data to code.

A map task is a few hundred kilobytes of JAR; its input split is 128 MB. Shipping the former is free, shipping the latter is the job. The following cases respect the order the resource manager prefers:

#PlacementWhat it costs
1Process and data on the same nodeNo network at all: a local disk read
2Process and data on different nodes of the same rackOne hop over the fast intra-rack link
3Process and data on different racks of the same data centerCrosses the aggregation layer, where bandwidth is scarcer
4Process and data on different racks of different data centersThe worst case: wide-area transfer of a whole split
The data locality preference ladder Four nested scopes drawn as concentric rounded rectangles: same node innermost, then same rack, then same data center, then different data centers, with the transfer cost rising outward. 4 · different racks, different data centers 3 · different racks, same data center 2 · different nodes, same rack  (rack-local) 1 · same node  (data-local) the code is moved to the data: no transfer preference cost of moving the data replication gives the scheduler three candidate nodes per block, so level 1 or 2 is usually reachable
Plate 5.3 — The locality ladder. Every step outward multiplies the transfer cost, following the bandwidth gradient of Chapter 2. The reason the scheduler usually succeeds is Chapter 3: because each block has three topology-aware replicas, there are three chances to land in the green box instead of one.

Where did this task land?

Pick where the free container is, relative to the node holding the input split, and see how MapReduce classifies the placement.

Editor’s note

Data locality is the point where all three previous chapters meet. Chapter 2 said intra-rack bandwidth is much greater than inter-rack bandwidth — that is why the ladder has these rungs. Chapter 3 said replication is topology-aware and the NameNode knows which DataNodes hold each block — that is what makes the choice possible. Chapter 4 said the optimal split size equals the DFS block size — that is what makes one task correspond to one local block. Remove any of the three and locality stops working.

6. The YARN walkthrough

Application execution consists of three movements: the client submits the application, the RM bootstraps the AMP instance, and the AMP instance manages the application execution. In eight steps:

  1. A client program submits the application, including the necessary specifications to launch the application-specific AMP itself.
  2. The RM negotiates a specified container in which to start the AMP, and then launches it.
  3. The AMP, on boot-up, registers with the RM. After asking details to the RM, the client program is able to communicate directly with its own AMP.
  4. During normal operation, the AMP negotiates appropriate resource containers.
  5. On successful container allocations, the AMP launches the container by providing the container launch specification to the NM, including information to enable communications with the AMP.
  6. The application code executing within the container provides necessary information (progress, status, etc.) to its AMP.
  7. During the application execution, the client communicates directly with the AMP to get status, progress updates, etc.
  8. Once the application is complete, the AMP deregisters with the RM and shuts down, allowing its own container to be repurposed.

Walk the eight steps

Advance through the sequence and watch which component is acting at each moment. Notice how quickly the Resource Manager drops out of the picture.

Key idea

Follow the client through those eight steps. It talks to the RM exactly once, in step 1, and after step 3 it never talks to it again — all progress reporting goes directly to the AMP. Follow the RM and the pattern is the same: it launches one container per application and then steps aside. This is the architecture of a system designed for thousands of concurrent tasks: the global authority is deliberately kept out of every hot path.

7. YARN schedulers

Deciding which application gets the next free container is a policy question, not a mechanism one, so YARN provides a choice of schedulers and configurable policies.

Simple to understand, no configuration needed. Applications are served in the order they arrive.

Not suitable for shared clusters. One long job at the head of the queue starves everything behind it — a five-hour ETL blocks a five-second query, which is intolerable the moment more than one team uses the cluster.

Reserves a fixed amount of capacity to each job. The cluster is carved into guaranteed shares, so a small interactive job always has somewhere to run, regardless of what else is queued.

The cost of a guarantee is rigidity: capacity reserved for a queue that is currently idle is capacity nobody is using.

Dynamically balances the available resources between all running jobs. Rather than reserving shares up front, it continuously redistributes: with one job running, that job gets everything; when a second arrives, resources are rebalanced between them.

8. Hadoop MapReduce: the job

Now the implementation of the paradigm from Chapter 4. Recall the definition by Dean and Ghemawat (Google): MapReduce is a programming model and an associated implementation for processing and generating large data sets — and Hadoop MapReduce is an open-source implementation of the MapReduce programming model.

A MapReduce program, referred to as a job, consists of:

Each MapReduce job is divided by the system into smaller units called tasks — map tasks and reduce tasks. The tasks are scheduled using YARN and run on nodes in the cluster, and if a task fails, it will be automatically rescheduled to run on a different node.

A map in Java

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private static final IntWritable one = new IntWritable(1);
    private Text word = new Text();
    public void map(LongWritable key, Text value, Context context)
       throws IOException, InterruptedException {
        String line = value.toString();
        StringTokenizer tokenizer = new StringTokenizer(line);
        while (tokenizer.hasMoreTokens()) {
          word.set(tokenizer.nextToken());
          context.write(word, one);
        }
    }
}

A reduce in Java

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    public void reduce(Text key, Iterable<IntWritable> values, Context context)
       throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable value : values) {
          sum += value.get();
        }
        context.write(key, new IntWritable(sum));
    }
}

Compare this signature with the abstract one from Chapter 4: reduce (k2, list(v2)) → list(k3, v3). The Iterable<IntWritable> values is the list(v2) — the framework has already collected, shuffled and sorted every value emitted for this key, from every map task in the cluster, before this method is called even once.

The job in Java

public class WordCount {
 public static void main(String[] args) throws Exception {
        Job job = new Job(new Configuration(), "WordCount");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        job.waitForCompletion(true);
    }
}
Key idea

Those three listings are the entire what. There is not one line about which machine runs what, how the intermediate pairs travel, or what happens when a node dies mid-job. All of that is the how, and it is the subject of the next section. This is the founding compromise of Chapter 1 made concrete: you write forty lines of domain logic, and you accept that you do not control the execution.

9. MapReduce execution in detail

The important idea behind MapReduce is separating the what of distributed processing from the how. We have seen the former; now the latter.

The developer launches the job on the client’s JVM, which contacts the YARN RM to submit the application. The execution framework takes care of everything else: it transparently handles all aspects of distributed code execution, on clusters ranging from a single node to a few thousand nodes.

The MapReduce job execution sequence A swimlane diagram with five lanes — client, Resource Manager, Node Manager hosting the application master, Node Manager hosting a task, and the distributed file system — crossed by the numbered steps from job submission to task execution. client JVM Resource Mgr NM · AMP NM · task DFS 1 waitFor…() 2 app ID 3 JAR, conf, splits 4 submit · 5a 6 AMP starts 7 read splits 8 ask containers 9a·9b launch 10 load · 11 run job submission job initialization task assignment & execution the job JAR goes to the DFS with a default replication factor of 10
Plate 5.4 — The execution sequence across five actors. The client only submits; the Resource Manager only bootstraps; the application master does the negotiating; the task containers do the work — and the DFS is touched at three separate moments, for the job resources, the split metadata and the actual input data.

Job submission

StepWhat happens
1The MapReduce program calls either the submit() or waitForCompletion() method to create the Job.
2The Job contacts the RM to get an application ID.
3The Job copies to the DFS the resources needed to run the job: configuration file, JAR file, input splits metadata. The job JAR is copied with a default replication factor of 10, so that NMs can easily access it.
4The application is submitted to the RM.
Editor’s note — why replication 10

Chapter 3 established that the default replication factor is 3. The job JAR gets 10 because its access pattern is the opposite of a data block: instead of one task reading one block, potentially hundreds of Node Managers need this same small file at almost the same instant. More replicas means more nodes that can serve it in parallel, and a much better chance that each NM finds a copy locally. It is replication used for read throughput, not for durability.

Job initialization

StepWhat happens
5aThe YARN Scheduler (called by the RM) allocates a container on a NM to host the AMP — called MRAppMaster in the reference picture.
6The AMP is launched in the container.
7Input split data are identified on the DFS.

At this point the AMP evaluates the amount of resources required to run the job, and asks itself two questions: how many containers are necessary? and is the parallelization worth the overhead? For a small enough input, the answer to the second question is no — starting containers across a cluster costs more than simply running the job where it stands.

Task assignment

Step 8: the AMP requests containers for map (and reduce) tasks. Two rules govern the order:

The RM tries to honor the data locality constraint for map tasks, distinguishing three cases:

CaseDefinition
Data-localThe task is run on the same node that the input split resides on
Rack-localThe task is run on a different node in the same rack that the input split resides on
NeitherSome tasks are neither data-local nor rack-local
For the exam

Both scheduling rules in step 8 have a reason worth stating. Maps first, with higher priority, because no reducer can finish before every mapper has emitted its pairs — allocating reducers early would just hold containers idle. But reduce tasks start at 5% of map completion, not at 100%, because the shuffle can begin as soon as some map output exists: overlapping the transfer with the remaining map work hides most of the network cost. It is a deliberate compromise between not wasting containers and not serialising the two phases.

Task execution

StepWhat happens
9aThe AMP starts the containers by contacting the NMs, in accordance with the assignments made by the RM.
9bThe container is initialized to run the map (or reduce) task.
10The task loads the required resources: configuration file, JAR file, input data.
11The map (or reduce) task is run. Code execution is isolated within the container: any bug or failure will not affect the NM.

Progress and status updates

Jobs may take from tens of seconds to hours to run, so a job and each of its tasks carry a status, which includes:

Watch out

The three reduce bands are a favourite exam detail, and they explain a phenomenon everybody who has watched a Hadoop console has seen: a reduce sitting at 33% for a very long time. That is not the reduce function being slow — it is the shuffle, i.e. the network transfer of map output, which is the expensive part. The user-defined reduce logic does not begin until the last third of the bar.

Job completion

10. Coping with node failures

Chapter 3 said that on commodity hardware failure is the norm rather than the exception. Here is the compute-side counterpart of that statement. Note that who detects the failure depends on what failed:

FailureDetected and managed byWhat happens
Failure of a worker the AMP The tasks assigned to this worker will have to be redone — and in case of a reduce failure, the map tasks that produced its input may have to be redone as well. The AMP sets the status of each failed task to idle and reschedules them on a worker when one becomes available.
Failure of the AMP the RM Job history is used to recover the state of the tasks that were already run. Worst case: the entire map-reduce job must be restarted.
Key idea — why a reduce failure can cost map work

Recall from Chapter 4 that map output is intermediate output stored on the local disk, deliberately not in HDFS with replication, because that would be overkill. The consequence appears exactly here: when a worker dies, the map output it was holding dies with it. If a reducer needed those pairs, they no longer exist anywhere, and the corresponding map tasks must be re-executed to regenerate them. The storage decision and the recovery cost are two sides of one trade-off.

What the runtime handles

Stepping back, this is the complete list of what the MapReduce “runtime” does on your behalf:

ConcernWhat it means
SchedulingAssigns workers to map and reduce tasks
Data distributionGets data to the workers
SynchronizationGathers, sorts and shuffles intermediate data
Errors and faultsDetects container failures and restarts

And everything happens on top of a DFS.

11. The limitations that produced Spark

Hadoop’s MapReduce is the result of many years of development — and that is precisely the problem. Follow the dates backwards:

In the meanwhile, a lot changed:

Against that backdrop, two families of limitation stand out.

Hardware resources are not adequately exploitedThe paradigm is strict
  • Every MapReduce job ends by saving results to HDFS, which is slow.
  • No possibility to keep data in RAM.
  • Multi-core architecture not easily exploited.
  • End result: it is slow.
  • Everything has to fit into Map and Reduce → programming is not straightforward.
  • Complex algorithms take multiple jobs and passes on hard disk.
  • Not suitable for iterative algorithms or interactive processing.

The picture that makes it concrete

The deck puts the two data-processing models side by side. In MapReduce, every iteration is an HDFS read, the computation, and an HDFS write; the next iteration reads it all back. Every interactive query re-reads the input from HDFS from scratch. The caption is blunt: slow due to data replication and disk I/O. Remember that an HDFS write is not one disk write — with replication factor 3, it is three, two of them across the network.

In Spark, the input is read once with one-time processing, and then every iteration and every query runs from what is already in memory: 10–100× faster than network and disk.

Count the HDFS round trips

Set the number of iterations of an algorithm and compare how many times each model touches the distributed file system.

For the exam

“Why is Hadoop MapReduce slow for iterative algorithms?” has a two-part answer, and most people give only the first. Part one: results are persisted to HDFS between jobs, so an n-iteration algorithm pays 2n distributed-storage operations, each write replicated three times. Part two: the paradigm itself is strict — an algorithm that does not decompose into map and reduce must be expressed as a chain of separate jobs, and it is the chain, not any single job, that creates those round trips. Spark attacks both: RDDs can stay cached in RAM, and the API is not limited to two functions.

That is the bridge to the next chapter. Everything in Chapter 6 — resilient distributed datasets, lazy evaluation, the DAG, caching — is an answer to one of the bullet points above.

Test your knowledge

What was the original idea of the Data Lake, and how does it become a swamp?

Originally the Data Lake was just a central repository system for storage, processing and analysis of raw data, in which data is kept in its original format and is processed to be queried only when needed. It becomes a swamp in the absence of organization and governance: the data is all still there, but nobody can find, trust or interpret it. Deferring the schema does not remove the work of understanding the data — it moves that work to query time and multiplies it by the number of people asking.

List the five areas of an organised Data Lake and explain what makes the Discovery area special.

Landing (data stored immediately after ingestion), Working (temporary tables and configuration data), Harbor (data completely or partially processed from the landing area), Discovery (data created by data scientists for experimental purposes), Access (data ready to be accessed by reporting and visualization tools). The areas represent the processing state of the data. Discovery is special because it is a safe sandbox where data is only taken from, and not published to, other areas — a one-way valve that lets experimentation be free without contaminating anything downstream.

Map the medallion layers onto the data lake areas and the data warehouse layers.

Raw area = Bronze = Source layer; Harbor area = Silver = Reconciled layer; Access area = Gold = Warehouse layer. Bronze holds data immediately after ingestion with only minimal transformations such as type conversions; Silver is where raw data is filtered, cleaned and augmented by joining across one or many other tables; Gold is purpose-built to solve explicit intended business goals. Is medallion just a revamped 3-layer warehouse? “Perhaps” — there is no universal number of areas, levels or layers; the basic philosophy is common and you specialize it based on the complexities of your organization and pipelines.

What does a resource negotiator do, and why is YARN not tied to MapReduce?

It has a global view of the cluster resources; decides where and when each unit of work is allocated and with how many resources (CPU and RAM); uses a scheduling policy to manage concurrency; avoids over-instantiation of processes on the same worker; and handles fault tolerance. YARN was introduced in Hadoop 2 to improve the MapReduce implementation but is general enough to support other distributed computing paradigms, because its APIs for requesting cluster resources are used by frameworks (MapReduce, Spark) and not by user code. YARN allocates containers with CPU and memory; it does not know what a map task is.

Describe the two YARN daemons and the role of the application master process.

The Resource Manager is global, one per cluster, and is the ultimate authority that arbitrates resources among all applications. The Node Manager is a per-node slave responsible for containers — abstract entities used to execute an application-specific process with a constrained set of resources — and it monitors their CPU and memory usage and reports to the RM. On a client request, the RM finds a NM that can launch the AMP in a container; the AMP controls the execution of one application, requests further containers dynamically to run the distributed computation, and offloads the burden from the RM. The RM arbitrates between applications, the AMP manages within one.

State the data locality principle and the four preference levels.

When computations involve a large set of data, it is cheaper (i.e. faster) to move code to data rather than data to code. Preference order: (1) process and data on the same node; (2) process and data on different nodes of the same rack; (3) process and data on different racks of the same data center; (4) process and data on different racks of different data centers. It works because block replication is topology-aware, so the scheduler has three candidate nodes per block rather than one.

Walk through the eight steps of a YARN application, and say when the client stops talking to the Resource Manager.

(1) The client submits the application including the specifications to launch the AMP. (2) The RM negotiates a container in which to start the AMP and launches it. (3) The AMP registers with the RM on boot-up; after asking the RM for details, the client can communicate directly with its own AMP. (4) The AMP negotiates appropriate resource containers. (5) On successful allocation the AMP launches the container by giving the launch specification to the NM. (6) The application code in the container reports progress and status to its AMP. (7) The client communicates directly with the AMP for status and progress. (8) On completion the AMP deregisters with the RM and shuts down, letting its container be repurposed. The client contacts the RM only in step 1 and, after step 3, deals exclusively with its AMP.

What are the four steps of job submission, and why is the job JAR replicated ten times?

(1) The program calls submit() or waitForCompletion() to create the Job. (2) The Job contacts the RM to get an application ID. (3) The Job copies to the DFS the resources needed to run the job — configuration file, JAR file, input splits metadata. (4) The application is submitted to the RM. The JAR is copied with a default replication factor of 10 so that Node Managers can easily access it: unlike a data block read by one task, this small file is needed almost simultaneously by many NMs, so extra replicas buy parallel read throughput and a better chance of a local copy — replication for performance, not durability.

In task assignment, why are map tasks requested first, and why do reduce tasks start at 5%?

Requests for map tasks are made first and with higher priority because no reducer can complete before the mappers have emitted their pairs, so allocating reducers early would hold containers idle. But reduce tasks are requested once 5% of the map tasks have completed, rather than 100%, because the shuffle can begin as soon as some map output exists — overlapping the network transfer with the remaining map work hides most of its cost.

What do the three reduce progress bands mean?

The progress of a reduce is an estimate of the proportion of the reduce input processed, divided into 0–33% shuffling, 34–66% sorting, 67–100% reducing. This is why a reduce can appear stuck at around 33%: that is the shuffle, i.e. the network transfer of map output from every mapper, and the user-defined reduce function does not start running until the final third.

Who handles a worker failure, who handles an application master failure, and why can a reduce failure cost map work?

A worker failure is detected and managed by the AMP: the tasks assigned to that worker must be redone, the AMP sets each failed task to idle and reschedules it on a worker when one becomes available. An AMP failure is detected and managed by the RM: job history is used to recover the state of the tasks already run, and in the worst case the entire job must be restarted. A reduce failure can force map re-execution because map output is intermediate data written to the local disk, not to HDFS with replication — when the node holding it dies, those pairs no longer exist anywhere and the corresponding map tasks must regenerate them.

List the two families of limitation of Hadoop MapReduce that motivated Spark.

Hardware resources are not adequately exploited: every MapReduce job ends by saving results to HDFS which is slow; there is no possibility to keep data in RAM; the multi-core architecture is not easily exploited; the end result is that it is slow. The paradigm is strict: everything has to fit into map and reduce so programming is not straightforward; complex algorithms take multiple jobs and passes on hard disk; and it is not suitable for iterative algorithms or interactive processing. In MapReduce every iteration reads from and writes to HDFS (slow due to data replication and disk I/O), whereas Spark reads once and then works from memory, 10–100× faster than network and disk.