Skip to content
MapReduce: Simplified Data Processing on Large Clusters 5 min
Back to Papers

Jeffrey Dean, Sanjay Ghemawat · OSDI 2004

MapReduce: Simplified Data Processing on Large Clusters

Google turned web-scale data processing into two functions: map and reduce. This paper explains how that simple model let a framework handle parallelization, failures, and network efficiency automatically, and became the blueprint for Hadoop and the entire big-data ecosystem.

Read the original paper

Systems & Distributed · beginner · 5 min read

MapReduce: Simplified Data Processing on Large Clusters

By the early 2000s, Google had a recurring problem that had nothing to do with search ranking: hundreds of engineers each needed to process web-scale data (building inverted indexes, computing PageRank, analyzing crawl logs), and each of them was independently rediscovering the same painful infrastructure: how to split work across thousands of machines, how to keep going when some of those machines inevitably crash mid-job, and how to move data between stages without saturating the network.

Jeffrey Dean and Sanjay Ghemawat's answer was not a faster machine or a smarter scheduler. It was a radically restrictive programming model: express your computation as exactly two functions, map and reduce, and let the underlying system handle every distributed-systems headache for you. Constraining the model to something this simple is precisely what made it possible to automate the hard parts.

MapReduce lets you write two simple functions, map and reduce, and the runtime automatically parallelizes them across thousands of machines, handles failures by re-executing tasks, and schedules work near the data it needs to avoid saturating the network.


The programming model: two functions, borrowed from Lisp

The model comes straight from functional programming. The user supplies:

  • map(k1, v1) -> list(k2, v2): takes one input key/value pair and produces zero or more intermediate key/value pairs.

  • reduce(k2, list(v2)) -> list(v2): takes all the intermediate values associated with one intermediate key and merges them into a smaller set of output values.

The canonical example, word counting across a huge collection of documents, is almost embarrassingly small:

map(String key, String value):
    // key: document name, value: document contents
    for each word w in value:
        EmitIntermediate(w, "1")

reduce(String key, Iterator values):
    // key: a word, values: a list of "1"s
    int result = 0
    for each v in values:
        result += ParseInt(v)
    Emit(AsString(result))

Notice what is completely absent from this code: no sockets, no thread pools, no retry logic, no concept of "which machine." The engineer writes sequential-looking code for a single record, and the framework is responsible for turning that into a job running across an entire cluster.

What actually happens underneath

The input, usually sitting in the Google File System (GFS), is automatically split into M pieces (typically 16 to 64 MB each, matching a GFS chunk). A single master process assigns each split to an idle worker machine to run the Map function. Each Map worker writes its intermediate output to local disk, not to the shared filesystem, partitioned into R regions using a partitioning function, by default hash(key)modRhash(key) \bmod R.

Each Map task writes R partitions to local disk. Each Reduce task pulls its one partition from every Map task before running the reduce function.

Once a Map task finishes, the master tells every relevant Reduce worker where to find its partition. Reduce workers pull their partition's data over the network from every Map worker, a phase called the shuffle, sort the combined data by intermediate key (so that all values for the same key are adjacent), and then invoke the user's reduce function once per unique key. Final output is written back to GFS, one file per Reduce task.

Fault tolerance: just redo the work

MapReduce's failure model is refreshingly blunt: with thousands of cheap machines, failures during a large job are not an edge case, they are guaranteed to happen, so the system is built to make re-execution cheap and safe rather than trying to prevent failure entirely.

The master pings every worker periodically. If a worker stops responding:

  • Any Map tasks it completed are reset back to idle and re-executed elsewhere, even if they finished successfully, because their output lived on that worker's local disk and is now unreachable.

  • Any in-progress Reduce task on that worker is reset and reassigned, but completed Reduce tasks are safe, because their output was already written to the shared filesystem (GFS), not local disk.

This asymmetry, redo finished Map work but not finished Reduce work, is a direct consequence of where each stage writes its output. It is a small design detail with a large payoff: it is the difference between "restart part of the job" and "restart the whole job."

When a worker stops responding, its finished Map tasks go back to idle and get re-executed elsewhere, since their output lived only on the dead machine's local disk.

One more failure mode gets special treatment: stragglers, machines that are technically still working but running far slower than their peers (bad disk, contended CPU, flaky network). Near the end of a job, the master schedules backup executions of whichever tasks are still in progress, on other idle machines, and simply takes whichever copy finishes first. The paper reports this alone cut one large sort job's completion time by 44%.

Bringing the computation to the data

Network bandwidth was, and often still is, the scarcest resource in a cluster, far scarcer than CPU or local disk I/O. MapReduce exploits the fact that GFS already stores multiple replicas of every chunk (typically 3) on different machines, and the master uses this to schedule each Map task on, or as close as possible to, a machine that already holds a replica of its input split.

The master prefers scheduling a Map task on a machine that already holds the data locally, avoiding an expensive network transfer for input that is often read exactly once.

For large jobs across a big cluster, this meant the vast majority of input data was read from local disk rather than pulled over the network, which was often the single biggest reason MapReduce could process terabytes of data efficiently on the commodity hardware Google was using at the time.

Why this paper still matters

MapReduce directly inspired Apache Hadoop, which took the same map/shuffle/reduce model open source and became the foundation of an entire industry's big-data tooling for the better part of a decade: Hive, Pig, HBase, and countless data pipelines were all built assuming a MapReduce engine underneath. Google itself eventually moved on to more flexible systems for many workloads, and the broader industry largely followed with Apache Spark, which generalizes MapReduce's rigid two-stage model into arbitrary directed acyclic graphs of operations and keeps intermediate data in memory rather than always touching disk.

What survived, even as the specific engine fell out of fashion, is the vocabulary and the mental model: partitioning work by key, a shuffle phase that regroups data across the cluster, fault tolerance through cheap re-execution rather than expensive coordination, and scheduling for data locality. Any distributed data processing system you touch today, Spark, Flink, even serverless batch pipelines, is having a conversation this paper started.

Key takeaways: express computation as map and reduce over key/value pairs, let the framework parallelize and handle failure by re-executing tasks, partition intermediate data with a shuffle phase, and schedule work near the data to save network bandwidth.

Found this breakdown useful?

Share it with someone else wrestling with this paper.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!

More Papers

Enjoyed this? Get more like it.

New paper breakdowns, levels, and one concept worth knowing, straight to your inbox.

No spam, ever. Unsubscribe in one click.

Enjoyed this content?

Your support keeps us creating free resources

We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.

$

One-time payment via Stripe. ScaleDojo account required.