Привет, Хабр! На связиМарк — ведущий архитектор группы компаний «ГлоуБайт». Мой коллега Евгений Вилков в своей статье Тестирование систем и движков массивно-параллельных вычислений. Часть II. TPC-DS анонсировал выход статьи ​​по нагрузочному тестированию GreenPlum 6.X, GreenPlum 7.X и Cloudberry. Если не читали статью Евгения, рекомендую ознакомиться, в ней было краткое описание методики TPC-DS, про которую сегодня тоже пойдет речь. Тесты мы проводили параллельно, в своей статье Евгений как раз использовал результаты нашего тестирования Greenplum 6 на соответствующем для Data Ocean Nova сайзинге.

Историческая справка

В этом году GreenPlum отмечает 22 года. В конце сентября 2023 года состоялся релиз GreenPlum 7, спустя ровно 4 года после выхода GreenPlum 6. Между выходом GP5 и GP6 прошло 2 года. Заявлялось много новой интересной и полезной функциональности: как минимум повышение версии ядра с морально устаревшей Postgres 9.4 (2014 года рождения) до чуть менее устаревшей Postgres 12 (2019 года рождения). Многие ждали выход GreenPlum 7, ко мне до сих пор приходят коллеги и спрашивают: «А что там с GP7, собираете, когда ставить можно будет?»

Если смотреть на историю GP6, то стабилизация после релиза заняла примерно год. Активно выходили новые минорные версии, исправлялись баги. Некоторые компании только недавно мигрировали на GP6, кто-то даже до сих пор живет на GP5. Примерно такой же сценарий мы видели и для GP7, но в мае 2024 года репозиторий в GitHub был заархивирован, и дальнейшая разработка пошла в закрытом формате. Последняя открытая версия была 7.2. Именно она лежит сейчас в основе форков на российском рынке. 

При этом Broadcom продолжает развивать технологию без OSS-сообщества. Актуальная версия на момент написания статьи — 7.5.2. Есть и интересные фичи, направленные на оптимизацию, управление ресурсами и исправление багов. 

Примеры фичей:

  • Оптимизация ANALYZE (7.5.0): Пропуск статистических вычислений, если таблица не изменялась с последнего сбора статистики (новый параметр gp_analyze_only_modified_relations).

  • Улучшения GPORCA:

    • Поддержка REFRESH для материализованных представлений (7.5.0);

    • Оптимизация SIRV (Subquery Inlining for Row Expressions) (7.5.0, 7.4.0);

    • Поддержка Row Expressions (7.4.0);

    • Улучшенное управление памятью для метаданных (7.4.0).

  • Улучшения Direct dispatch для DML операций с явным указанием id сегмента  (7.4.0).

  • Раннее освобождение ресурсов (7.4.0): Параметр gp_resgroup_enable_early_unassign. Ресурсы будут высвобождать после исполнения отдельного запроса, не дожидаясь завершения всей сессии.

  • Добавлены новые утилиты:

    • gpcheck (7.5.0): Новая утилита для диагностики кластера (начальная версия включает проверку сети MTU);

    • gpmigrate (7.4.0): Утилита проверки совместимости между Greenplum 6 и 7;

    • gpctl и gpservice (7.4.0): Новые утилиты для управления кластером на основе gRPC;

  • Улучшения vacuumdb (7.5.0).

  • Большое количество критических исправлений в части стабильности, надежности и производительности.

С полным списком можно ознакомиться в Release Notes

Примерно в то же время в информационном поле стали появляться китайские “убийцы” Greenplum. Один из них – Cloudberry, результат “скрещивания” GP7 и Postgres 14. Cloudberry привлек к себе внимание, когда на ряде конференций (например, тут) Яндекс объявил, что решил контрибьютить в него.

Если сравнивать репозитории, то можно заметить, что развитие Open Source Greenplum 7 остановилось не начавшись, а в Cloudberry что-то даже происходит.

