В чём разница между MapReduce и Apache Spark?

«В чём разница между MapReduce и Apache Spark?» — вопрос из категории Apache Spark, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

MapReduce и Apache Spark — это фреймворки для распределённой обработки больших данных, но с разными подходами к производительности и удобству использования.

Ключевые различия:

  1. Модель выполнения:

    • MapReduce использует двухэтапную модель (Map и Reduce) и записывает промежуточные данные на диск (HDFS) после каждого этапа. Это вызывает высокие накладные расходы ввода-вывода для итеративных алгоритмов (например, машинного обучения) или многоэтапных конвейеров.
    • Spark выполняет операции в памяти, используя абстракцию Resilient Distributed Datasets (RDD). Данные кэшируются в оперативной памяти кластера, что делает итеративную обработку на порядки быстрее. Запись на диск происходит только при нехватке памяти или для сохранения результатов.
  2. Удобство разработки:

    • MapReduce требует написания кода на низком уровне (Java, Python) для каждой задачи Map и Reduce.
    • Spark предоставляет высокоуровневые API на Java, Scala, Python и R, а также специализированные библиотеки (Spark SQL для SQL-запросов, MLlib для машинного обучения, Structured Streaming для потоковой обработки), что значительно ускоряет разработку.
  3. Обработка в реальном времени:

    • Классический MapReduce предназначен исключительно для пакетной обработки.
    • Spark поддерживает микропакетную потоковую обработку через Spark Streaming (DStreams) и низколатентную обработку через Structured Streaming.

Практический пример на PySpark:

# Подсчёт слов в Spark (для сравнения с классическим MapReduce)
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("WordCount").getOrCreate()
text_file = spark.sparkContext.textFile("hdfs://.../large_file.txt")
word_counts = text_file.flatMap(lambda line: line.split(" ")) 
                       .map(lambda word: (word, 1)) 
                       .reduceByKey(lambda a, b: a + b)
word_counts.saveAsTextFile("hdfs://.../output")

Итог: Spark стал преемником MapReduce в большинстве сценариев благодаря производительности в памяти, единой платформе для пакетной, интерактивной и потоковой обработки, а также более удобным API.