сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Greenplum

Greenplum: распределение по сегментам

Зачем это спрашивают

DISTRIBUTED BY - решение №1 любой GP-таблицы, и вопрос «как выберешь ключ дистрибуции» - сердце GP-собеса. Два критерия конкурируют: локальность джойнов и равномерность.

// Смена ключа - полная перекладка таблицы: решение принимается при проектировании, «потом поправим» не работает.

Три способа разложить таблицу

DISTRIBUTED BY (hash): строки раскладываются по сегментам хешем ключа. Правильный ключ даёт локальные джойны и ровную нагрузку.

DISTRIBUTED RANDOMLY - равномерно, но без всякой co-location: годится для staging и таблиц без стабильного ключа джойна. DISTRIBUTED REPLICATED - полная копия на каждом сегменте: маленькие справочники джойнятся локально с чем угодно; для больших таблиц - запрещённый приём.

// Co-location - главный приз: две таблицы, соединяемые по своему ключу дистрибуции, джойнятся локально, без перегонок по сети.

co-location
джойн по ключу дистрибуции обеих таблиц - локален
REPLICATED
копия на каждом сегменте; только справочники

Skew: перекос данных и обработки

Равномерность обязательна: перекошенный ключ - статус, страна, NULL'ы - собирает данные на одном сегменте, и он пашет за всех. Все NULL хешируются в один сегмент - дистрибуция по колонке с NULL'ами это гарантированный горб.

Data skew проверяется SQL'ем: count(*) по gp_segment_id, gp_toolkit.gp_skew_coefficients; перекос от 10-20% - повод менять ключ.

// Processing skew коварнее: данные ровные, но GROUP BY или джойн по перекошенному значению собирает обработку в одном месте - виден только в рантайме.

data / processing skew
перекос хранения / перекос обработки в рантайме

Выбор ключа как компромисс

Идеальный ключ дистрибуции: высокая кардинальность (равномерность), участвует в главных джойнах (локальность), без NULL'ов. Обычно это id сущности-центра схемы: user_id, order_id.

Дистрибуция по дате у растущей таблицы фактов - антипаттерн: свежие данные всегда на одном сегменте, и «сегодняшние» запросы пашут на 1/N кластера.

// Конфликт «джойны просят один ключ, равномерность - другой» решается в пользу главного джойна, а равномерность проверяется фактом.

Как отвечать: «Как выберешь ключ дистрибуции для таблицы фактов?»

По двум критериям сразу. Первый - джойны: ключ должен совпадать с ключом дистрибуции таблиц, с которыми факты чаще всего соединяются, тогда джойн локален, без motion по сети; обычно это id центральной сущности вроде user_id. Второй - равномерность: высокая кардинальность, без NULL'ов - все NULL уезжают в один сегмент. После загрузки проверяю фактом: count(*) по gp_segment_id, перекос больше 10-20% - меняю ключ. Дату не беру никогда - свежие данные лягут на один сегмент. Справочники - REPLICATED, staging без стабильных джойнов - RANDOMLY. И помню: смена ключа - полная перекладка, это решение проектирования.

Оба критерия, проверка фактом и три готовых паттерна - решение, а не перечисление опций.