Сегодня мы хотим ответить на следующие вопросы:

  • Насколько лучше производительность в GP7 и Cloudberry относительно GP6?

  • Насколько стабильно работают GP7 и Cloudberry?

  • А стоит ли мигрировать с GP6 в 2025? И если да, то на что?

Подготовка к тестированию

Стенд тестирования: ВМ в Яндекс Cloud следующего сайзинга:

Хост

Количество

vCPU

RAM

SSD

Цена за месяц

Master

1

8

64

1,5TB

37720

Segment

4

16

128

2TBx4

135943

581492

Наши подопытные:

  • Open Source GreenPlum 6.27.1 – последняя open source версия GP6;

  • Open Source GreenPlum 7.2;

  • CloudBerry 1.6.0.

Тесты, которые проводились:

  • Тестирование по методике НТ MPP-движков. 

  • Тестирование по методике TPC DS.

Подробнее о методиках — ниже по тексту.

Тестирование проводилось на одинаковых настройках ОС, за исключением использования cgroups v1 и cgroups v2.

Базовые настройки кластера также совпадают для всех дистрибутивов:

  • max_connections=400

  • max_prepared_transactions=400

  • gp_resource_group_memory_limit=0.9

Дополнительные настройки кластера для оптимизации делались в рамках тестов и будут указаны ниже в деталях тестирования.

Настройки ресурсных групп выставлялись одинаковые, с поправкой на изменившийся формат конфигурации, за исключением ситуаций, когда тесты падали по памяти. В таком случае выставлялось значение concurrency, при котором тест отрабатывал без ошибок.

Тесты проводили на 4 и 8 сегментах на сегмент-хост. По итогу выбрали конфигурацию с 8 сегментами, так как на ней результаты оказались лучше у всех участников забега. 

Методика НТ MPP-движков

Методика была разработана нашим клиентом совместно с одним из вендоров лет 8 назад и хорошо себя зарекомендовала для use case сценариев проверки решения задач аналитического хранилища данных. Методика, адаптированная под Greenplum, выложена в нашем открытом репозитории: https://git.angara.cloud/gbgreenplum/greenplum.playbook.loadtest

В процессе тестирования моделируются данные и процессы, которые являются типовыми в задачах ETL-вычислений, ad-hoc запросов и, самое главное, в режиме высококонкурентного пользовательского доступа.

Тестирование платформ проводится на одинаковом наборе синтетических данных.

Приблизительный объем несжатых тестовых данных составляет 8 ТБ (терабайт).

Допускается применение любых особенностей платформы для оптимизации тестовых запросов кроме:

  • Принудительного размещения объектов в памяти;

  • Материализации результатов тестовых запросов в виде заранее созданных аналитических проекций, join-индексов, материализованных представлений.

Методика включает в себя следующий набор тестов:

Типовые ETL-задачи:

  • Запрос 1. Группировка данных большой таблицы по полям с разной селективностью.

  • Запрос 2. Группировка данных большой таблицы по полям с разной селективностью:

    • Запрос 2.1. Группировка данных большой таблицы по полям с разной селективностью с фильтром по дате.

  • Запрос 3. Операции сортировки данных большой таблицы 1.

  • Запрос 4. Операции сортировки данных большой таблицы 2.

 Аналитические запросы:

  • Запрос 5. Запросы с аналитическими функциями.

  • Запрос 6. Построение одного большого результирующего набора на основании соединения больших и маленьких таблиц с фильтрацией по полям с разной селективностью.

  • Запрос 7. Построение одного большого результирующего набора на основании соединения больших и маленьких таблиц с фильтрацией по полям с разной селективностью.

Технологические запросы:

  • Запрос 8. Операции вида Create Table As Select из большой таблицы 1.

  • Запрос 9. Операции вида Create Table As Select из большой таблицы 2.

  • Запрос 10. Операции вида insert + update.

  • Запрос 11. Операции вида upsert.

