intermediate
Narrow vs Wide Transformations
8 min read
Overview
Learn to distinguish between Narrow Transformations (which run locally on partitions) and Wide Transformations (which force network shuffles).
What You Will Learn
In this lesson, you will learn:
- Narrow Transformations: Map-side transformations with no network dependencies.
- Wide Transformations: Operations requiring network shuffles.
- Performance Impacts: Why minimizing shuffles improves query speed.
Detailed Concept Explanation
Spark transformations are categorized into narrow or wide based on their partition dependencies.
Narrow Transformations
- Behavior: Each input partition maps to at most one output partition. The data does not leave the executor node.
- Examples:
map(),filter(),flatMap(),union(),select(). - Performance: Very fast, as operations run in parallel across partitions with zero network I/O.
Wide Transformations
- Behavior: Multiple input partitions map to multiple output partitions. Records with matching keys are routed across nodes. This network reorganization is called a Shuffle.
- Examples:
groupBy(),join(),repartition(),distinct(). - Performance: Expensive due to network latency, disk serialization, and synchronization barriers.
Code Examples
Python (PySpark) Implementation
python
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("NarrowWide").getOrCreate()
df = spark.createDataFrame([("A", 1), ("B", 2)], ["key", "val"])
# Narrow: filter keeps data on same partition
narrow_df = df.filter(df.val > 1)
# Wide: groupByKey shuffles data across network
wide_df = df.groupBy("key").count()
Execution Plan Diagram (Python & Scala)
Execution Plan Diagram
SparkSession.builder
createDataFrame
filter(val > 1) [Narrow]
groupBy(key).count() [Wide - Shuffle]
Scala Implementation
scala
import org.apache.spark.sql.SparkSession
val spark = SparkSession.builder().appName("NarrowWideScala").getOrCreate()
import spark.implicits._
val df = Seq(("A", 1), ("B", 2)).toDF("key", "val")
val narrow = df.filter($"val" > 1)
val wide = df.groupBy("key").count()
Interview Perspective
What is the difference between a narrow and a wide dependency in Spark?
A narrow dependency means each partition of the child RDD/DataFrame depends on at most one partition of the parent, requiring no network shuffles (e.g. map, filter). A wide dependency means child partitions depend on multiple parent partitions, forcing data to be shuffled across nodes over the network (e.g. groupBy, join).