03. Spark Architecture
Phase 3 — Apache Spark Fundamentals
Apache Spark is the distributed execution engine behind a large part of Databricks data engineering. To become effective with Databricks, you need to understand not only how to write PySpark or SQL, but where the code runs, how Spark builds an execution plan, how work is divided, and how that work reaches the machines that process the data.
1. The Spark mental model
Start with one sentence:
The driver plans and coordinates; executors perform distributed work against partitions of data.
A simplified execution path is:
User / Notebook / Job
|
v
SparkSession
|
v
DRIVER
plan + coordinate
|
v
Cluster Resources
|
+----+----+
| |
v v
Worker 1 Worker 2 ... Worker N
| |
Executor Executor
| |
Tasks Tasks
| |
Partitions of data
This mental model explains a huge percentage of Spark behavior.
2. What is a Spark application?
A Spark application is the execution context for a workload.
Conceptually:
One Spark Application
│
├── Driver process
│
├── SparkContext / SparkSession
│
├── Executors
│ ├── Executor 1
│ ├── Executor 2
│ └── Executor N
│
└── One or more Jobs
A single application can execute multiple actions and therefore multiple jobs.
Do not confuse:
- Application — lifetime of the Spark execution context.
- Job — work triggered by an action.
- Stage — a phase of a job separated by shuffle boundaries.
- Task — work for one partition within a stage.
- Partition — a unit of distributed data processing.
The hierarchy is:
Application → Job → Stage → Task → Partition
This hierarchy becomes extremely important later when diagnosing Spark UI performance.
3. Where Spark fits inside Databricks
Databricks is a platform; Spark is an execution engine.
A useful enterprise mental model is:
Databricks Platform
│
├── Workspace
│
├── Unity Catalog
│
├── Jobs / Lakeflow
│
├── Compute
│ |
│ └── Databricks Runtime
│ |
│ └── Apache Spark
│
└── Cloud Storage
└── S3 / Delta
Databricks manages the Spark environment for you. You normally do not manually create a SparkContext or initialize a cluster manager in a Databricks notebook. citeturn828704search9
For current Databricks compute, distributed processing runs on worker nodes and Databricks runs one Spark executor per worker node; therefore Databricks documentation often uses worker and executor almost interchangeably. citeturn828704search3
4. Driver
The driver is the control process for a Spark application.
Its major responsibilities include:
- Running your application logic.
- Maintaining the Spark execution context.
- Building logical and physical execution plans.
- Coordinating executors.
- Scheduling tasks.
- Tracking application state.
- Returning results to the application.
Conceptually:
DRIVER
|
+------------+------------+
| | |
Plan work Schedule Track
| tasks state
| | |
+------------+------------+
|
Executor processes
Important
The driver does not normally perform all the distributed data processing itself.
If your code causes a huge amount of data to be collected back to the driver, you can create a driver bottleneck.
For example:
df.collect()
may move a large result to the driver.
That is very different from:
df.write.format("delta").saveAsTable("catalog.schema.table")
where the distributed work can remain distributed.
5. Executors
Executors are processes responsible for executing tasks sent by the driver.
An executor can:
- Run tasks.
- Process partitions.
- Keep intermediate data.
- Cache data when requested.
- Perform shuffle operations.
- Report execution status back to the driver.
Conceptually:
Driver
|
+---- Task 0 ----> Executor 1
|
+---- Task 1 ----> Executor 2
|
+---- Task 2 ----> Executor 3
|
+---- Task 3 ----> Executor 1
Multiple tasks can run concurrently depending on available executor cores and workload characteristics.
6. Worker vs executor
This distinction matters on interviews.
A worker node is a compute machine.
An executor is a Spark process running on that worker.
In the standard Databricks architecture, Databricks runs one executor per worker node. citeturn828704search3
So:
Worker Node
└── Spark Executor
├── Task
├── Task
└── Task
Therefore, when you see:
"Executor 5 is slow"
you should think about the worker hosting that executor and then inspect its tasks, memory, CPU, I/O and shuffle behavior.
7. SparkSession and SparkContext
In modern Spark applications, SparkSession is the main entry point for working with Spark.
Typical Databricks Python code:
spark
The spark variable represents the SparkSession that Databricks provides to the notebook.
You normally do not need to create it manually.
The conceptual relationship is:
SparkSession
|
v
SparkContext
|
v
Spark execution infrastructure
SparkSession provides APIs for:
- DataFrames
- SQL
- Catalog operations
- Configuration
- Access to the underlying Spark context
8. Cluster manager — where does it fit?
In generic Apache Spark architecture, a cluster manager allocates resources for Spark applications.
The simplified open-source model is:
Spark Application
|
Driver
|
Cluster Manager
|
+------+------+
| |
Worker Worker
| |
Executor Executor
Depending on deployment mode, Spark can integrate with different cluster managers.
In Databricks, however, the platform abstracts much of this infrastructure management from the user. You normally select and configure Databricks compute rather than manually managing the Spark cluster manager.
This is an important distinction:
Learn the Spark architecture even when Databricks hides the infrastructure implementation.
You need the architecture to understand performance, failures and resource behavior.
9. From code to execution
Suppose you write:
result = (
orders
.filter("status = 'COMPLETED'")
.groupBy("customer_id")
.sum("amount")
)
result.write.mode("overwrite").saveAsTable("gold.customer_sales")
What happens?
Step 1 — Build the plan
The DataFrame operations describe what you want Spark to do.
Step 2 — Lazy evaluation
The transformations do not immediately execute the complete computation.
Step 3 — Action
The write triggers execution.
Step 4 — Optimize
Spark/Databricks constructs and optimizes the execution plan.
Step 5 — Schedule
The driver breaks execution into stages and tasks.
Step 6 — Distribute
Tasks are sent to executors.
Step 7 — Process partitions
Each task processes its assigned partition.
Step 8 — Write result
The distributed output is written to the target.
DataFrame transformations
|
v
Logical plan
|
v
Optimized / physical plan
|
v
Jobs + Stages
|
v
Tasks
|
v
Executors
|
v
Partitions
|
v
Storage
Spark uses lazy evaluation: transformations build processing logic and an action triggers execution. citeturn828704search9
10. Why partitions are fundamental
Spark does not normally send "the whole table" to one executor.
It processes partitions.
Imagine a 1 TB dataset:
1 TB Dataset
│
├── Partition 0
├── Partition 1
├── Partition 2
├── ...
└── Partition N
Tasks operate on these partitions.
For a stage with 2,000 partitions, Spark can conceptually create approximately 2,000 tasks for that stage.
The actual concurrency depends on available compute resources.
This leads to one of the most important Spark relationships:
Parallelism is constrained by the number and size of partitions and the available execution resources.
We will study partitioning in depth later.
11. Jobs
A job is triggered by an action.
Common examples include:
df.count()
df.collect()
df.show()
df.write.format("delta").save(...)
The important point is:
A transformation describes work; an action asks Spark to execute the required work.
A single Spark application can have multiple jobs.
Application
│
├── Job 0
├── Job 1
├── Job 2
└── Job 3
Spark's scheduler can manage multiple jobs within an application, depending on how they are submitted and the configured scheduling mode. citeturn828704search2
12. Stages
A job is divided into stages.
A simplified example:
Job
│
├── Stage 0
│ └── map/filter work
│
├── Stage 1
│ └── shuffle + aggregation
│
└── Stage 2
└── final write
A major concept is the shuffle boundary.
When data must move between executors to satisfy an operation such as a large aggregation or join, Spark may create a shuffle.
That movement can introduce:
- Network I/O
- Disk I/O
- Serialization
- Additional scheduling overhead
This is why shuffle becomes one of the most important performance topics in Spark.
13. Tasks
A task is the unit of work Spark sends to an executor.
A simplified stage:
Stage 1
│
├── Task 0 → Partition 0
├── Task 1 → Partition 1
├── Task 2 → Partition 2
├── Task 3 → Partition 3
└── ...
If a stage has 500 partitions, it can have approximately 500 tasks.
Tasks are where your transformations ultimately execute against specific partitions.
14. The complete hierarchy
Memorize this:
Spark Application
|
+-- Job
| |
| +-- Stage
| |
| +-- Task
| |
| +-- Partition
|
+-- Job
|
+-- Stage
|
+-- Task
Interview answer
If asked:
"Explain Spark execution hierarchy."
Answer:
"A Spark application contains one or more jobs. Jobs are triggered by actions and are divided into stages based on execution dependencies and shuffle boundaries. Each stage contains tasks, and each task processes a partition of data on an executor."
That is the foundation for the rest of this course.
15. Local vs distributed execution
Not every Spark workload requires multiple workers.
A single-node environment can run Spark in local mode.
For distributed processing:
Driver
|
+--- Worker 1 / Executor
+--- Worker 2 / Executor
+--- Worker 3 / Executor
For small workloads, single-node compute can be appropriate. For large distributed workloads, multiple worker nodes provide parallel execution. citeturn828704search1
This is why compute selection matters even before tuning Spark code.
16. What happens when an executor fails?
Spark is designed for distributed execution and task retry.
Conceptually:
Task 27
|
Executor 2 fails
|
v
Task retry
|
Executor 4
|
v
Task succeeds
A failure does not necessarily mean the entire application immediately fails.
Spark can retry failed tasks, although repeated executor failures, memory pressure, corrupted data, unavailable resources or other conditions can ultimately fail a stage/job.
This becomes important when reading the Spark UI and diagnosing executor loss. Databricks specifically recommends using the Spark UI to inspect jobs, stages, task behavior, shuffle, spill and executor issues. citeturn828704search0
17. Driver failure vs executor failure
These have different blast radii.
Executor failure
Potential impact:
- Tasks on that executor fail.
- Spark may retry them elsewhere.
- The stage can potentially recover.
Driver failure
Potential impact:
- The application loses its coordinator.
- The Spark application may fail.
- Notebook/job execution context can be lost.
Therefore:
Driver stability is especially important for production workloads.
Common driver-pressure patterns include:
- Huge
collect() - Huge
toPandas() - Excessive metadata operations
- Very large query plans
- Too much application-side processing
18. Driver memory vs executor memory
This distinction is fundamental.
Driver memory
Used for things such as:
- Application state
- Query planning
- Scheduling
- Notebook/application logic
- Results returned to the application
Executor memory
Used for:
- Task execution
- Shuffle
- Cached data
- Intermediate data
- Execution structures
A common mistake is to increase executor memory when the actual problem is driver memory.
Always identify which process is under pressure.
19. Databricks Runtime
Databricks Runtime provides the environment in which Spark workloads run.
It includes Spark plus Databricks optimizations and additional components.
For example:
Databricks Runtime
│
├── Apache Spark
├── Databricks optimizations
├── Runtime libraries
└── Cloud/platform integrations
Databricks also provides Photon for supported workloads. Photon is an important performance topic, but do not confuse Photon with Spark itself.
We will cover Photon deeply in the Performance Engineering phase.
20. Spark vs Photon
A useful mental model:
Databricks workload
|
+------------------+
| |
Spark execution Photon acceleration
| |
+---------+--------+
|
Compute
Spark remains the programming and execution abstraction you need to understand.
Photon is a Databricks-native vectorized execution engine that accelerates supported workloads.
Therefore:
Learn Spark first. Then learn how Databricks accelerates Spark/SQL workloads.
21. Spark architecture and storage
Spark is compute.
S3, ADLS, GCS and other systems are storage.
A typical AWS flow:
Databricks
|
Compute
|
+-------+-------+
| |
Driver Executors
|
|
S3
|
Delta / Parquet
This separation is fundamental to the lakehouse architecture.
Compute can be created and terminated independently from durable cloud storage.
That is one of the reasons lakehouse platforms can scale compute independently of storage.
22. Spark architecture and Unity Catalog
Unity Catalog governs data assets; Spark executes the processing.
Conceptually:
User / Job
|
v
Spark workload
|
v
Compute
|
+------> Unity Catalog authorization
|
+------> Cloud storage
Unity Catalog does not replace Spark.
Spark does not replace Unity Catalog.
They solve different architectural problems:
| Layer | Primary responsibility |
|---|---|
| Spark | Distributed computation |
| Databricks Compute | Compute infrastructure |
| Unity Catalog | Governance and access control |
| S3 | Durable object storage |
| Delta Lake | Transactional data layer |
23. How to read Spark architecture as an architect
When someone says:
"The pipeline is slow."
Do not immediately change the cluster size.
Ask:
- Is the driver healthy?
- How many jobs are being triggered?
- Which stage is slow?
- Is there a shuffle?
- How many partitions exist?
- Are tasks balanced?
- Is there data skew?
- Is there spill?
- Is the workload I/O-bound or CPU-bound?
- Are executors failing?
- Is the data layout efficient?
- Is the compute type appropriate?
The Spark UI exposes jobs, stages, tasks, executor behavior and shuffle metrics specifically to help answer these questions. citeturn828704search0turn828704search4
24. Hands-on: inspect your Spark environment
Run this in a Databricks notebook:
print("Spark version:", spark.version)
print("Application ID:")
print(spark.sparkContext.applicationId)
print("Master:")
print(spark.sparkContext.master)
print("App name:")
print(spark.sparkContext.appName)
Then inspect:
spark.conf.get("spark.sql.shuffle.partitions")
You are learning to connect:
Notebook → SparkSession → SparkContext → Application → Compute
Do not focus on memorizing configuration values yet.
Focus on understanding the architecture.
25. Hands-on: create a small execution
df = spark.range(0, 1_000_000)
result = (
df
.filter("id % 2 = 0")
.groupBy()
.count()
)
result.show()
Ask yourself:
- What is the application?
- Which operation is the action?
- When does execution start?
- Where are tasks executed?
- What partitions are processed?
- What would appear in the Spark UI?
The answer to these questions matters more than the code itself.
26. Spark UI: your diagnostic microscope
The Spark UI gives you the execution evidence.
Important areas include:
Jobs
Shows jobs and their execution timeline.
Stages
Shows stage-level duration, tasks, input/output and shuffle.
Executors
Shows executor resource and task information.
SQL
Shows SQL/DataFrame execution details.
The Spark Web UI exposes job DAGs, stage metrics, task progress, input/output and shuffle metrics. citeturn828704search4
Architect workflow
Slow pipeline
|
v
Jobs
|
v
Longest Stage
|
+---- Skew?
+---- Shuffle?
+---- Spill?
+---- I/O?
+---- Executor failure?
|
v
Root cause
|
v
Targeted optimization
Databricks recommends starting with the Jobs Timeline and then examining the longest stage, skew/spill and I/O characteristics. citeturn828704search0
27. Common beginner misconceptions
Misconception 1
"Spark is the cluster."
No.
Spark is the distributed processing engine. Databricks compute provides the infrastructure and runtime environment.
Misconception 2
"Driver processes all the data."
No.
The driver coordinates distributed execution. Executors process distributed partitions.
Misconception 3
"One table equals one task."
No.
Tasks operate on partitions.
Misconception 4
"One job equals one stage."
No.
A job can contain multiple stages.
Misconception 5
"More workers always make Spark faster."
No.
The bottleneck may be shuffle, skew, I/O, driver pressure, small files, poor partitioning or another issue.
Misconception 6
"Databricks hides Spark, so Spark architecture is unnecessary."
The opposite.
Databricks abstracts infrastructure management, but Spark concepts are essential for debugging and performance engineering.
28. Architect reference architecture
For an enterprise AWS lakehouse:
USERS / JOBS / BI
|
v
DATABRICKS
|
+------+------+
| |
Compute Unity Catalog
| |
+-----+-----+ |
| | |
Driver Workers |
| |
Executors |
| |
+-----+----+
|
v
Amazon S3
|
Delta / Parquet
Add:
- SSO / identity
- Service principals
- Compute policies
- Network controls
- Audit logging
- CI/CD
- Lakeflow Jobs
and this becomes an enterprise execution platform rather than simply a Spark cluster.
29. Architect-level interview questions
Q1. What is the difference between a driver and an executor?
The driver coordinates the Spark application and schedules work. Executors run tasks and process partitions.
Q2. What is the relationship between worker and executor in Databricks?
Databricks commonly runs one Spark executor per worker node, so the terms are often used interchangeably in Databricks architecture documentation. citeturn828704search3
Q3. What triggers a Spark job?
An action triggers execution.
Q4. What determines task count?
A task generally corresponds to processing one partition for a stage.
Q5. Why does Spark create multiple stages?
Stages separate portions of execution around dependency/shuffle boundaries.
Q6. Why can a driver run out of memory?
Large results collected to the driver, excessive application state, large plans or application-side processing can create driver pressure.
Q7. How do you troubleshoot a slow Spark job?
Start with Jobs → identify the longest stage → inspect tasks, shuffle, skew, spill, I/O and executor behavior → identify root cause → apply targeted optimization.
Q8. Why is Spark knowledge essential for Databricks?
Because Databricks provides a managed platform around distributed processing; Spark remains fundamental to understanding execution, resource usage and performance.
30. Final mental model
Memorize this architecture:
APPLICATION
|
SPARKSESSION
|
DRIVER
plan + coordinate
|
+-------+-------+
| |
WORKER WORKER
| |
EXECUTOR EXECUTOR
| |
TASKS TASKS
| |
PARTITIONS PARTITIONS
| |
+-------+-------+
|
STORAGE
S3 / Delta
And memorize this execution hierarchy:
Application
↓
Jobs
↓
Stages
↓
Tasks
↓
Partitions
↓
Data
If you understand this hierarchy, you have the foundation for understanding Spark performance, shuffle, partitioning, joins, caching, skew, the Spark UI and Databricks optimization.
Official references
- Databricks — Apache Spark on Databricks
- Databricks — Compute configuration reference
- Databricks — Spark UI guide
- Apache Spark — Cluster Mode Overview
- Apache Spark — Job Scheduling
- Apache Spark — Web UI
Next
03.1 Driver and Executors — deep dive into driver responsibilities, executor lifecycle, cores, memory, task concurrency, executor loss, driver bottlenecks and Databricks troubleshooting.