Каждый тест – это запуск соответствующего запроса 1-9 в 10 одновременных подключений. В рамках теста в каждом из подключений могут подставляться свои случайные значения в фильтр. Некоторые запросы работают над всем объемом данных.
В качестве результата берется min, avg и max в рамках каждого теста.
Запросы 10 и 11 запускаются в одно подключение.

 Повышенная конкурентная нагрузка:              

  • Работа всех запросов 1-9 одновременно, каждый из которых работает в 10 одновременных подключений.

  • Работа всех запросов 1-9 одновременно, каждый из которых работает в 20 одновременных подключений.

В качестве результата берется среднее значение выполнения всех запросов в рамках теста.     

Построение нормализованной витрины:

  • Запускается в одно подключение.

В качестве результата берется длительность построения витрины.

В рамках тестирования также замеряется время генерации синтетики и ее итоговый объем.

Методика TPC DS

Информация о методике: https://www.tpc.org/tpcds/.

Если кратко:

  1. При запуске теста задается scale factor, который влияет на количество данных.
    В нашем случае мы делали два теста:

    1. scale factor 1000 – 1ТБ RAW CSV (объем данных в GP AOCO со сжатием ZSTD 3 ~400 ГБ);

    2. scale factor 10000 –  10ТБ RAW CSV (объем данных  в GP AOCO со сжатием ZSTD 3 ~4 ТБ).

  2. Генерируется синтетика.

  3. Запускаются 99 запросов в single user режиме, каждый запрос запускается последовательно. Фиксируется длительность выполнения каждого запроса и длительность выполнения теста.

  4. Запускаются эти же 99 запросов только в multi user режиме. Для тестов Greenplum 6/Greenplum 7/Cloudberry мы выбрали 5 одновременных подключений. Для сравнения с Data Ocean Nova повторяли тест в 4 одновременных подключениях на увеличенном, соответствующем тестам Data Ocean Nova, сайзинге (сайзинг указан в статье). Фиксируется длительность каждого запроса, длительность всего теста и сумма времени по всем запросам.

Результаты тестирования

Для тех, кто шел посмотреть чисто на циферки, сразу итоговый результат.
Ниже будут детали по тестированию GP7 и CBDB и выводы, которые мы для себя сделали.

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

Настройки РГ для GP6 (по сути одинаковые, но разные по формату конфигов):

concurrency

cpu_rate_limit

memory_limit

memory_shared_quota

memory_spill_ratio

10

80

80

0

100

Настройки РГ для GP7 и Cloudberry:

concurrency

cpu_max_percent

cpu_weight

cpuset

memory_limit

min_cost

io_limit

10

100

500

-1

80

0

-1

Результаты:

Таблица. Сравнение результатов тестирования по методике НТ MPP-движков для GP6, GP7 и CBDB
Таблица. Сравнение результатов тестирования по методике НТ MPP-движков для GP6, GP7 и CBDB
Диаграмма. Сравнение GP6, GP7 и CBDB. Чем меньше, тем лучше
Диаграмма. Сравнение GP6, GP7 и CBDB. Чем меньше, тем лучше
Диаграмма. Сравнение конкурентной нагрузки и построения витрины на GP6, GP7 и CBDB. Чем меньше, тем лучше
Диаграмма. Сравнение конкурентной нагрузки и построения витрины на GP6, GP7 и CBDB. Чем меньше, тем лучше

Объемы синтетических данных (при одинаковом количестве строк в таблицах):

GP6, GB

GP7, GB

CBDB, GB

Contractor

1

1.5

1

Account

19

17

17

Agreement

10

9

8

Document

419

389

389

Transaction

866

835

687

Transaction индексы

7

Сумма

1315

1251.5

1109

Время генерации данных:

GP6, сек

GP7, сек

CBDB, сек

19800

17600

25200

Результаты tpc-ds:

