Partager via


Tutoriel : Conception pour les microservices avec des clusters élastiques

Dans ce tutoriel, vous utilisez Azure Database pour PostgreSQL comme back-end de stockage pour plusieurs microservices. Le tutoriel illustre un exemple d’installation et d’opération de base d’un tel cluster. Découvrez comment :

  • Prerequisites
  • Créer des rôles pour vos microservices
  • Utiliser l’utilitaire psql pour créer des rôles et des schémas distribués
  • Créer des tables pour les exemples de services
  • Configurer les services
  • Exécuter les services
  • Explorer la base de données

Prerequisites

Créez un cluster élastique de l’une des manières suivantes :

Créer des rôles pour vos microservices

Vous pouvez placer dynamiquement des schémas distribués au sein d’un cluster élastique. Le système peut les rééquilibrer en une unité entière sur les nœuds disponibles. Vous bénéficiez donc d’une amélioration de l’efficacité sur vos ressources de cluster sans allocation manuelle.

Lorsque vous appliquez le partitionnement de schéma à un modèle de conception de microservice, vous créez un schéma de base de données pour chaque microservice correspondant. Utilisez également un RÔLE distinct pour chaque microservice lors de la connexion à la base de données. Lorsque chaque utilisateur se connecte, son nom de rôle passe au début de la search_path. Si le nom du rôle correspond au nom du schéma, vous n’avez pas besoin de modifications d’application supplémentaires pour définir la search_path correcte.

Dans cet exemple, utilisez trois microservices :

  • utilisateur
  • time
  • ping

Créez les rôles de base de données pour chaque service :

CREATE USER user_service;
CREATE USER time_service;
CREATE USER ping_service;

Utiliser l’utilitaire psql pour créer des schémas distribués

Après vous être connecté au cluster élastique à l’aide de psql, vous pouvez effectuer certaines tâches de base.

Vous pouvez distribuer un schéma de deux façons :

  • Manuellement en appelant la fonction citus_schema_distribute(schema_name).
CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

SELECT citus_schema_distribute('user_service');
SELECT citus_schema_distribute('time_service');
SELECT citus_schema_distribute('ping_service');

Cette méthode vous permet également de convertir des schémas standard existants en schémas distribués.

Note

Vous ne pouvez distribuer que des schémas qui ne contiennent pas de tables distribuées et de référence.

  • En activant la variable de citus.enable_schema_based_sharding configuration. Vous pouvez modifier la variable de la session active ou définitivement à partir des paramètres du nœud coordinateur. Lorsque vous définissez le paramètre sur ON, tous les schémas créés sont distribués par défaut.
SET citus.enable_schema_based_sharding TO ON;

CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

Exécutez la commande suivante pour répertorier les schémas actuellement distribués :

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             5 | 0 bytes     | user_service
 time_service |             6 | 0 bytes     | time_service
 ping_service |             7 | 0 bytes     | ping_service
(3 rows)

Créer des tables pour les exemples de services

Vous pouvez maintenant vous connecter au cluster élastique pour chaque microservice. Dans l’exemple suivant, la base de données de cluster élastique est nommée Citus. À partir de la session psql, vous pouvez utiliser la commande \c pour échanger vers un autre utilisateur.

\c citus user_service
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
\c citus time_service
CREATE TABLE query_details (
    id SERIAL PRIMARY KEY,
    ip_address INET NOT NULL,
    query_time TIMESTAMP NOT NULL
);
\c citus ping_service
CREATE TABLE ping_results (
    id SERIAL PRIMARY KEY,
    host VARCHAR(255) NOT NULL,
    result TEXT NOT NULL
);

Configurer les services

Dans ce tutoriel, nous utilisons un ensemble simple de services. Vous pouvez les obtenir en clonant ce dépôt public :

git clone https://github.com/citusdata/citus-example-microservices.git
$ tree
.
├── LICENSE
├── README.md
├── ping
│   ├── app.py
│   ├── ping.sql
│   └── requirements.txt
├── time
│   ├── app.py
│   ├── requirements.txt
│   └── time.sql
└── user
    ├── app.py
    ├── requirements.txt
    └── user.sql

