🧱 Apache Spark Fundamentals
DataFrame API, Spark SQL, трансформации, действия, оптимизация
⚡ Spark Architecture
Driver — создаёт SparkContext, планирует DAG. Executors — выполняют реальную работу (task). Cluster Manager: YARN, Kubernetes, Databricks (на базе k8s). DAG (Directed Acyclic Graph) — план трансформаций. Иерархия Stage → Task.
🔄 Transformations vs Actions
Lazy Evaluation — трансформация не выполняется до вызова action. Narrow transformations: filter, select, map — без shuffle. Wide transformations: groupBy, join, distinct — требуют shuffle (expensive!). Actions: show(), count(), collect(), write().
📊 DataFrame API
Structured API. `spark.read`, `df.select()`, `df.filter()`, `df.groupBy().agg()`, `df.join()`, `df.write`. Catalyst Optimizer — оптимизирует запросы. Tungsten — управление памятью. Adaptive Query Execution (AQE) — оптимизация во время выполнения.
💡 Spark SQL & Caching
SQL-запросы напрямую в Spark. `spark.sql("SELECT ...")`. Temp Views: `df.createOrReplaceTempView("name")`. Caching: `df.cache()` или `df.persist(StorageLevel.MEMORY_AND_DISK)`. Кэш полезен только при многократном использовании одного и того же датасета.
💡 Ключевые моменты
- Lazy evaluation: ничего не выполняется до появления action
- Wide transformation (groupBy, join) = shuffle = expensive
- AQE: оптимизация плана запроса во время выполнения
- cache() = для повторного использования, но занимает память
- Catalyst Optimizer выполняет всю оптимизацию SQL/DataFrame
📋 Пример кода
from pyspark.sql import functions as F
# DataFrame operations
df = spark.read.format("delta").load("/data/sales")
result = (df
.filter(F.col("date") >= "2024-01-01")
.groupBy("category")
.agg(
F.sum("amount").alias("total"),
F.count("*").alias("count")
)
.orderBy(F.desc("total"))
)
result.show(10)
# Spark SQL alternative
df.createOrReplaceTempView("sales")
spark.sql("""
SELECT category, SUM(amount) as total
FROM sales
WHERE date >= '2024-01-01'
GROUP BY category
ORDER BY total DESC
""")
🎯 Советы для экзамена
- Narrow vs Wide: filter/select/map = narrow (no shuffle), groupBy/join/distinct = wide (shuffle)
- repartition() vs coalesce(): repartition — полный shuffle (если увеличиваем разделы), coalesce — минимальный shuffle (только для уменьшения)
- Broadcast Join — предотвращает shuffle при join малой таблицы (< 10MB по умолчанию) с большой: `F.broadcast(small_df)`
- collect() — все данные поступают на driver: риск OOM! Только для небольших результатов
- Spark UI: Stage, Task, Shuffle read/write — смотрите в первую очередь при отладке медленных задач
⚠️ Частые ошибки
- Считать count() трансформацией — count() = ACTION, выполняется немедленно
- Думать, что cache() всегда полезен — для DF, используемого один раз, cache впустую расходует память
- Не знать, что distinct тоже выполняет shuffle — `df.distinct()` тоже является wide transformation
🧠 Для запоминания: "FAST Cache" = Filter/select (narrow, fast), Aggregation/Sort/Transformation wide, Cache for reuse. "Actions Start Computation: show, count, write, collect"
Проверьте себя по теме «Apache Spark Fundamentals»
Бесплатные интерактивные тесты, пробный экзамен и полные уроки — на платформе CertMaster.
Начать бесплатно →