Таблица. Сравнение результатов tpc-ds для GP6, GP7 и CBDB
Таблица. Сравнение результатов tpc-ds для GP6, GP7 и CBDB
Диаграмма. Сравнение результатов tpc-ds для GP6, GP7 и CBDB. Чем меньше, тем лучше
Диаграмма. Сравнение результатов tpc-ds для GP6, GP7 и CBDB. Чем меньше, тем лучше

Что видим из тестов:

  1. В большинстве тестов все дистрибутивы показывают схожие результаты.

  2. Cloudberry очень плохо показывает себя на группировках и сортировках (группы запросов 1, 2, 3 и 4).

  3. За счет оптимизаций витрина на Cloudberry считается намного быстрее (последний тест – запрос построения витрины).

  4. Cloudberry эффективнее хранит данные. В GP7 тоже есть улучшения по оптимальности хранения относительно GP6.

  5. В tpc-ds GP7 проявил себя лучше, но прирост производительности незначительный.

  6. При этом есть вопросы по стабильности работы Cloudberry и GP7. Для GP7 пришлось повторять тест, так как половина тестов упала из-за проблем с интерконнектом. Но проблемы плавающие, при повторном тесте только один запрос упал с ошибкой. Аналогичные проблемы есть у Cloudberry.

Детали тестирования Greenplum 7

Тестирование проводилось в конфигурации: 8 сегментов на хост. 

В рамках тестирования проводилось 2 итерации:

  1. С использованием cgroups v1.

  2. С использованием cgroups v2.

В обоих случаях распределение ресурсов между группами настраиваются через одну системную таблицу, соответственно, имеет полностью идентичный интерфейс конфигурирования.

Но при использовании cgroups v1 игнорируется настройка ограничения на IO.

Также при переключении ресурсных групп меняются внутренние механизмы выделения и распределения ресурсов между процессами. 

В наших тестах мы не упирались в диски, поэтому ограничение на IO не выставляли.  

Настройки ресурсных групп одинаковые для всех тестов:

concurrency

cpu_max_percent

cpu_weight

cpuset

memory_limit

min_cost

io_limit

10

100

500

-1

80

0

-1

Результаты:

Таблица. Сравнение результатов GP7 на разных версиях cgroups
Таблица. Сравнение результатов GP7 на разных версиях cgroups

Из результатов видно, что при использовании cgroups v1 результаты получаются лучше. При этом cgroups v2 дают более тонкую настройку и могут давать эффект в инсталляциях с сильно нагруженными дисками.

Одна из самых интересных фичей в GP7 – BRIN Index.

Эту фичу мы сначала очень ждали в GP6. Потом очень ждали GP7, чтобы протестировать, что же в итоге получилось. Проверяли его на самой большой таблице transaction (21 млрд записей, 835 GB).

Размер индекса – 9 ГБ.

Одно из самых больших разочарований в GP7 – BRIN Index.

Он не сработал на таком объеме данных. При этом он срабатывает для данного запроса, если в таблице transaction мало данных (в public была создана таблица transaction с тем же ddl, вставлено небольшое количество записей из оригинальной таблицы, создан BRIN Index, произведен analyze). При том что BRIN можно создать над AO таблицей и занимает он не так много места, как, например, уникальный индекс, его все еще нужно обслуживать и его обновление занимает время. По итогу минусов все равно больше, чем плюсов. 

План запроса на большом объеме данных:

Gather Motion 32:1  (slice1; segments: 32)  (cost=0.00..10360.61 rows=493 width=16) (actual time=76433.414..76433.895 rows=500 loops=1)
  ->  Finalize HashAggregate  (cost=0.00..10360.59 rows=16 width=16) (actual time=76373.141..76373.181 rows=29 loops=1)
        Group Key: transaction_type_id_int
        Extra Text: (seg0)   hash table(s): 1; chain length 1.7 avg, 2 max; using 12 of 32 buckets; total 0 expansions.
 
        Extra Text: (seg10)  hash table(s): 1; chain length 2.2 avg, 3 max; using 29 of 64 buckets; total 1 expansions.
 
        ->  Redistribute Motion 32:32  (slice2; segments: 32)  (cost=0.00..10360.59 rows=16 width=16) (actual time=66239.748..76372.765 rows=928 loops=1)
              Hash Key: transaction_type_id_int
              ->  Streaming Partial HashAggregate  (cost=0.00..10360.59 rows=16 width=16) (actual time=66976.504..66976.617 rows=500 loops=1)
                    Group Key: transaction_type_id_int
                    Extra Text: (seg0)   hash table(s): 1; chain length 2.2 avg, 4 max; using 500 of 1024 buckets; total 5 expansions.
 
                    ->  Dynamic Seq Scan on transaction  (cost=0.00..6739.84 rows=29728907 width=16) (actual time=16.495..35916.451 rows=29827513 loops=1)
                          Number of partitions to scan: 12 (out of 264)
                          Filter: ((transaction_date >= '2015-01-01 00:00:00'::timestamp without time zone) AND (transaction_date <= '2015-12-31 00:00:00'::timestamp without time zone))
                          Partitions scanned:  Avg 12.0 x 32 workers.  Max 12 parts (seg0).
Optimizer: GPORCA
Planning Time: 123.700 ms
  (slice0)	Executor memory: 57K bytes.
* (slice1)	Executor memory: 48K bytes avg x 32 workers, 48K bytes max (seg0).  Work_mem: 24K bytes max, 24K bytes wanted.
* (slice2)	Executor memory: 423K bytes avg x 32 workers, 423K bytes max (seg0).  Work_mem: 129K bytes max, 129K bytes wanted.
Memory used:  128000kB
Memory wanted:  556kB
Execution Time: 76504.757 ms

План запроса на малом объеме данных:

Gather Motion 32:1  (slice1; segments: 32)  (cost=0.00..388.27 rows=1 width=16) (actual time=8.302..8.304 rows=0 loops=1)
  ->  GroupAggregate  (cost=0.00..388.27 rows=1 width=16) (actual time=0.000..7.711 rows=0 loops=1)
        Group Key: transaction_type_id_int
        ->  Sort  (cost=0.00..388.27 rows=1 width=8) (actual time=0.000..7.709 rows=0 loops=1)
              Sort Key: transaction_type_id_int
              Sort Method:  quicksort  Memory: 800kB
              Executor Memory: 802kB  Segments: 32  Max: 26kB (segment 0)
              ->  Redistribute Motion 32:32  (slice2; segments: 32)  (cost=0.00..388.27 rows=1 width=8) (actual time=0.000..7.702 rows=0 loops=1)
                    Hash Key: transaction_type_id_int
                    ->  Dynamic Bitmap Heap Scan on transaction  (cost=0.00..388.27 rows=1 width=8) (actual time=0.000..5.276 rows=0 loops=1)
                          Number of partitions to scan: 12 (out of 264)
                          Recheck Cond: ((transaction_date >= '2015-01-01 00:00:00'::timestamp without time zone) AND (transaction_date <= '2015-12-31 00:00:00'::timestamp without time zone))
                          Filter: ((transaction_date >= '2015-01-01 00:00:00'::timestamp without time zone) AND (transaction_date <= '2015-12-31 00:00:00'::timestamp without time zone))
                          Heap Blocks: exact=4294967295
                          Partitions scanned:  Avg 12.0 x 32 workers.  Max 12 parts (seg0).
                          ->  Dynamic Bitmap Index Scan on brin_transaction_date_idx  (cost=0.00..0.00 rows=0 width=0) (actual time=0.000..0.038 rows=0 loops=12)
                                Index Cond: ((transaction_date >= '2015-01-01 00:00:00'::timestamp without time zone) AND (transaction_date <= '2015-12-31 00:00:00'::timestamp without time zone))
Optimizer: GPORCA
Planning Time: 48.915 ms
  (slice0)	Executor memory: 48K bytes.
  (slice1)	Executor memory: 48K bytes avg x 32 workers, 48K bytes max (seg0).  Work_mem: 26K bytes max.
  (slice2)	Executor memory: 219K bytes avg x 32 workers, 219K bytes max (seg0).