Avant d’exécuter les services toutefois, modifiez user/app.py, ping/app.pyet time/app.py des fichiers fournissant la configuration de connexion pour votre cluster élastique :

# Database configuration
db_config = {
    'host': 'EXAMPLE.postgres.database.azure.com',
    'database': 'postgres',
    'password': 'SECRET',
    'user': 'ping_service',
    'port': 5432
}

Après avoir apporté les modifications, enregistrez tous les fichiers modifiés et passez à l’étape suivante, l’exécution des services.

Exécuter les services

Accédez à chaque répertoire d’application et exécutez-les dans leur propre environnement Python.

cd user
pipenv install
pipenv shell
python app.py

Répétez les commandes pour le service de temps et le service ping, après quoi vous pouvez utiliser l’API.

Créez des utilisateurs :

curl -X POST -H "Content-Type: application/json" -d '[
  {"name": "John Doe", "email": "john@example.com"},
  {"name": "Jane Smith", "email": "jane@example.com"},
  {"name": "Mike Johnson", "email": "mike@example.com"},
  {"name": "Emily Davis", "email": "emily@example.com"},
  {"name": "David Wilson", "email": "david@example.com"},
  {"name": "Sarah Thompson", "email": "sarah@example.com"},
  {"name": "Alex Miller", "email": "alex@example.com"},
  {"name": "Olivia Anderson", "email": "olivia@example.com"},
  {"name": "Daniel Martin", "email": "daniel@example.com"},
  {"name": "Sophia White", "email": "sophia@example.com"}
]' http://localhost:5000/users

Listez les utilisateurs créés :

curl http://localhost:5000/users

Obtenez l’heure actuelle :

Get current time:

Exécutez le test ping sur example.com :

curl -X POST -H "Content-Type: application/json" -d '{"host": "example.com"}' http://localhost:5002/ping

Explorer la base de données

Maintenant que vous avez appelé certaines fonctions d’API, les données sont stockées et vous pouvez vérifier si citus_schemas ce qui est attendu :

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             1 | 112 kB      | user_service
 time_service |             2 | 32 kB       | time_service
 ping_service |             3 | 32 kB       | ping_service
(3 rows)

Lorsque vous avez créé les schémas, vous n’avez pas indiqué sur quelles machines créer les schémas. Cela a été fait automatiquement. Vous pouvez voir où réside chaque schéma avec la requête suivante :

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
nodename  | nodeport |         table_name         | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
 localhost |     7002 | ping_service.ping_results  | 32 kB

Pour obtenir une concision de l’exemple de sortie sur cette page, au lieu d’utiliser nodename comme adresse IP, nous la remplaçons par localhost. Supposons que localhost:7001 s’agit du nœud un et que localhost:7002 s’agit du nœud deux.

Vous pouvez constater que le service de temps a atterri sur le nœud localhost:7001, tandis que le service utilisateur et le service ping partagent de l’espace sur le deuxième nœud localhost:7002. Les exemples d’applications sont simplistes et les tailles de données ici sont insignifiantes, mais supposons que vous êtes affecté par l’utilisation inégale de l’espace de stockage entre les nœuds. Il serait plus logique que les deux services plus petits, ceux liés au temps et au ping, résident sur un seul nœud, tandis que le service utilisateur, plus important, réside sur son propre nœud.

Vous pouvez facilement rééquilibrer le cluster par taille de disque :

SELECT citus_rebalance_start();
NOTICE:  Scheduled 1 moves as job 1
DETAIL:  Rebalance scheduled as background job
HINT:  To monitor progress, run: SELECT * FROM citus_rebalance_status();
 citus_rebalance_start
-----------------------
                     1
(1 row)

Lorsque vous avez terminé, vous pouvez vérifier à quoi ressemble notre nouvelle disposition :

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
 nodename  | nodeport |         table_name        | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7001 | ping_service.ping_results  | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
(3 rows)

Conformément aux attentes, les schémas sont déplacés et nous avons un cluster plus équilibré. Cette opération est transparente pour les applications. Vous n’avez même pas besoin de les redémarrer, ils continuent à traiter des requêtes.

Étape suivante