Отто не читает номера зон. Ему нужны названия: «Центр», «Уралмаш», «ВИЗ». Названия лежат в справочнике зон, и его надо соединить с заказами. В базе данных JOIN это одна строка запроса. В Spark тоже, но под ней скрывается выбор: таблицы лежат на разных машинах, и чтобы соединить строки с одинаковым ключом, их надо как-то свести вместе. Spark умеет это двумя основными способами, и разница между ними бывает в десятки раз.
Две стратегии
Представьте, что сто сотрудников разбирают письма, и каждому нужно знать, какой район обслуживает какой почтальон. Если список почтальонов умещается на одном листке, проще всего сделать сто копий и раздать каждому. Никто никуда не ходит, все работают со своей стопкой писем и своей копией листка.
А если «листок» это огромная картотека на тысячу страниц, копировать её сто раз бессмысленно. Тогда письма и карточки раскладывают по районам: все письма и все карточки «Центра» в одну комнату, «Уралмаша» в другую. В каждой комнате письма и карточки сортируют по номеру и сверяют подряд.
Первый способ это broadcast join, второй это sort-merge join.
Broadcast hash join
Broadcast hash join: маленькая таблица собирается на драйвере и рассылается всем исполнителям. Каждая задача держит её в памяти хеш-таблицей и соединяет со своей партицией большой таблицы. Большая таблица никуда не едет, shuffle нет.
Spark выбирает его сам, если оценка размера одной стороны меньше порога spark.sql.autoBroadcastJoinThreshold, по умолчанию 10 МБ. Если вы знаете, что таблица маленькая, а Spark не знает (например, после сложных фильтров), подскажите: orders.join(F.broadcast(zones), "zone_id").
У broadcast есть предел. Рассылаемая таблица должна поместиться в память драйвера и каждого исполнителя. Таблицу на десятки гигабайт рассылать нельзя.
Sort-merge join
Sort-merge join: обе таблицы перемешиваются по ключу соединения, чтобы строки с одинаковым ключом оказались в одной партиции. Потом каждая партиция сортируется по ключу, и две отсортированные половины сливаются подряд. Так соединяют две большие таблицы. Это надёжно, но стоит двух shuffle.
Spark выбирает его, когда ни одна сторона не проходит под порог.
урок из курса
Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.