Эластичные кластеры на гибком сервере База данных Azure для PostgreSQL

Эластичные кластеры в службе "База данных Azure для PostgreSQL" — это управляемое предложение расширения Citus с открытым исходным кодом для PostgreSQL, которое обеспечивает горизонтальное сегментирование PostgreSQL.

Хотя Citus является просто расширением, он подключает несколько экземпляров PostgreSQL. При развертывании гибкого сервера База данных Azure для PostgreSQL с Citus он обеспечивает управление и настройку нескольких экземпляров PostgreSQL как единого ресурса. Также автоматически настраивает узлы и регистрирует их в расширении Citus.

Эластичные кластеры в службе предлагают две модели сегментирования: сегментирование на основе строк и сегментирование на основе схем. Дополнительные сведения см. в документации с открытым исходным кодом о моделях сегментирования.

Architecture

Эластичные кластеры состоят из одного или нескольких узлов База данных Azure для PostgreSQL гибких серверов. Эти экземпляры автоматически обнаруживают друг друга и подключаются к кластеру Citus. Узлы должны быть одинаковыми уровнями вычислений и хранилища, и их можно масштабировать равномерно вверх или вниз до более высоких или более низких уровней.

Эластичные кластеры используют экземпляры гибких серверов (называемых узлами) для координации друг с другом в архитектуре "общего ничего". Архитектура также позволяет масштабировать базу данных, добавляя дополнительные узлы в кластер.

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

В отличие от Cosmos DB для PostgreSQL, адреса узлов не предоставляются внешним образом. При просмотре таблиц метаданных Citus, например pg_dist_node, можно заметить, что все узлы имеют один и тот же IP-адрес, что и в примере 10.7.0.254 , но разные номера портов.

select nodeid, nodename, nodeport from pg_dist_node;
 nodeid |  nodename  | nodeport
--------+------------+----------
      1 | 10.7.0.254 |     7000
      2 | 10.7.0.254 |     7001
 
(2 rows)

В инфраструктуре Azure эти узлы живут на разных виртуальных машинах, даже если они могут быть разными портами на одном компьютере.

Дополнительные сведения о Citus см. в официальной документации по проекту с открытым кодом.

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

Для каждого запроса в распределенных таблицах запрашиваемый узел либо направляет его на один узел, либо параллелизирует его между несколькими узлами. Решение зависит от того, находятся ли необходимые данные на одном узле или на нескольких. С сегментированием на основе схемы координатор направляет запросы непосредственно на узел, на котором размещена схема. В обоих случаях — при шардировании на основе схем и шардировании на основе строк — узел решает, что делать, обращаясь к таблицам метаданных. Эти таблицы отслеживают расположение и работоспособность узлов, а также распределение данных между узлами.

После распространения данных с помощью одной из моделей сегментирования можно подключиться к любому из узлов для выполнения операций DML (язык изменения данных) (SELECT, UPDATE, INSERT, DELETE). Все узлы содержат метаданные, необходимые для поиска данных, необходимых для запроса, и могут получить его для ответа на запрос.

Операции DDL (язык определения данных) и операции в масштабе всего кластера в настоящее время доступны только на узле, выполняющем роль координатора. Убедитесь, что операции DDL и общекластерные операции выполняются при подключении через порт 5432, а не через порт 7432.

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

Осколки

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

Таблица pg_dist_shard метаданных содержит строку для каждого сегмента каждой распределенной таблицы в системе. Строка соответствует идентификатору сегмента (shardid) с диапазоном целых чисел в хэш-пространстве (shardminvalue, shardmaxvalue).

SELECT * from pg_dist_shard;
logicalrelid  | shardid | shardstorage | shardminvalue | shardmaxvalue
---------------+---------+--------------+---------------+---------------
 github_events |  102026 | t            | 268435456     | 402653183
 github_events |  102027 | t            | 402653184     | 536870911
 github_events |  102028 | t            | 536870912     | 671088639
 github_events |  102029 | t            | 671088640     | 805306367
 
 (4 rows)

Если узел хочет определить, какой сегмент содержит строку github_events, он хэширует значение столбца распространения в строке. Затем узел проверяет, какой диапазон сегмента содержит хэшированное значение. Диапазоны определены так, чтобы образ хэш-функции был их непересекающимся объединением.

Размещение шардов

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

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

SELECT
    shardid,
    node.nodename,
    node.nodeport
FROM pg_dist_placement placement
JOIN pg_dist_node node
  ON placement.groupid = node.groupid
 AND node.noderole = 'primary'::noderole
WHERE shardid = 102027;
┌─────────┬───────────┬──────────┐
│ shardid │ nodename  │ nodeport │
├─────────┼───────────┼──────────┤
│  102027 │ localhost │     5433 │
└─────────┴───────────┴──────────┘