Nœuds et tables dans Azure Cosmos DB for PostgreSQL

S’APPLIQUE À : Azure Cosmos DB for PostgreSQL (avec l’extension de base de données Citus pour PostgreSQL)

Nœuds

Azure Cosmos DB for PostgreSQL permet aux serveurs PostgreSQL (appelés nœuds) de se coordonner entre eux dans une architecture dite « sans partage ». Collectivement, les nœuds dans un cluster contiennent davantage de données et utilisent plus de cœurs d’UC que ce qui serait possible sur un seul serveur. L’architecture permet également à la base de données de mettre à l’échelle en ajoutant des nœuds supplémentaires au cluster.

Coordinateur et travailleurs

Chaque cluster dispose d’un nœud coordinateur et de plusieurs Workers. Les applications envoient leurs requêtes vers le nœud coordinateur, qui les relaie vers les Workers concernés et accumule leurs résultats.

Azure Cosmos DB for PostgreSQL permet à l’administrateur de base de données de distribuer des tables et/ou des schémas, stockant différentes lignes sur différents nœuds Worker. Les tables et/ou les schémas distribués sont la clé des performances d’Azure Cosmos DB for PostgreSQL. À défaut de distribuer les tables et/ou les schémas, ils restent entièrement sur le nœud coordinateur et ne peuvent pas tirer parti du parallélisme entre ordinateurs.

Soit le coordinateur achemine chaque requête sur des tables distribuées vers un nœud Worker unique, soit il la met en parallèle sur plusieurs autres, en fonction de l’emplacement des données requises, sur un nœud unique ou sur plusieurs nœuds. Avec le partitionnement basé sur les schémas, le coordinateur achemine les requêtes directement vers le nœud qui héberge le schéma. Dans le partitionnement basé sur les schémas et le partitionnement basé sur les lignes, le coordinateur décide de l’action à effectuer en consultant les tables de métadonnées. Ces tables suivent les noms DNS et l’intégrité des nœuds Worker, ainsi que la distribution des données entre les nœuds.

Types de tables

Il existe cinq types de tables dans un cluster, chacune stockée différemment sur des nœuds et utilisée à différentes fins.

Type 1 : Tables distribuées

Le premier type (le plus courant) est celui des tables distribuées. Elles ressemblent à des tables normales pour les instructions SQL, mais sont partitionnées horizontalement dans les nœuds worker. Cela signifie que les lignes de la table sont stockées sur des nœuds différents dans les tables de fragments appelées partitions.

Azure Cosmos DB for PostgreSQL exécute non seulement des instructions SQL mais aussi des instructions DDL dans un cluster. La modification du schéma d’une table distribuée a pour effet en cascade de mettre à jour toutes les partitions de table des Workers.

Colonne de distribution

Azure Cosmos DB for PostgreSQL utilise le partitionnement algorithmique pour affecter des lignes à des partitions. L’affectation est effectuée de façon déterministe en fonction de la valeur d’une colonne de table appelée colonne de distribution. L’administrateur de cluster doit désigner cette colonne lors de la distribution d’une table. Il est important pour les performances et les fonctionnalités de faire le bon choix.

Type 2 : Tables de référence

Une table de référence est un type de table distribuée dont l’intégralité du contenu est concentré dans une seule partition. La partition est répliquée sur chaque Worker. Les requêtes sur un Worker peuvent accéder localement aux informations de référence, sans surcharger le réseau en demandant des lignes d’un autre nœud. Les tables de référence n’ont pas de colonne de distribution, car il n’est pas nécessaire de distinguer des partitions différentes par ligne.

Les tables de référence sont généralement petites et servent à stocker des données qui s’appliquent aux requêtes en cours d’exécution sur n’importe quel nœud Worker. C’est, par exemple, le cas des valeurs énumérées telles que les états de commande ou les catégories de produits.

Type 3 : Tables locales

Lorsque vous utilisez Azure Cosmos DB for PostgreSQL, le nœud coordinateur auquel vous vous connectez est une base de données PostgreSQL normale. Vous pouvez créer des tables ordinaires sur le coordinateur et choisir de ne pas les partitionner.

Les petites tables d’administration qui ne font pas partie de requêtes de jointure font d’excellentes tables locales. C’est, par exemple, le cas d’une table users pour l’authentification et la connexion à l’application.

Type 4 : tables gérées locales

Azure Cosmos DB for PostgreSQL peut automatiquement ajouter des tables locales aux métadonnées si une référence de clé étrangère existe entre une table locale et une table de référence. En outre, les tables gérées localement peuvent être créées manuellement en exécutant la fonction create_reference_table citus_add_local_table_to_metadata sur des tables locales régulières. Les tables présentes dans les métadonnées sont considérées comme des tables gérées et peuvent être interrogées à partir de n’importe quel nœud. Citus sait effectuer l’acheminement vers le coordinateur afin d’obtenir des données de la table gérée locale. Ces tables sont affichées en tant que ressources locales dans la vue citus_tables.

Type 5 : tables de schémas

Avec le partitionnement basé sur le schéma introduit dans Citus 12.0, les schémas distribués sont automatiquement associés à des groupes de colocation individuels. Les tables créées dans ces schémas sont automatiquement converties en tables distribuées colocalisées sans clé de partition. Ces tables sont considérées comme des tables de schémas et sont affichées en tant que schéma dans la vue citus_tables

Partitions

La section précédente décrivait la façon dont les tables distribuées sont stockées en tant que partitions sur les nœuds worker. Cette section fournit d’autres détails techniques.

La table de métadonnées pg_dist_shard sur le coordinateur contient une ligne pour chaque partition de chaque table distribuée dans le système. La ligne correspond à un ID de partition avec une plage d’entiers dans un espace de hachage (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)

Si le nœud coordinateur souhaite déterminer quelle partition héberge une ligne de github_events, il hache la valeur de la colonne de distribution dans la ligne. Ensuite, le nœud vérifie quelle plage de la partition contient la valeur hachée. Les plages sont définies de sorte que l’image de la fonction de hachage soit leur union disjointe.

Placements de partition

Supposons que la partition 102027 est associée à la ligne en question. La ligne est lue ou écrite dans une table appelée github_events_102027 dans un des Workers. Quel worker ? Cela est entièrement déterminé par les tables de métadonnées. Le mappage de partition au Worker est appelé positionnement de partition.

Le nœud coordinateur réécrit les requêtes en fragments qui font référence à des tables spécifiques, telles que github_events_102027, et exécute ces fragments sur les Workers appropriés. Voici un exemple d’une requête exécutée en arrière-plan pour rechercher le nœud contenant l’ID de partition 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 │
└─────────┴───────────┴──────────┘

Étapes suivantes