Memory used:  128000kB
Execution Time: 27.278 ms

Еще в GreenPlum 7 появился UPSERT.

Но только для heap-таблиц.

И с ACCESS EXCLUSIVE блокировкой, если не включен Global Deadlock Detector.

Мы решили сравнить стандартный INSERT + UPDATE, с которым мы живем в GP6, и UPSERT.

Запрос 10. Операции вида insert + update

3673

Запрос 11. Операции вида upsert

1104

В обоих тестах одинаковый объем дельты, которая применяется к самой большой таблице transaction.

Так как upsert работает только с heap-таблицами, для запроса 11 была создана копия таблицы transaction. Также для работы upsert нужен уникальный индекс над таблицей.

Время создания heap-таблицы и уникального индекса заняло 6 часов: из них 3 часа на загрузку данных в таблицу и 3 часа на создание индекса.  

Что имеем в итоге: upsert работает в 3 раза быстрее. Но есть один нюанс. А точнее ряд нюансов. Для работы upsert необходимо в 8 раз больше места. Индекс подобного объема требует пристального внимания и регулярного обслуживания со стороны DBA. Перестроение такого индекса при вставках в таблицу будет занимать недопустимо много времени. 

Ниже сравнение объемов таблиц:

Transaction AOT

835 GB

Transaction Heap

5691 GB

Уникальный индекс Transaction

1134 GB

Детали тестирования Cloudberry

На наш взгляд, в Cloudberry больше интересных оптимизаций. Это связано по большей части с использованием Postgres 14 в качестве ядра.

Но и тут не обошлось без нюансов. Все новые параметры, влияющие на оптимизацию, работают только с Postgres legacy optimizer. А это значит, что такие запросы могут работать неоптимально и даже токсично в Greenplum-подобных системах. Это можно заметить и по графикам потребления ресурсов в тестах ниже. При анализе оптимальности запросов в Greenplum мы в первую очередь обращаем внимание на используемый оптимизатор, так что считаем это очень важным моментом.  

Аuto materialized views AQUMV

Создаем инкрементальную материализованную view. Включаем параметр enable_answer_query_using_materialized_views = ON.

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

Звучит хорошо, но на данный момент имеет очень много ограничений:

  • Only SELECT queries for a single relationship are supported, which is applicable to materialized view queries and the original queries.

  • Unsupported features include:

    • Aggregation (AGG)

    • Subqueries

    • Sorting of original queries (ORDER BY)

    • Joins (JOIN)

    • Sublinks (SUBLINK)

    • Grouping (GROUP BY)

    • Window functions

    • Common table expressions (CTE)

    • Deduplication (DISTINCT ON)

    • Refreshing materialized views (REFRESH MATERIALIZED VIEW)

    • CREATE AS statements

  • Не поддерживаются партицированные таблицы

В наших тестах ни один запрос не подошел под эту фичу. Возможно, после доработок она станет полезной.

Параллельность вычислений

Для каждого запроса можно задать параллельность его вычисления. По сути, количество сегментов умножается на указанную параллельность.

Мы задались вопросом: а что если сделать кластер с маленьким количеством сегментов на хосте, например, 2, а дальше под каждый запрос выставлять разную степень параллелизма? Таким образом, можно получить достаточно гибкую систему.

Решено было сравнить стандартную конфигурацию с 8 сегментами на хост и включенным gporca и конфигурацию с 2 сегментами на хост и параллельностью 4 (в такой конфигурации в плане запроса это выглядит как те же 8 сегментов на хост).

Таблица. Сравнение результатов CBDB с разной параллельностью
Таблица. Сравнение результатов CBDB с разной параллельностью

Тесты показывают, что в большинстве случаев это реально может работать быстрее и более гибко. Но если в запросе есть motion-операции, то увеличение параллельности очень сильно увеличит объем перераспределения данных, а в случае с broadcast motion это кратно увеличит время выполнения запроса.

