Apache Spark: Distributed Data Processing & PySpark Guide
Apache Spark is the leading unified analytics engine for large-scale data processing, combining batch processing, streaming, SQL, machine learning, and graph computation in a single framework. Process petabytes across thousands of nodes with in-memory speed.
What is Apache Spark?
Apache Spark is an open-source, distributed computing framework originally developed at UC Berkeley's AMPLab in 2009. It provides a unified API for batch processing, streaming, SQL queries, machine learning (MLlib), and graph processing (GraphX). Spark's core innovation is in-memory computation — intermediate results are kept in RAM across transformation steps rather than written to disk like Hadoop MapReduce, making it 10–100x faster for iterative workloads.
Spark can run on a local machine, a standalone cluster, YARN, Mesos, or Kubernetes. Managed services like Databricks, Amazon EMR, Google Dataproc, and Azure HDInsight run Spark at scale without cluster management overhead. PySpark is the Python API and the most widely used interface — it provides the full DataFrame, Spark SQL, and Streaming API with Python syntax.
PySpark DataFrame Quickstart
# pip install pyspark
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, sum as spark_sum, avg, count
# Initialize SparkSession
spark = SparkSession.builder .appName("Sales Analysis") .config("spark.sql.shuffle.partitions", "200") .getOrCreate()
# Read data (Parquet, CSV, JSON, Delta, JDBC...)
df = spark.read.parquet("s3://my-bucket/sales/")
# DataFrame transformations (lazy — nothing executes yet)
result = (
df
.filter(col("status") == "completed")
.filter(col("amount") > 0)
.withColumn("amount_usd", col("amount") / 100)
.groupBy("region", "product_category")
.agg(
spark_sum("amount_usd").alias("total_revenue"),
avg("amount_usd").alias("avg_order_value"),
count("order_id").alias("order_count"),
)
.orderBy(col("total_revenue").desc())
)
# Action triggers actual computation
result.show(20)
result.write.mode("overwrite").parquet("s3://my-bucket/output/sales_summary/")
spark.stop() Spark SQL & Broadcast Joins
# Spark SQL — register temp view and run SQL
from pyspark.sql import SparkSession
from pyspark.sql.functions import broadcast
spark = SparkSession.builder.appName("SparkSQL").getOrCreate()
orders = spark.read.parquet("s3://bucket/orders/")
customers = spark.read.parquet("s3://bucket/customers/")
# Register as temp views
orders.createOrReplaceTempView("orders")
customers.createOrReplaceTempView("customers")
# Run standard SQL
result = spark.sql("""
SELECT
c.country,
DATE_TRUNC('month', o.created_at) AS month,
COUNT(o.order_id) AS orders,
SUM(o.amount_usd) AS revenue
FROM orders o
JOIN customers c ON o.user_id = c.user_id
WHERE o.status = 'completed'
GROUP BY 1, 2
ORDER BY 2 DESC, 3 DESC
""")
result.show()
# Broadcast join optimization for small dimension tables
result2 = orders.join(
broadcast(customers), # sends small table to all executors
on="user_id",
how="left"
) Performance Optimization
# Spark performance optimization techniques
from pyspark.sql import SparkSession
from pyspark.sql.functions import col
spark = SparkSession.builder.appName("Optimization").getOrCreate()
df = spark.read.parquet("s3://bucket/events/")
# 1. Caching — keeps DataFrame in memory across multiple actions
df.cache() # MEMORY_AND_DISK by default
df.persist() # same as cache()
df.unpersist() # free memory when done
# 2. Repartitioning
df_balanced = df.repartition(200) # round-robin
df_by_key = df.repartition(50, col("user_id")) # hash partition
df_small = df.coalesce(10) # reduce (no shuffle)
# 3. Predicate pushdown — Spark pushes filters to data source
df_filtered = spark.read .option("pushDownPredicate", "true") .parquet("s3://bucket/events/") .filter(col("event_date") == "2024-01-01")
# 4. Explain plan — inspect physical plan
df_filtered.explain(mode="formatted")
# 5. Adaptive Query Execution (AQE) — Spark 3.x auto-tuning
spark.conf.set("spark.sql.adaptive.enabled", "true")
spark.conf.set("spark.sql.adaptive.coalescePartitions.enabled", "true") Spark vs Apache Flink vs Dask
| Feature | Apache Spark | Apache Flink | Dask |
|---|---|---|---|
| Primary use case | Batch + streaming unified | Low-latency streaming | Scale-out Pandas/NumPy |
| Streaming model | Micro-batch (or ContinuousProcessing) | True event-by-event | Batch only |
| Python API | PySpark (full-featured) | PyFlink (growing) | Native Python |
| Managed cloud | Databricks, EMR, Dataproc | Kinesis, Confluent Cloud | Coiled, self-hosted |
| SQL support | Excellent (Spark SQL) | Good (Flink SQL) | Limited |
| Learning curve | Medium | High | Low (Pandas-like) |
Best Practices
- Enable Adaptive Query Execution (
spark.sql.adaptive.enabled=true) for automatic shuffle partition optimization - Broadcast small dimension tables in joins to eliminate expensive sort-merge shuffle
- Use
coalesce()to reduce partition count without shuffle;repartition()when you need a balanced distribution - Always call
unpersist()after cached DataFrames are no longer needed to free executor memory - Store data in columnar Parquet or Delta Lake format to benefit from predicate pushdown and columnar reads
- Profile jobs with Spark UI's SQL tab and Stage details to identify shuffle bottlenecks and spill
Frequently Asked Questions
What is the difference between RDDs, DataFrames, and Datasets in Spark?▼
RDDs (Resilient Distributed Datasets) are the low-level API — collections of objects distributed across the cluster, processed with functional transformations (map, filter, reduce). They give full control but lack optimization. DataFrames are distributed collections of rows with named, typed columns — similar to a database table. Spark's Catalyst optimizer can optimize DataFrame queries automatically. Datasets are type-safe DataFrames available in Scala and Java (Python does not have them). For Python, always use DataFrames — they are faster than RDDs and fully optimized by Catalyst and Tungsten.
What does 'lazy evaluation' mean in Spark?▼
In Spark, transformations (filter, groupBy, join, select) are lazy — they build up a logical execution plan but do not actually run any computation. Execution only happens when an action is called (show, collect, write, count). This design allows Spark's Catalyst optimizer to examine the full transformation plan before execution and apply optimizations like predicate pushdown, projection pruning, and join reordering. It also means you can chain many transformations with no performance cost until you trigger an action.
What causes Spark shuffles and why are they expensive?▼
A shuffle occurs when data must be redistributed across partitions — typically during groupBy, join, distinct, orderBy, and repartition. Shuffled data is written to disk, transferred over the network to target executors, then read back. Shuffles are expensive because they involve disk I/O, network I/O, and serialization. Minimize shuffles by: broadcasting small tables in joins, filtering data before joining, using partition-aware operations, and setting spark.sql.shuffle.partitions to an appropriate value (default 200 is often too high for small datasets).
How does Spark's in-memory processing work and when does it spill to disk?▼
Spark stores intermediate data in executor JVM memory. Each executor has an execution memory pool (for shuffles and aggregations) and a storage memory pool (for cached RDDs/DataFrames). With Unified Memory Management (Spark 1.6+), these pools dynamically share memory. When execution memory is exhausted during a shuffle or sort, Spark spills data to local disk. Spill is far slower than in-memory but prevents OOM errors. Tune executor memory (--executor-memory), cores per executor, and the memory.fraction settings to minimize spill on large jobs.
What is Adaptive Query Execution (AQE) in Spark 3?▼
Adaptive Query Execution (AQE), introduced in Spark 3.0, allows Spark to re-optimize the query plan at runtime based on actual statistics collected during execution. It handles three main scenarios automatically: coalescing post-shuffle partitions (merging small partitions to reduce task overhead), converting sort-merge joins to broadcast joins when a table turns out to be small enough, and skew join optimization (splitting oversized partitions). Enable AQE with spark.sql.adaptive.enabled=true — it is enabled by default in Spark 3.2+.
When should I choose Spark over Pandas or Dask?▼
Use Pandas when your data fits comfortably in a single machine's RAM (typically under 20–50 GB) — it is simpler, faster to develop with, and has a richer ecosystem for exploratory analysis. Use Dask when you want Pandas-like syntax but need to process data that is too large for one machine without the operational complexity of a Spark cluster. Use Spark when you have genuinely large datasets (hundreds of GB to petabytes), need to integrate with a data lake or warehouse (Delta Lake, Iceberg, Hive), require SQL support alongside DataFrame operations, or are on a managed cluster (Databricks, EMR, Dataproc).
Related Products
on GumroadDeveloper Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →AI Prompt Engineering Toolkit
58 structured prompt templates for Claude, ChatGPT, and Gemini — organized by use case. Code Review, Debugging, Documentation, Architecture, and 10 model-specific tips. Stop writing prompts from scratch.
Buy on Gumroad →Developer Cheat Sheet Bundle
10 print-ready cheat sheets for the tools developers use every day: Git, Docker, Linux CLI, SQL, Regex, HTTP Status codes, VS Code shortcuts, Bash scripting, jq/JSON, and Markdown.
Buy on Gumroad →You Might Also Need
JSON Formatter & Validator
Format, beautify, and validate JSON online. Paste your JSON to instantly pretty-print it with 2-space, 4-space, or tab indentation. Minify JSON too. Free, runs in your browser.
Open free tool →
Regex Tester
Free regex tester. Test regular expressions against multiple strings with expected match/no-match assertions — see instant pass/fail results. Built-in presets for email, URL, IPv4, and phone. Pro: unl
Open free tool →
Base64 Encoder & Decoder
Free Base64 Encoder & Decoder. Convert text, images, and any file to Base64 and back. Supports URL-safe Base64, image data URIs, and file download from Base64. Runs 100% in your browser — no data sent
Open free tool →
More Free Tools
Related Articles
Apache Airflow vs Prefect: Workflow Orchestration Comparison 2026
Apache Airflow vs Prefect 2026: DAG vs flow syntax, scheduling, dynamic workflows, observability, learning curve, cloud offerings, and which to choose for your data team.
Apache Kafka for Real-Time Data Pipelines: Tutorial 2026
Apache Kafka tutorial 2026: topics, partitions, consumer groups, producers/consumers in Python, Schema Registry, Kafka Connect, exactly-once semantics, and production best practices.
Apache Spark vs Flink: Stream Processing Comparison 2026
Apache Spark vs Apache Flink 2026: architecture differences, true streaming vs micro-batch, latency, exactly-once semantics, SQL support, state management, and when to choose each.
DuckDB vs PostgreSQL for Analytics: When to Choose Each 2026
DuckDB vs PostgreSQL 2026: OLAP vs OLTP, query performance on large datasets, Parquet/CSV support, and when to choose DuckDB for analytics workloads.
ETL vs ELT: Modern Data Pipeline Architecture Guide 2026
ETL vs ELT data pipeline comparison 2026: traditional ETL limitations, cloud ELT advantages, dbt for transformation, tools comparison (Fivetran/Airbyte/dbt), and when to use each approach.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →