Как правильно выбрать ключ дистрибуции в Greenplum?

Ключ дистрибуции — архитектурное решение в Greenplum, которое почти невозможно изменить незаметно: оно задаётся один раз при создании таблицы и влияет на каждый последующий запрос. Неверный выбор не проявляется сразу — таблица годами живёт нормально, пока объём не вырастет настолько, что один сегмент начинает захлёбываться, а остальные простаивают. Greenplum distributed по своей природе означает, что производительность DWH упирается в то, насколько равномерно легли данные.

Любой greenplum sql запрос, который джойнит две большие таблицы DWH, зависит от того, как выбран ключ дистрибуции. В статье разберём, что такое перекос данных, какие стратегии дистрибуции Greenplum предлагает — DISTRIBUTED BY, DISTRIBUTED RANDOMLY и DISTRIBUTED REPLICATED, как найти перекос через gp_segment_id и gp_toolkit, и какие ошибки в выборе ключа дистрибуции greenplum встречаются чаще всего.
Аудит Arenadata DB Администрирование Arenadata DB

Что такое перекос данных (Data Skew) в MPP-архитектуре?

База данных greenplum — субд greenplum с архитектурой shared nothing, где каждый сегмент — независимый процесс со своей частью данных. Запрос выполняется параллельно на всех сегментах и завершается только тогда, когда отработает последний из них. Если один сегмент хранит непропорционально много строк, именно он определяет время всего запроса — остальные к этому моменту уже простаивают.
Это и есть Data Skew. В поддержке сильный перекос дистрибуции гринплам иногда называют просто arenadata перекос — то же явление, характерное и для Greenplum, и для Arenadata DB, поскольку обе системы используют один движок дистрибуции. Опасность в том, что перекос не виден в средних метриках нагрузки кластера — CPU и диск в среднем выглядят нормально, пока не разложить нагрузку по каждому сегменту отдельно.

Равномерное распределение против Data Skew: 80% строк на одном сегменте из четырёх

Ключ дистрибуции Greenplum: базовые стратегии распределения

Greenplum архитектура закладывает выбор стратегии распределения прямо в DDL: greenplum create table поддерживает три варианта распределения строк по сегментам. Если создать таблицу greenplum без явного DISTRIBUTED BY, движок сам возьмёт первый подходящий столбец — и это первый источник будущего перекоса.

Распределение по хешу (DISTRIBUTED BY)

Стандартный и самый частый вариант: Greenplum вычисляет хэш от значения столбца и по нему определяет сегмент. Строки с одинаковым значением ключа всегда попадают на один сегмент — это создаёт возможность локального JOIN без Motion, если вторая таблица распределена по тому же ключу.
CREATE TABLE fact_orders (
    order_id     bigint,
    customer_id  bigint,
    amount       numeric,
    order_date   date
)
DISTRIBUTED BY (customer_id);
Хороший ключ дистрибуции greenplum — столбец с высокой кардинальностью, вовлечённый в большинство JOIN-ов таблицы: customer_id, order_id, device_id. Статус заказа, булев флаг или регион с 3-5 значениями для этой роли не подходят: значений слишком мало, чтобы разложиться поровну по десяткам или сотням сегментов, — они гарантированно приведут к перекосу.

Равномерное распределение (DISTRIBUTED RANDOMLY)

Greenplum раскладывает строки по сегментам циклически, игнорируя содержимое столбцов. Перекоса не будет никогда — но и локального JOIN тоже: при соединении с любой другой таблицей потребуется Redistribute или Broadcast Motion. RANDOMLY подходит для таблиц без естественного ключа для JOIN, для стейджинговых таблиц перед трансформацией в dbt и для логов, которые почти никогда не джойнятся напрямую по своим столбцам.

Полная репликация (DISTRIBUTED REPLICATED)

Полная копия таблицы физически хранится на каждом сегменте — это broadcast, выполненный один раз при загрузке данных, а не на каждый запрос: JOIN с такой таблицей никогда не требует Motion. REPLICATED уместен для небольших справочников — валют, статусов, календарей, — которые джойнятся почти в каждом отчёте dwh greenplum. Плата за это — место на диске (данные хранятся N раз, где N — число сегментов) и более медленные вставки, применяемые на всех копиях сразу. Для таблицы на 200 строк это не заметно, а вот попытка реплицировать таблицу на 50 млн строк умножит её объём на число сегментов кластера и ощутимо замедлит загрузку.

Как найти arenadata перекос на практике?

Использование системного столбца gp_segment_id

У каждой строки в Greenplum есть скрытый системный столбец gp_segment_id — номер сегмента, где она физически хранится. Прямой запрос к нему — самый быстрый способ увидеть перекос своими глазами:
SELECT gp_segment_id, count(*) AS rows_cnt
FROM fact_orders
GROUP BY gp_segment_id
ORDER BY rows_cnt DESC;
 
 gp_segment_id | rows_cnt
