Цикл статей о Greenplum. Часть 1. GP под капотом
Всем привет!
Как вы знаете, многие поставщики ПО ушли с российского рынка ввиду введённых санкций и многие компании столкнулись с необходимость заняться импортозамещением в кратчайшие сроки. Не стал исключением и наш заказчик. Целевой системой, на которое было принято решение мигрировать старое хранилище, стал Greenplum (далее GP) от компании Arenadata.
Этой статьей мы c @omoskvin запускаем цикл материалов посвященных Greenplum. В рамках цикла мы разберем, как вообще устроен GP и как выглядит его архитектура. Постараемся выделить must have практики при работе с данным продуктом, а также обсудим, как можно спроектировать хранилище на GP, осуществлять мониторинг эффективности работы и многое другое. Данный цикл статей будет полезен как разработчикам БД, так и аналитикам.
Вне зависимости от роли в команде важно понимать основы администрирования СУБД. Ведь прежде, чем без раздумий копировать DDL из старого хранилища в GP, конечно же нужно понимать, как выглядит архитектура СУБД и с чем придется столкнуться в работе. Для чего это нужно? Представим ситуацию, у вас написан идеальный SQL запрос, лишние подзапросы и неэффективные соединения таблиц сведены к минимуму, однако выполняется код уже час (случай из реальной практики) и никак не выдаст результат. В такие моменты стоит «думать как система», чтобы понять истинную причину такой долгой работы.
Вступление
В двух словах, Greenplum — это массивно-параллельная аналитическая база данных с открытым исходным кодом, основанная на PostgreSQL. Она оптимальна для аналитических задач, связанных с огромными объемами данных, что позволяет создавать обширные и надежные системы хранения. Это стало возможным благодаря архитектуре MPP и довольно мощным алгоритмам оптимизации.
Если вы ранее не сталкивались с подобным понятием, попробуем разобраться, что такое MPP система. Наверняка, почти каждый из читающих сейчас эту статью, использует ноутбук. Представим, что вы установили на него экземпляр Postgres, с которым будете работать. С выполнением простых запросов на небольшом количестве данных проблем возникнуть не должно. Однако более сложные запросы ограничены мощностью вашего ноутбука, его памятью и т.д. А теперь представьте, что ноутбуки всех читателей объединены в одну сеть, физически данные между ними также распределены поровну. Запрос выполняется, задействуются несколько ноутбуков одновременно. Очевидно, что, работая параллельно, они сделают это куда быстрее. По своей сути это и есть MPP.
Так как Greenplum состоит из инстансов PostgreSQL, между ними есть сходства и различия.
Сходства Greenplum с PostgreSQL:
синтаксис SQL, объекты базы данных и встроенные функции;
структура системного каталога;
механизм реализации транзакций (к примеру, матрица блокировок);
ролевая модель;
работа драйвера для PostgreSQL.
Отличия Greenplum от PostgreSQL:
у Greenplum есть иная, чем у PostgreSQL, функциональность и специфичные изменения в системном каталоге (специфичные технические таблицы);
некоторая функциональность PostgreSQL отличается от Greenplum. К примеру, в GP присутсвует два вида планировщика запроса и большее количество методов сжатия данных;
все механизмы PostgreSQL в Greenplum переписаны под MPP-архитектуру;
PostgreSQL больше подходит для OLTP нагрузок, а Greenplum – для OLAP.
Напомним, что OLTP (Online Transaction Processing) и OLAP (Online Analytical Processing) — это два разных подхода к обработке данных.
OLTP используется для обработки транзакций и подходит для ситуаций, когда необходимо часто обновлять данные небольшими порциями. Примером может служить банковское приложение, где OLTP обеспечивает мгновенное отражение транзакций на счетах и гарантирует точность текущих балансов.
OLAP, в свою очередь, предназначен для быстрых расчётов над большими объёмами данных. Он используется, например, для создания финансовых прогнозов на основе данных о продажах за последние годы.
Архитектура
Физически Greenplum состоит из нескольких хостов, среди которых выделен отдельный хост, к которому подключаются клиенты — мастер-хост. Также мастер-хост содержит все метаданные. Мастер-хост дублируется в целях отказоустойчивости резервным мастер-хостом. В Greenplum всегда есть ровно один мастер-хост и один резервный мастер-хост.
Далее идет интерконнект – сетевой слой. Интерконнект Greenplum использует стандартную коммутационную структуру Ethernet. Из соображений производительности рекомендуется использовать 10-гигабитную систему или выше.
Все остальные хосты предназначены для хранения и обработки данных БД. Эти хосты называются сегмент-хосты, и их может быть несколько, но не менее двух (иначе теряется смысл MPP).
Логически база данных Greenplum является массивом отдельных инстансов PostgreSQL, расположенных на серверах кластера. Различают несколько типов сегментов.
Первичные сегменты (primary segments). Они располагаются внутри сегмент-хостов. Этих сегментов в кластере несколько. В своих директориях первичные сегменты хранят пользовательские данные, с которыми взаимодействуют пользователи, и реплику каталога БД. На первичных сегментах обрабатываются DML-операции, они несут основную пользовательскую нагрузку.
Сегменты-зеркала (mirror segments). Они также располагаются на сегмент-хостах. Этих сегментов в кластере столько же, сколько и первичных. Зеркала хранят реплики данных с первичных сегментов. Они не обрабатывают запросы, а только принимают поток репликации данных, поэтому почти не создают нагрузку на процессор и память. Репликация на зеркалах синхронная: при записи данных на первичный сегмент транзакция не закончится, пока данные не реплицируются на зеркало. Зеркала находятся на других сегмент-хостах, нежели их первичный сегмент, и используются в запросах только в том случае, если основной сегмент отказал.
Мастер-сегмент (master). По аналогии с первичными сегментами, располагается на мастер-хосте. Мастер присутствует в кластере в единственном экземпляре. Он принимает подключения клиентов, выдаёт результаты запросов, обеспечивает координацию работы всего кластера.
Резервный мастер (standby). Располагается на резервном мастер-хосте и принимает поток репликации с мастера. При нормальной работе к нему невозможно подключиться, но в случае отказа мастера можно вручную активировать резеврный мастер и перевести его в режим мастера. Автоматически данный процесс проводится только в последней ванильной версии GP.
Для просмотра конфигурации текущего кластера можно сделать запрос к таблице gp_segment_configuration. Она имеет следующую структуру:
Поле | Тип данных | Описание |
dbid | smallint | Уникальный идентификатор сегмента (или мастера) |
content | smallint | Уникальный идентификатор контента сегмента. Основной сегмент и его зеркало всегда имеют одинаковые идентификатор.Параметр может принимать значения от 0 до N-1, где N — количество сегментов. Для мастер ноды значение всегда равно -1 |
role | char | Роль, в которой сегмент работает в данный момент.Значение p (от primary) для основного и m (от mirror) для зеркала. |
preferred_role | char | Роль, которая изначально была назначена сегменту. Значение p (primary) для основного и m (mirror) для зеркала. |
mode | char | Режим синхронизации основного сегмента и его зеркала.Значение s (synchronized) — сихнронизировано, n (not In sync) - не синхронизировано. |
status | char | Статус работоспособности сегмента.Значение u (up) показывает, что сегмент активен, d (down) — сегмент не работает. |
port | integer | Порт TCP. |
hostname | text | Имя хоста сегмента. |
address | text | Имя хоста, используемое для доступа к конкретному экземпляру сегмента на хосте сегмента.Это значение может совпадать с именем хоста в системах, в которых не настроены имена хостов для каждого интерфейса. |
datadir | text | Каталог данных экземпляра сегмента. |
Например, если мы хотим узнать количество сегмент-хостов в кластере, это можно сделать с помощью запроса:
SELECT COUNT(DISTINCT hostname)
FROM gp_segment_configuration;
Для поиска активных первичных сегментов воспользуемся запросом:
SELECT COUNT(DISTINCT dbid)
FROM gp_segment_configuration
WHERE 1=1
AND role = 'p'
AND status = 'u'
AND content >= 0;
Архитектура запроса
Когда пользователь пишет свой запрос, он попадает на мастер-сегмент, где в первую очередь обрабатывается парсером (parser). Парсер – переводчик с языка человеческого на язык машины. Также в этот момент проверяется синтаксис и в случае возникновения ошибок, запрос падает, возвращая описание ошибки. Если парсер успешно считывает запрос, то далее строится план запроса. За это отвечает оптимизатор. Далее создается подпроцесс QD (query dispatcher). На основе плана запроса он раздаёт различные команды на сегменты. QD и мастер обмениваются данными через общую память. После прихода на сегмент задачи, на нём создаётся подпроцесс QE (query executor) для обработки последующих запросов. QD и QE в каждом сегменте устанавливают интерконнект. Каждый процесс QE будет выполнять назначенную ему подзадачу параллельно или последовательно, после возвращая результаты в QD. QE также взаимодействуют друг с другом через интерконнект. QD суммирует собранные результаты запроса и возвращает их клиенту.
Если подытожить, то:
QD — диспетчер запросов, который является распространителем.
QE — исполнитель запросов, обрабатывающий запросы.
Заключение
Сегодня мы разобрали архитектуру GP и узнали, что она состоит из хостов, внутри которых находятся сегменты. Мастер-хост с одноименным сегментом хранит метаданные и принимает запросы от клиентов. Также на мастере происходит парсинг и строится план запроса. После с помощью сетевого слоя (интерконнект) идёт связь с сегмент-хостами, которые хранят данные в первичных сегментах и их копиях – зеркалах. При запросе на сегментах образуется QE, выполняющий свою подзадачу параллельно или последовательно. Результаты снова возвращаются на мастер и суммируются в QD.
В следующей статье из цикла мы перейдём к созданию таблиц. Обсудим их виды, типы ориентации данных и возможность сжатия данных. Разберёмся, как данные разбиваются по сегментам с помощью дистрибьюции и партиционирования.