На чём валят

  • Дистрибуция по колонке с NULL'ами/низкой кардинальностью - все NULL на одном сегменте.
  • Джойн больших таблиц по разным ключам дистрибуции - motion всей таблицы.
  • REPLICATED для таблицы на сотни миллионов строк.
  • Не проверить skew после загрузки: «кластер медленный», а пашет один сегмент.
  • Дистрибуция по дате - свежие данные всегда на одном сегменте.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 13, остальные разбираются в тренажёре.

  1. #gp_distribution1 / 5
    Когда таблицу объявляют DISTRIBUTED RANDOMLY?
    A)Когда нужно, чтобы строки с одинаковым ключом попадали на один и тот же сегмент
    B)Когда таблицу часто джойнят по конкретному столбцу и важна локальность джойна
    C)Нет удачного ключа/редкие джойны → равномерное случайное распределение
    D)По умолчанию для больших таблиц, так как случайное распределение самое быстрое
    показать ответ и разбор
    +C)Нет удачного ключа/редкие джойны → равномерное случайное распределение

    // разбор: DISTRIBUTED RANDOMLY раскидывает строки по сегментам случайно (round-robin-подобно), гарантируя равномерность независимо от данных. Берут, когда нет столбца-хорошего ключа (любой даёт перекос) и таблицу не джойнят регулярно по определённому полю. Минус: любой джойн по такой таблице требует перераспределения (redistribute) или broadcast, ведь связанные строки не co-located. Поэтому для часто джойнимых больших таблиц random — плохой выбор; там подбирают хеш-ключ под джойны.

  2. #gp_distribution2 / 5
    Что делает DISTRIBUTED REPLICATED и для каких таблиц это уместно?
    A)Реплицирует таблицу на mirror-сегменты ради отказоустойчивости, как это делает механизм зеркал
    B)Распределяет строки таблицы случайно и равномерно по всем сегментам без ключа распределения
    C)Подходит в первую очередь для самых больших факт-таблиц кластера ради ускорения их чтения
    D)Копия таблицы на каждом сегменте — локальные джойны с мелким справочником
    показать ответ и разбор
    +D)Копия таблицы на каждом сегменте — локальные джойны с мелким справочником

    // разбор: REPLICATED-таблица не имеет ключа распределения — её полная копия лежит на каждом сегменте. Смысл — маленькие часто джойнимые измерения/справочники: раз копия есть на каждом сегменте, джойн большой распределённой таблицы с ней идёт локально, без перераспределения или broadcast в рантайме. Это заранее оплаченный broadcast. Годится только для небольших таблиц: для крупных репликация на все сегменты пожирает место и замедляет запись (каждая вставка идёт на все сегменты).

  3. #gp_distribution3 / 5
    Как выбирают хороший ключ распределения таблицы в Greenplum?
    A)Равномерный + совпадающий с ключом джойнов; баланс двух целей
    B)Берут столбец самой низкой кардинальности (например, булев флаг), чтобы сегментов задействовать меньше
    C)Ключ распределения выбирать не нужно — Greenplum сам обеспечивает идеальную равномерность
    D)Берут тот же столбец, что и первичный ключ, независимо от того, как таблицу джойнят
    показать ответ и разбор
    +A)Равномерный + совпадающий с ключом джойнов; баланс двух целей

    // разбор: Хороший ключ распределения удовлетворяет двум вещам сразу. Равномерность: высокая кардинальность и отсутствие доминирующих значений/NULL, иначе один сегмент перегружен (data skew), и запрос идёт со скоростью самого медленного сегмента. Co-location: если распределить джойнимые таблицы по общему ключу джойна, соединение идёт локально на сегментах без перераспределения. Эти цели часто конфликтуют (равномерный ключ ≠ ключ джойна), и приходится выбирать приоритет по нагрузке. Никогда не берут ключ с большой долей NULL или сильным перекосом.

  4. #gp_distribution4 / 5
    Один сегмент хранит втрое больше строк, чем остальные, и запросы тормозят. Что это и почему?
    A)Это нормальная работа MPP: неравномерность по сегментам не влияет на скорость выполнения запросов
    B)Data skew из-за плохого ключа распределения: перекошенный сегмент — узкое место, запрос идёт со скоростью самого нагруженного
    C)Проблема в нехватке памяти координатора, а распределение данных по сегментам тут ни при чём
    D)Достаточно добавить в кластер новые сегменты — перекос исчезнет сам без смены ключа распределения
    показать ответ и разбор
    +B)Data skew из-за плохого ключа распределения: перекошенный сегмент — узкое место, запрос идёт со скоростью самого нагруженного

    // разбор: Это data skew — неравномерное распределение из-за ключа с доминирующими значениями, большой долей NULL или низкой кардинальностью (хеш кладёт непропорционально много строк на один сегмент). MPP работает со скоростью самого медленного сегмента: перегруженный обрабатывает свою гору данных, пока остальные простаивают, — параллелизм теряется. Диагностика — count по gp_segment_id. Лечение: сменить ключ распределения на более равномерный (иногда добавить составной ключ) или, если равного нет, DISTRIBUTED RANDOMLY.

  5. #gp_distribution5 / 5
    Что такое co-location таблиц в Greenplum и зачем она нужна?
    A)Co-location означает физическое хранение всех таблиц кластера на одном общем выделенном сегменте
    B)Co-location — это репликация обеих джойнимых таблиц целиком на все сегменты кластера сразу
    C)Общий ключ распределения → локальный джойн без перераспределения
    D)Co-location ускоряет запись данных в таблицы, а на стоимость джойнов не влияет
    показать ответ и разбор
    +C)Общий ключ распределения → локальный джойн без перераспределения

    // разбор: Co-location — таблицы распределены по одному и тому же ключу, по которому их джойнят: тогда строки с совпадающим ключом гарантированно лежат на одном сегменте, и соединение выполняется локально на каждом сегменте без обмена строками по сети (motion). Это резко дешевле, чем redistribute/broadcast больших таблиц. Поэтому ключ распределения крупных часто джойнимых таблиц подбирают под их общий ключ джойна. Если распределения не совпадают, планировщик вынужден перераспределять данные в рантайме — главный источник дороговизны джойнов в MPP.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.