Chapter 3: MapReduce Framework
MapReduce is the distributed data processing framework that sits at the heart of Hadoop. Inspired by Google’s MapReduce paper, it provides a simple yet powerful programming model that abstracts away the complexities of parallel programming, fault tolerance, and data distribution.- Understand the MapReduce programming model
- Master map and reduce phases in detail
- Learn the complete execution flow from job submission to completion
- Explore shuffle and sort mechanisms
- Study fault tolerance and speculative execution
- Compare Hadoop MapReduce with Google’s original implementation
The MapReduce Programming Model
Core Concept
MapReduce is inspired by functional programming concepts, specifically the map and reduce operations:Map and Reduce Functions
- Map Function
- Reduce Function
- Complete Example
MapReduce Execution Architecture
Components
Job Submission Flow
Step 1: Job Submission
Step 1: Job Submission
Step 2: Input Splitting
Step 2: Input Splitting
Step 3: Task Scheduling
Step 3: Task Scheduling
Step 4: Task Execution
Step 4: Task Execution
The Shuffle and Sort Phase
The shuffle is the most complex and critical part of MapReduce—it’s where intermediate data is transferred from mappers to reducers and sorted.Shuffle Architecture
Map-Side Processing
- Partitioning
- Sorting
- Combining
Reduce-Side Processing
- Shuffle/Fetch
- Shuffle Deep Dive
- Merge & Sort
- Reduce
Fault Tolerance in MapReduce
Handling Failures
Task Failure
- Task not reporting progress
- Task sends failure notification
- TaskTracker crashes
- Reschedule task on different node
- Re-execute from beginning (stateless)
- No cascading failures
Node Failure
- No heartbeat for 10 minutes
- JobTracker marks node dead
- All tasks on node marked failed
- Reschedule on healthy nodes
- Even completed map tasks re-run (outputs lost)
Straggler Tasks
- One slow task delays entire job
- Common due to hardware issues, data skew
- Launch duplicate task on different node
- First to complete wins
- Other task killed
JobTracker Failure
- Single point of failure
- Job must restart from beginning
- YARN ResourceManager HA
- Job state checkpointed
- Can resume after failover
Speculative Execution
MapReduce Optimizations
Configuration Tuning
- Memory Settings
- Compression
- Combiners
- Partitioning
Advanced MapReduce Patterns
Common Design Patterns
Filtering
Filtering
Top N
Top N
Join
Join
Secondary Sort
Secondary Sort
Distributed Cache
Distributed Cache
Comparing Hadoop MapReduce with Google’s MapReduce
Key Differences
Why Hadoop Made Different Choices
- Java vs C++
- Open Source
- Evolution
Key Takeaways
- Simple Model, Powerful Abstraction: Map and reduce are simple functions, but framework handles all complexity (distribution, fault tolerance, optimization)
- Shuffle is the Bottleneck: Most optimization focuses on reducing shuffle data (combiners, compression, partitioning)
- Data Locality is Critical: Moving computation to data (not vice versa) is fundamental to MapReduce efficiency
- Fault Tolerance via Stateless Tasks: Re-execution works because tasks are stateless and deterministic
- Speculative Execution Handles Stragglers: Don’t wait for slow tasks—run duplicates and take first result
- Map-Only Jobs for Simple Cases: Not everything needs reduce—filtering, transformation can be map-only
- Combiners are Free Performance: If your reduce is associative/commutative, always use combiner
- Java Enabled the Ecosystem: Performance trade-off was worth it for portability and community growth
Interview Questions
Basic: Explain MapReduce in simple terms
Basic: Explain MapReduce in simple terms
-
Map: Transforms each input record into key-value pairs
- Example: For word count, map(“hello world”) → [(“hello”, 1), (“world”, 1)]
-
Reduce: Aggregates values for each key
- Example: reduce(“hello”, [1, 1, 1]) → (“hello”, 3)
- Automatically parallelizes map and reduce tasks
- Distributes data across cluster
- Handles failures by re-executing tasks
- Optimizes data locality (schedule tasks near data)
- Manages shuffle (moving data from mappers to reducers)
Intermediate: Walk through the shuffle phase in detail
Intermediate: Walk through the shuffle phase in detail
- Buffer: Map outputs go to circular in-memory buffer (default 100MB)
-
Spill: When 80% full, background thread spills to disk
- Partition by reducer (hash(key) % numReducers)
- Sort within each partition
- Optionally run combiner (local aggregation)
- Merge: Multiple spills merged into single sorted file per map task
- Fetch: Reducers fetch their partitions from all mappers via HTTP
- Starts as soon as first map completes (don’t wait for all)
- Parallel copies from multiple mappers (default 5)
-
Merge: Reducer merges fetched data
- Keep small segments in memory
- Spill large segments to disk
- Multi-way merge sort (k-way merge using min-heap)
- Group: Sorted data automatically groups values by key
- Reduce: Call reduce() for each unique key with all its values
- Compression reduces network transfer
- Combiner reduces data volume
- Pipelining (fetch while maps still running)
Advanced: How does speculative execution work and when should you disable it?
Advanced: How does speculative execution work and when should you disable it?
- Monitoring: JobTracker tracks progress of all tasks
-
Straggler Detection: Identifies tasks significantly slower than average
- Based on progress rate, not absolute time
- Considers task has made progress recently
-
Duplicate Launch: Launches speculative copy on different node
- Runs in parallel with original
- Both tasks process same input split
-
Race to Completion: First task to complete wins
- Outputs from winner are used
- Loser task is killed
-
Side Effects: Tasks write to external database
- Duplicate writes could corrupt data
- Non-idempotent operations
-
Resource Constraints: Cluster at full utilization
- No spare slots for speculative tasks
- Would delay other jobs
-
Heterogeneous Hardware: Some nodes intentionally slower
- Speculative execution would waste resources
- Example: mixed SSD and HDD nodes
-
Debugging: Want to see actual task failures
- Speculative execution masks underlying issues
System Design: Design a MapReduce job to find top 10 most frequent words
System Design: Design a MapReduce job to find top 10 most frequent words
- Approach 1: Simpler, reusable word count, but two jobs
- Approach 2: More efficient, less shuffle data, but more complex
- Use combiner in Approach 1 to reduce shuffle
- Consider top 100 per mapper, then top 10 in reducer (reduce network)
- If only need approximate top 10, use sampling
Deep Dive: How would you optimize a MapReduce job that's running slowly?
Deep Dive: How would you optimize a MapReduce job that's running slowly?
- Map time vs reduce time vs shuffle time
- Data skew (some reducers much slower)
- Spill counts (too many disk writes)
- GC time (memory pressure)
- Input Splits: Ensure 1 split = 1 block for locality
- Combiner: Add combiner to reduce map output
- Compression: Compress map output (Snappy)
- Memory: Increase sort buffer (io.sort.mb)
- Avoid Small Files: Combine small files before processing
- Compression: Always compress intermediate data
- Combiner: Reduces shuffle volume dramatically
- Fetch Parallelism: Increase parallel copies
- Memory: Increase shuffle buffer percentage
-
Number of Reducers:
- Too few: Reducers become bottleneck
- Too many: Overhead, small output files
- Rule of thumb: 0.95 or 1.75 × (nodes × max containers per node)
-
Skew Handling:
- Use better partitioner
- Salt skewed keys
- Increase reducers
- Memory: Increase reducer heap size
- Avoid object creation in map/reduce
- Reuse Writable objects
- Use efficient data structures
- Profile with JVM profiler
- Slots: Ensure map/reduce slots properly configured
- Locality: Check data locality percentage
- Speculative Execution: Enable for stragglers
- JVM Reuse: Reuse JVMs for multiple tasks
Further Reading
MapReduce Paper
Hadoop Documentation
Data-Intensive Applications
Hadoop: The Definitive Guide
Up Next
In Chapter 4: YARN, we’ll explore:- How Hadoop 2.x evolved beyond MapReduce
- ResourceManager and NodeManager architecture
- Generic resource management for multiple frameworks
- ApplicationMaster pattern
- How YARN enables Spark, Flink, and other frameworks
Interview Deep-Dive
The shuffle phase is often the biggest bottleneck in MapReduce. Walk me through why, and how you would optimize it.
The shuffle phase is often the biggest bottleneck in MapReduce. Walk me through why, and how you would optimize it.
Explain speculative execution in MapReduce. When does it help, and when does it actually hurt performance?
Explain speculative execution in MapReduce. When does it help, and when does it actually hurt performance?
MapReduce forces everything into a map-then-reduce pattern. What workloads does this fit poorly, and what alternatives emerged?
MapReduce forces everything into a map-then-reduce pattern. What workloads does this fit poorly, and what alternatives emerged?