Greenplum Flashcards

(7 cards)

1
Q

Что это простыми словами

A

Greenplum это распределённая (шардированная) база данных на основе PostgreSQL.

Распределённость даёт возможность обрабатывать кратно больший объём данных за счёт горизонтального масштабирования (в обработке участвуют несколько серверов, каждый из которых хранит свой кусок каждой таблицы). Также гринплам оптимизирован под OLAP нагрузку.

Ггринплам версии 6.х создан на основе Postgres 9.4.x, и сильно отстаёт по функционалу от Postgres 17 (latest на март 2025). 7я версия пока ещё не используется в продакшене в России (на начало 2025, насколько мне известно).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Архитектура Greenplum

A

Состоит из нескольких частей:

Master-node: Здесь развернут главный инстанс PostgreSQL, через него идёт подключение, обрабатываются SQL-запросы, проходит оптимизация

Standby или резервный мастер: Обеспечивает отказоустойчивость, вручную врубается при отказе мастера
Сегментов(каждый сегмент - отдельный инстанс postgres)

Interconnect - узел связи между мастером и сегментом

Segment-host - Хранит и обрабатывает данные по сегментам. Обычно сегментов в Greenplum от 2 до 8. Каждый primary segment - отдельный инстанс PostgreSQL, у которого есть свой зеркальный сегмент(тоже инстанс посгри), который включается в работу при отказе основного

Из архитектуры GP вытекает 2 проблемы

Сомнительная отказоустойчивость - если падает мастер, надо вручную переключать, а значит GP будет простаивать вырубленным, а у этого килотонна последствий от рассинхрона до полной остановки важных вычислений

Невозможность адекватно горизонтально масштабировать на хранилища, которые измеряются в петабайтах:
Слишком высокая нагрузка на interconnect + перегрузка мастера обработкой системных задач + лимиты на количество сегментов(слишком большое кол-во сегментов нерационально поддерживать)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Распределение данных (Distribution)

A

Задаётся в DDL, при создании таблицы, можно поменять(перераспределить) таблицу с помощью ALTER TABLE

Таблицы в Greenplum всегда распределяются по сегментам

Существует три основных способа распределения:
DISTRIBUTED BY(multiple or single columns) - преимущественно используется распределение по одной колонке, желательно int и без null
DISTRIBUTED RANDOMLY
DISTRIBUTED REPLICATED

В большинстве ситуаций логика - если есть уникальный для каждого значения клюx(primary key), то вешаем распределение по этому ключу, если нету - делаем randomly

Делать Join лучше всего по ключу распределения, особенно если нам предстоят тяжёлые джоины, тогда ищем primary key, вешаем на него distributed by и джоиним по этому ключу

Если подгружаем какой-то небольшой лёгкий справочник, то можно распределить и целиком по сегментам - replicated

В случае Join не по ключам сегмента возникает Motion: Redistribute - когда джоиним тяжёлые таблицы, вызывает перераспределение для конкретной операции(Высокий риск Data Skew), Broadcast - реплицирует маленькую табличку(Если такая есть) по всем сегментам

Итог - подбираем необходимый вид распределения, ключ, если надо, смотрим, чтобы не происходило перераспределения при выполнении запроса, сравниваем разные для оптимизации

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Перекос данных

A

Это негативный результат неверно выбранной стратегии распределения данных. Гринплам работает со скоростью самого медленного сегмента, также как упряжка лошадей бежит со скоростью самой уставшей лошади.

Проверить перекос можно через запрос к системному полю gp_segment_id, которое есть в каждой таблице, но скрывается при

select *:
SELECT COUNT(1), gp_segment_id FROM <table-name> GROUP BY gp_segment_id ORDER BY 1 desc;

> Перекос это когда разница между максимальным и минимальным числом строк в сегментах различается на 10% и более.

Возможные причины перекоса:
* ключ распределения не указан явно, поэтому гринпламом выбран первый столбец (если нет PK constraint), в котором может быть много повторяющихся значений или null’ов
* выбранный ключ распределения содержит много одинаковых значений (null, идентификатор транзакций самого большого клиента или наиболее популярной категории товаров)

Способы борьбы с перекосом:
* ленивый способ, который сделает все запросы к таблице одинаково медленными: distributed randomly
* лучше – мониторить состояние max count, min count по gp_segment_id по активным табличкам и перераспределять данные до того, как произойдёт большое падение
* идеально – провести профилирование данных, обсудить с аналитиками, и понять, как будет использоваться таблица хотя бы в ближайшем будущем; выбирать ключ распределения “экспертно”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

