Partition (партиция) — это некая часть исходных данных, полученная в ходе разбиения датасета в Apache Spark или Hive. Процедура разбиения на партиции называется партицированием (partitioning). Благодаря делению на партиции появляется возможность обрабатывать большие данные.
Способы создания партиций в Apache Spark
Apache Spark поддерживает два вида партиций: в оперативной памяти в виде фрейма данных (DataFrame) и на диске в виде файла:
- Партиция в памяти выполняется с помощью вызовов
repartition
илиcoalesce
. - Партиция на диске выполняется с помощью вызова
partitionBy
(это аналогично партициям в Hive).
При создании партиций в оперативной памяти датасет будет просто разделен на равные части. Вызов repartition
также выполнит перетасовку (shuffle). А вызов coalesce
, который умеет только уменьшать число партиций, может этого не делать, поскольку он более оптимизирован.
При создании партиций на диске они будут сгенерированы на основе уникальных значений столбца(ов), по которому(ым) происходит разбиение. Иными словами, partitionBy
работает как groupBy
, только вместо групп на диске создаются файлы с партициями.
В чем преимущества партиций
Apache Spark предназначен для обработки больших данных (Big Data), и партиции являются одним из способов это сделать. К плюсам партиций относятся:
- быстрый доступ к данным;
- возможность производить операции на меньших датасетах.
Действительно, хранить в оперативной памяти огромный датасет может быть не возможен, однако его заранее можно разбить на меньшие части, и уже с ними работать. К тому же фильтрационные запросы подразумевают партицирование, поэтому сделав это вручную, мы пропускаем этап этап.
К минусам партиций относятся:
- наличие большого числа партиций (операции ввода-вывода медленные);
- не решают проблему неравномерности данных (партиции могут быть разного размера, например, количество записей с населением Китая и Ватикана разное).
В чем отличие бакетов от партиций
Бакетирование (bucketing) разбивает данные на части, количество которых задается пользователем. Вместо уникальных значений столбца бакетирование стремится разделить данные на равные части, где каждой части присваивается свой ключ на основе вычисления хэш-функции.
Основное преимущество бакетов — это обхождение перетасовки. Если ваш конвейер состоит из цепочек преобразований: join
, distinct
, groupBy
, reduceBy
, — то будет выполнена всего одна перетасовка в момент генерации бакетов.
Категориальные значения лучше разбивать на партиции, а непрерывные на бакеты. Партиции можно также разбить на бакеты, а вот бакеты на партиции нельзя.
Ниже таблица, которая показывает разницу между партицированием и бакетированием.
Партицирование (Partitioning) | Бакетирование (Bucketing) |
---|---|
Распределяет данные по строкам | Делит данные на части |
Количество партиций зависит от количества уникальных значений | Количество заранее задается |
Подходит для категориальных значений | Подходит для непрерывных значений |
Хранит данные статически и динамически | Хранит данные динамически |
Выполнение будет быстрым при небольших размерах партиций | Операции map на бакетах будут быстрыми |
Нет возможности хранить данные в отсортированном порядке для каждой партиции | Есть возможность хранить данные в отсортированном порядке для каждой бакета |
Партиции могут быть разбиты на бакеты | Бакеты не могут быть разбиты на партиции |