Ниже графики нагрузки.

Тест для gporca:

Рис. Графики нагрузки при использовании gporca
Рис. Графики нагрузки при использовании gporca

Тест для 2 сегментов на хост с параллельностью 4:

Рис. Графики нагрузки при использовании legacy-оптимизатора с параллельностью 4
Рис. Графики нагрузки при использовании legacy-оптимизатора с параллельностью 4

Aggregation pushdown и RuntimeFilter

Aggregation pushdown позволяет сделать агрегации до джойнов. Для включения необходимо выставить конфигурационный параметр gp_enable_agg_pushdown.

RuntimeFilter – в основе реализации лежат блум-фильтры. При использовании HashJoin данные предварительно могут фильтроваться в рантайме. Оптимизация определяет, следует ли генерировать оператор RuntimeFilter на основе скорости фильтрации условий соединения HashJoin и размера внутренней таблицы. Если объем данных слишком сильно отклоняется от предполагаемого результата во время фактического выполнения, то использование RuntimeFilter будет автоматически отключено. Для включения – выставить конфигурационный параметр gp_enable_runtime_filter.

Но и тут на данный момент есть ограничения: работает это, только если предполагаемое количество строк во внутренней таблице составляет менее 16 миллионов.

Ниже результаты сравнения тестов на gporca и с оптимизациями.

Настройки РГ одинаковы для всех тестов:

concurrency

cpu_max_percent

cpu_weight

cpuset

memory_limit

min_cost

io_limit

10

100

500

-1

80

0

-1

Результаты:

Таблица. Сравнение результатов CBDB с оптимизациями и без
Таблица. Сравнение результатов CBDB с оптимизациями и без

Сильнее всего оптимизации ощущаются при построении витрины, так как там срабатывают и pushdown-агрегации, и RuntimeFilter. Но и тут есть небольшие странности: когда мы анализировали графики потребления ресурсов, то заметили, что при использовании Postgres optimizer потребление ресурсов имеет больший перекос по CPU и дискам. Это заметно и на графике тестов параллельности.

График нагрузки при использовании оптимизаций:

Рис. Графики нагрузки при использовании legacy-оптимизатора с оптимизациями
Рис. Графики нагрузки при использовании legacy-оптимизатора с оптимизациями

По итогам тестов делаем важный для себя вывод: кажется, для CBDB оптимальнее всего делать кластеры с 4 сегментами на хост и для каждого запроса точечно определять стратегию его расчета:

  • без оптимизаций, но с gporca;

  • c Postgres-оптимизатором, но с возможностью указать параллельность и опции оптимизации.

Отвечаем на вопросы, которыми задавались в начале

  • По производительности на данный момент все три дистрибутива сравнимы. За исключением некоторых тестов, в которых есть как улучшения, так и ухудшения производительности.

  • К стабильности тоже остаются вопросы. Если основные тесты по нашей методике отработали стабильно, то тесты tpcds часто падали по ошибке, связанной с интерконнектом. Такую же ошибку мы наблюдали на НТ другой сборки GP7 у одного из наших заказчиков. Возможно, это какой-то баг ядра, исследование мы пока не проводили.

  • Работа с Iceberg и другими открытыми форматами все еще является слабой стороной Greenplum, что не позволяет использовать его как generic SQL engine. В GP7 и CBDB в этой части улучшений нет. 

  • С учетом всего перечисленного выше, миграция на GP7 или Cloudberry на данный момент не имеет особого смысла. Затраты на миграцию, скорее всего, будут перевешивать улучшения в дистрибутивах GP7 и Cloudberry, тем более можно напороться на неприятные баги, влияющие на стабильность системы.

Лично от себя добавлю: Сloudberry мне показался более интересным и перспективным за счет более интересных фичей из Postgres 14.

Будем следить за развитием продуктов!

Комментарии (0)