Data & Analytics

Hadoop / Spark / Hive

Три кита распределённой обработки данных: Hadoop отвечает за хранение и кластер, Spark — за вычисления, Hive — за SQL поверх файлов.

Что такое Hadoop, Spark и Hive

Три проекта Apache, которые постоянно упоминают вместе, потому что исторически они образуют один стек для больших данных. Но задачи у них разные, и путать их не стоит:

  • Hadoop — хранение файлов на кластере и управление его ресурсами.
  • Spark — движок, который выполняет вычисления над этими данными.
  • Hive — слой, позволяющий писать SQL вместо кода.

Hadoop

Hadoop — не одна программа, а набор из трёх компонентов:

  • HDFS (Hadoop Distributed File System) — распределённая файловая система. Файл режется на блоки (по умолчанию 128 МБ), каждый блок хранится на трёх узлах. Диск умер — данные на месте, кластер тихо восстановит копию.
  • YARN — планировщик ресурсов: раздаёт задачам CPU и память по узлам.
  • MapReduce — исходная модель вычислений: map обрабатывает куски параллельно, reduce сводит результаты. Между стадиями всё пишется на диск.

Главная идея Hadoop — принести вычисление к данным: гонять петабайт по сети бессмысленно, поэтому задача запускается на том узле, где нужный блок уже лежит.

Сегодня MapReduce вручную почти не пишут — он слишком медленный из-за записи на диск между стадиями, его вытеснил Spark. HDFS тоже потеснили: в облаке роль дешёвого распределённого диска играет object storage вроде S3 или MinIO. Так что «Hadoop» сейчас чаще означает экосистему в целом, чем эти три компонента.

Spark

Spark — движок распределённых вычислений. Ключевое отличие от MapReduce: промежуточные результаты держатся в памяти, а не пишутся на диск после каждого шага. Для итеративных задач — джойны, агрегации в несколько стадий, обучение моделей — это принципиально: одни и те же данные не перечитываются с диска раз за разом.

Spark не требует Hadoop. Он умеет читать из HDFS, S3, PostgreSQL, Kafka, а запускаться — под YARN, Kubernetes или в standalone-режиме. Писать можно на Scala, Java, Python (PySpark) и R.

from pyspark.sql import SparkSession, functions as F

spark = SparkSession.builder.appName("revenue").getOrCreate()

orders = spark.read.parquet("s3a://lake/raw/orders/")

(orders
    .filter(F.col("status") == "paid")
    .groupBy("region", F.to_date("created_at").alias("day"))
    .agg(F.sum("amount").alias("revenue"))
    .write.mode("overwrite")
    .parquet("s3a://lake/marts/revenue_by_region/"))

Вычисления ленивые: ни одна строка не читается, пока не вызван write или collect. До этого Spark строит план и оптимизирует его целиком — например, сам протолкнёт фильтр к чтению файлов.

Что стоит знать до первого продакшена: узкое место Spark — shuffle, перераспределение данных между узлами при groupBy и джойнах. Он гоняет по сети объёмы, сопоставимые с исходным датасетом, и именно на нём падают джобы. Следствия практические: джойн большой таблицы с маленькой делают через broadcast, а перекос данных (99% строк с одним ключом) кладёт один executor независимо от размера кластера.

Hive

Hive — SQL-слой поверх файлов. Даёт две вещи: Metastore — каталог, который знает, что папка s3a://lake/raw/orders/ — это таблица orders с такими-то колонками и партициями, и движок трансляции SQL в распределённые задачи.

Metastore пережил сам Hive: в него ходят и Spark, и Trino, и Presto. Собственный движок Hive используют редко — он медленный, его вытеснили Spark SQL и Trino. А вот Metastore как каталог — до сих пор стандарт де-факто.

Что выбрать

Hadoop (HDFS/MapReduce) Spark Hive
Роль Хранение и ресурсы кластера Вычисления SQL и каталог таблиц
Где промежуточные данные Диск Память Зависит от движка
Интерфейс Java-код Код на Python/Scala/SQL Только SQL
Латентность Минуты — часы Секунды — минуты Минуты
Живой выбор в 2020-е HDFS — да, MapReduce — нет Да, стандарт Metastore — да, движок — нет

Отдельно стоит сказать, чего в этом списке нет. Если задача — быстрая аналитика по таблице в единицы терабайт, ClickHouse или Greenplum закроют её лучше и дешевле, чем Spark-кластер. Стек Hadoop/Spark оправдан, когда данные разнородные, объёмы измеряются сотнями терабайт или трансформации не выражаются в SQL.

Инфраструктура

Кластер собирают из средних узлов, а не из немногих мощных: 16–32 ядра, 128–256 ГБ RAM, локальные NVMe под shuffle. Сеть — узкое место номер один, 10 Gbit/s внутри стойки считается минимумом. Нагрузка пиковая: расчёт ночью, днём простой — поэтому executors удобно держать на spot-инстансах, Spark штатно переживает потерю узла и перезапустит задачу.

Связанные термины

Готовы запустить GPU-задачу?

Запустить GPU-сервер