---------------+----------
             7 | 42910384
             0 |   612044
             3 |   611390
             2 |   605122
             1 |   598877
Если один сегмент выдаёт на порядок больше строк, чем остальные, — это и есть перекос, дальше дело за выбором нового ключа.

Анализ через представления gp_toolkit

Считать перекос вручную по каждой таблице неудобно — в схеме gp_toolkit есть представление gp_skew_coefficients, которое возвращает коэффициент перекоса сразу для таблицы:
SELECT skcoid::regclass AS table_name, skcoeff
FROM gp_toolkit.gp_skew_coefficients
WHERE skcoid = 'fact_orders'::regclass;
 
     table_name     | skcoeff
---------------------+---------
 public.fact_orders  |  187.42
Чем ближе skcoeff к нулю, тем равномернее таблица; значения в десятки и сотни — сигнал пересмотреть DISTRIBUTED BY. Представление удобно гонять по всем таблицам DWH сразу — регулярный обход gp_toolkit выявляет проблемы раньше, чем перекос станет жалобой от бизнеса.

Главные ошибки при выборе ключа дистрибуции

Чаще всего перекос — не ошибка проектирования, а результат случая: таблицу создали с DISTRIBUTED BY по умолчанию (первый столбец, суррогатный id), не задумываясь, как её будут джойнить. Вторая ошибка — распределение по столбцу с низкой кардинальностью: статус, регион, тип операции. Третья — ключ выбрали верно на старте, но JOIN-паттерны поменялись через год, а таблицу не пересмотрели. Четвёртая — DISTRIBUTED REPLICATED применили к таблице, которая на деле не такая уж маленькая: справочник вырос за пару лет с полусотни строк до полумиллиона, а тип дистрибуции никто не пересмотрел. Последняя — после смены DISTRIBUTED BY забыли обновить greenplum статистика (VACUUM ANALYZE), и планировщик строит планы по старым данным.

Оптимизация DWH от ДБ-Сервис

Пересмотр ключей дистрибуции по всем таблицам DWH вручную — работа на недели, особенно если схема росла несколько лет и правило "один ключ — один архитектор" никогда не соблюдалось. Специалисты администрирования и аудита Greenplum и Arenadata DB от DB Serv проходят по gp_toolkit и статистике всех таблиц кластера, находят перекошенные и нерационально реплицированные таблицы и предлагают план пересмотра DISTRIBUTED BY без остановки продуктивной среды.

Краткие выводы

  • Data Skew — неравномерное распределение строк по сегментам, из-за которого один сегмент определяет время всего запроса.
  • DISTRIBUTED BY подходит для таблиц с высококардинальным ключом, часто участвующим в JOIN.
  • DISTRIBUTED RANDOMLY устраняет перекос гарантированно, но требует Motion при любом JOIN.
  • DISTRIBUTED REPLICATED убирает Motion полностью, но подходит только для небольших справочников.
  • Перекос проверяется запросом по gp_segment_id или коэффициентом skcoeff из gp_toolkit.gp_skew_coefficients.
  • Статус, регион и другие низкокардинальные столбцы — почти гарантированный источник перекоса.

Частые вопросы по теме

Столкнулись с перекосом данных (Data Skew) в кластере Greenplum?
Неверный ключ дистрибуции перегружает отдельные сегменты и замедляет аналитику. Эксперты DB Serv проведут аудит вашего DWH: найдут перекошенные таблицы через gp_toolkit, грамотно пересмотрят DISTRIBUTED BY и предложат план оптимизации кластера без остановки продуктивной среды.
Оставить заявку
Наши топ-3 компетенции по Arenadata DB
Каждое из наших направлений создано для того, чтобы ваше хранилище данных работало на максимальной скорости, а бизнес развивался без сбоев и непредсказуемых рисков.
  • Глубокий анализ производительности вашего хранилища данных. Выявляем узкие места в архитектуре, проверяем «тяжелые» запросы и ключи дистрибуции. Предоставляем четкие рекомендации и пошаговый план оптимизации кластера.
    Подробнее
  • Комплексное техническое сопровождение кластера. Грамотно распределяем ресурсы (Resource Groups), обеспечиваем бесперебойную работу ночных ETL-загрузок и дневной аналитики.
    Подробнее
  • Применяем системный и прозрачный подход. Понятный процесс работы: от детального сбора метрик конфигурации до профилирования нагрузки. Внедряем лучшие инженерные практики для выхода на новый уровень надежности.
    Подробнее

Эксперт ДБ-сервис

Еще статьи по теме