AOCO, heap таблицы, сжатие

A

Гринплам как OLAP система лучше всего раскрывает себя с Append-Optimized Column-oriented (AOCO) таблицами. Это свойство хранения таблицы по колонкам, когда записи вставляются в конец, а уже имеющиеся не обновляются и не удаляются. Хорошо комбинируется с SCD2 на одной колонке effective_from.

Также есть “heap” – row-oriented , по сути обычные постгрес таблицы. Хорошо подходят для справочников – маленьких таблиц, которые обновляются вручную. Не сжимаются, потому что

Про уровни сжатия хватит сказать “у нас везде был zstd, 4 лвл, более тонко не приходилось настраивать”

CREATE TABLE tab (i int)
  WITH
    (appendoptimized = TRUE, orientation=COLUMN,
    compresstype = zstd,
    compresslevel = 4)
DISTRIBUTED BY (i);
CREATE TABLE tab (i int);
/* row by default */
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Внешние таблицы, PXF, GPFDIST

A

PXF – Platform Extension Framework, набор коннекторов для подключения внешних источников (S3, HDFS, PostgreSQL и тд). Это позволяет работать с данными, которые лежат “снаружи” относительно GP, не загружая в хранилище. Может быть полезно для работы с архивами, например, или когда скорость работы с данными не важна, а сами данные нужны в доступе прям щас. Сегменты подключаются к файлам напрямую, в обход мастера.

Поддерживает форматы CSV, текст, JSON, AVRO, ORC, Parquet. Хорошо масштабируется, читает и пишет данные в несколько потоков. Если указано несколько файлов – распределяет подключения сегментов по ним равномерно.

Внешняя таблица – объект со стороны Greenplum, в котором конфигурируется подключение. Потом к этой таблице можно писать запросы. Таблица может быть READABLE или WRITABLE.

Например:

CREATE READABLE EXTERNAL TABLE recent_sales
(id int, sdate date, amt decimal(10,2))
LOCATION ('pxf://company.salesdata? PROFILE=Jdbc&SERVER=mysql-db')
FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');

Поддерживает predicate pushdown, то есть передачу фильтра where на систему-источник, чтобы СНАЧАЛА отфильтровать данные, а ПОТОМ переносить в гринплам только нужные по сети.

GPFDIST это утилита и протокол для создания внешних таблиц на основе файлов. Указывается в LOCATION:

LOCATION ( 'gpfdist://filehost:8081/*.txt' ) 
LOCATION ('gpfdist://etl1:8081/sales-1.out', 'gpfdist://etl1:8081/sales-2.out')
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Партиционирование (Partitioning)

A

Указывается при создании таблицы в DDL, в Greenplum 7 точно есть возможность делать Alter table DETACH ATTACH PARTITION. Не уверен насчёт возможности делать ALTER TABLE с партициями

Физическое разделение хранимых данных, по сути создаём несколько таблиц(реально физически выделяются новые файлы) из одной по логическому условию, позволяет выборочно сканировать только те части таблицы, которые соответствуют условию (partition elimination), значительно ускоряя запросы

Существует три способа партиционировать:
PARTITION BY RANGE - создание партиций по диапазону(дат, цен и т.д.)
PARTITION BY LIST - создание партиций по списку(регионы, типы и т.д.)
PARTITION BY default - партицию отделённую таким образом GP будет сканировать всегда

Partition by RANGE - самый стабильный вариант разбить на логически равные и удобные части, в 90% случаев идут диапазоны дат

Сначала происходит Distribution -> потом Partitioning на всех сегментах, т.е. GP сначала распределил таблицу по сегментам, равномерно(в идеале) распределив данные между сегментами, а потом уже внутри сегментов данные дробятся на партиции

Из вышеперечисленного следует, что не стоит дробить таблицу на слишком мелкие партиции - в таком случае образуется слишком много мелких табличек, который могут забить GP в зависимости от вашего сетапа. На мой субъективный взгляд разумный предел - 365, один год разбитый по дню

Разбивать на подпартиции (SUBPARTITION) можно, но не рекомендуется - много файлов, высокий шанс наплодить пустых таблиц

Distributed replicated таблицы - не партиционируются

How well did you know this?
1
Not at all
2
3
4
5
Perfectly