Как правильно работать с Greenplum. Часть третья — «distributed by»

distributed-byПродолжаем рассматривать Greenplum со всех сторон.

Основным механизмом работы с таблицами в Greenplum является их правильное создание — а именно, использование правильного условия distributed by. Правильное определение полей, по которым нужно «размывать» данные по узлам — гарантия высокопроизводительной работы системы.

Очевидно, что, поскольку Greenplum на все таблицы набрасывается сразу всеми своими узлами, то таблицы должны быть размыты как можно более равномерно по всем его узлам.

Distributed by — это, по сути, хэш-функция, рассчитываемая для каждой записи в таблице. Ее значение однозначно определяет, на какой из узлов попадет та или иная запись.

Поэтому основным правилом для использования полей в условие distributed by является их вхождение в primary (или unique) key в таблице. Начиная с версии Greenplum 4.2, на таблице невозможно создать Primary (или unique) key, чтобы этот ключ не стал автоматически условием distributed by.

Этим они, конечно, испортили многое — во-первых, на таблице нельзя теперь одновременно использовать и primary key, и unique key, а во-вторых, если поле входит в условие distributed by, то его значение невозможно изменить. Кроме всего прочего, разработчики Greenplum решили упростить себе жизнь и отказались от глобальных индексов в таблицах с partitions. То есть, primary key на таких таблицах теперь обязан включать поле партиционирования, что, конечно, совершенно неправильно. Unique key, как ни странно, не обязан включать поле партиционирования, но он все равно является уникальным только внутри партиции. Но Greenplum считает, что он создан для аналитики, а не для мелких операций, поэтому данные в него должны уже загружаться правильные. Ну, или как вариант, проверку правильности можно сделать «ручками». Возможно, что такой подход и имеет место, но миграция с более ранних версий Greenplum на версию 4.2 принесла немало неприятных минут. Эти особенности поведения Greenplum надо иметь в виду при определении условия distributed by и при описании таблиц.

Если на таблице существует primary (или unique) key, то для оптимальной производительности желательно, чтобы этот ключ был как можно короче, или чтобы для поиска конкретной записи использовались все поля из него. В этом случае поиск будет «целенаправленным» — сразу определится узел, на котором это значение хранится. Если же поиск осуществляется не по всем полям, входящим в ключ, то Greenplum будет вынужден сканировать все узлы, поскольку невозможно точно определить значение хэш-функции. Поэтому, если таблица партиционирована, то лучше на ней создать unique key по ID, а не primary key, который обязан в себя включать и ID, и поле партиционирования. Если используется только одно поле (ID), то поиск будет происходить по всем партициям, но только на одном узле, не нужно сканировать все узлы. Если же ключ включает ID и date, например, то поиск только по ID вынужден будет сканировать все узлы.

Иногда бывает невозможно определить primary key на таблице, или его использование в Greenplum нецелесообразно — как уже описывалось ранее, если, например, значения полей из primary key могут меняться. Для таких случаев Greenplum придумал условие distributed randomly, которое, на первый взгляд, убивает сразу почти всех зайцев (кроме обеспечения уникальности) — можно и поля любые менять, и все должно распределяться «равномерно и прямолинейно». Но все не так просто — если загрузка данных в таблицу происходит маленькими порциями, то распределение данных по узлам может оказаться не очень равномерным, что обязательно приведет к проблемам с производительностью.

Позже я расскажу о дополнительных тонкостях использования условия distributed by при оптимизации запросов.

© Михаил Герштейн

Поделиться в соц. сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники

Добавить комментарий