Master 2, Bases de données avancées, année 2023
Objectifs pédagogiques
- Se familiariser avec la plateforme OpenStack.
- Installer PostgreSQL depuis les dépôts sur plusieurs VM et configurer les accès distants.
- Réaliser un micro-benchmarque sur OpenStack pour avoir une idée des performances de PostgreSQL dans cet environnement.
- Mettre en place un mécanisme de distribution des données Primaire/Réplique
- Étudier l’efficacité de ces mécanismes.
Les scripts
Les années précédentes, les étudiants devaient se débrouiller pour installer/configurer PostgreSQL. Cela était intéressant pour monter en compétence et en agilité mais c’était au détriment du contenu pédagogique du cours.
Pour vous aider, je vous fournis des scripts que vous pouvez utiliser et/ou adapter à votre sauce.
Ils ne sont pas obligatoire mais ils vous donnent les étapes de configurations qu’il aurait fallu trouver en autonomie en lisant de la documentation. Leur contenu est par contre à connaître et comprendre.
Utilisation d’OpenStack
- Créez vous une paire de clef publique/privée pour ce cours. Vous pouvez le faire en ligne de commande:
ssh-keygen
Faites en sortes que votre clef privé soit accessible facilement (par exemple en l’ajoutant sur Nextcloud ou par mail).
Si vous partagez votre clef privé comme ça, alors ne l’utilisez pas pour autre chose que ce cours. Il faut la considérer comme non-sûre.
- Connectez vous à openstack et créez une instance Ubuntu avec le moins de ressources possibles. On utilisera éventuellement les ressources disponibles lors d’autres TP.
La plateforme est utilisable depuis chez vous en utilisant le VPN
étudiant. Vous pouvez choisir autre chose qu’ubuntu
mais
les scripts d’aide ne marcherons sans doute pas (et le TP sera plus long
à faire)
Pour cela Suivez le tutoriel
présent sur la plateforme. Configurez votre console local pour pouvoir
vous connecter en ssh
. Pour une instance
ubuntu
avec les clefs ssh configurées correctement il
suffit de faire: ssh ubuntu@[adresse-ip]
où
adresse-ip
est l’adresse indiquée par la plateforme.
Attention, lors de la configuration d’une machine, l’ajout d’une clef n’est pas obligatoire mais sans cela on ne peut pas s’y connecter à distance! N’oubliez pas d’ajouter votre clef publique
- Pour préparer votre VM pour le TP vous pouvez simplement faire:
ssh ubuntu@ip-address "curl -s https://paperman.name/data/scripts/prepare.sh | sh"
Cette commande va exécuter un script qui:
- Ajoute un utilisateur
cha
- Met à jour le MdP root (pour
ILovePostgreSQL
) - Met à jour les paquets
- Installe et configure postgresql sur la VM
- Permet à l’utilisateur
ubuntu
de se connecter à PostgreSQL depuis une machine distante avec le mot de passeubuntu
N’hésitez pas à le regarder pour essayer de comprendre comment il marche!
Pour vérifier que la machine à bien été installée exécuté:
psql -c 'SELECT $$ça marche!$$' -U ubuntu -h ip-address
Vous pouvez vous connecter à votre machine en ssh via la commande
ssh ubuntu@ip-address
Il est souvent commode d’y faire un tour en cas de bug pour être certain que tout a été bien configuré.
Pour ne pas avoir à s’embêter avec les adresses ip, les mots de passes on peut utiliser les variables d’environnement:
export PGHOST=ip-address
export PGUSER=ubuntu
export PGPASSWORD=ubuntu
Vous pouvez stocker ces variables d’environnement dans votre fichier
.bashrc
.
Pour vérifier que ça marche, exécutez:
psql -c 'SELECT $$ça marche!$$'
Une application de publipostage
Nous allons créer une petite application (sans front-end) pour publier des messages sur un forum de discussion. Le schéma est très simple:
CREATE TABLE channel(
id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
UNIQUE,
name TEXT
description TEXT, TIMESTAMP default now()
created_date
);
CREATE TABLE messages(
INTEGER REFERENCES channel(id),
channel_id
pseudo TEXT,
message TEXT, TIMESTAMP default now()
inserted );
Pour ce travail tout doit être fait sur votre machine locale en utilisant la base de donnée paramétrée dans la partie d’avant.
- Créez une base de données
BDA_chan
avec ce schéma.
Pour exécuter un fichier, vous pouvez simplement l’envoyer sur
l’entrée standard de psql
:
cat mon_fichier.sql | psql -h address-ip -U ubuntu --dbname ma_db
- Dans le langage de programmation de votre choix faites une petite API qui permet:
- De poster un nouveau message dans un channel (signature de fonction:
nom_channel, pseudo, message
) - De lire les derniers message dans un channel (signature de fonction:
nom_channel
) - De créer un nouveau channel (signature de fonction:
nom_channel, description
)
- Évaluez l’efficacité du système en écriture avec un programme qui:
- utilise votre API et qui envoie des messages en boucle dans une dizaine de channels prédéfinis,
- peut utiliser plusieurs threads pour simuler des connexions simultanées à la base de données.
- Évaluer l’efficacité du système en lecture avec un programme qui:
- utilise votre API et qui récupère des messages en boucle dans une dizaine de channels prédéfinis.
- Garde un thread qui écrit (de temps en temps) dans la base de données et ajoute des channels et poste des messages.
- Proposez des modifications du schéma pour améliorer les performances du systèmes
Une machine en réplication
Nous allons mettre en place une réplication total de la base de donnée. Il est possible de créer une deuxième instance de PostgreSQL sur la même machine. En situation réelle, il ne faut évidemment pas faire ça et héberger la réplique sur un autre serveur complètement.
Pour créer une nouvelle instance PostgreSQL, sur la machine virtuelle il suffit d’exécuter:
ssh ubuntu@ip-address "curl -s https://paperman.name/data/scripts/configure_replique.sh | sudo sh"
Ce qui va exécuter ce script.
Pour utilisez la réplique, il suffit de changer le port de connexion par défaut. La base de donnée écoute sur le port 5433.
Vérifiez que votre base de données est bien une réplique de la base de donnée principale et que les données sont mises à jour en temps réel.
(optionnelle) vous pouvez adapter le script fourni pour qu’il fonctionne sur une autre VM que vous lancerez pour l’occasion.
Si vous essayez d’écrire dans la réplique, vous devez obtenir une erreur (indiquant que la BDD est en lecture seule)
- Adapter votre api pour que les requêtes en écritures aillent sur la primaire et celles en lecture se répartissent entre la primaire et la secondaire.
Regardez comment les performances évoluent par rapport à l’utilisation d’une unique base de données.
Avec un seul CPU, il est possible que les performances diminuent avec deux instances de PostgreSQL. N’hésitez pas a essayer avec deux VM différentes, voire en empruntant une VM à un copain.
Une base de données réplique peut être promue en une base de donnée
master via la commande PostgreSQL SELECT pg_promote()
.
Faites en sorte que votre API soit résiliente. Si une des bases de données ne fonctionne plus, elle le détecte (via une gestion des erreurs et des timeout) et redirige le trafic vers la base de données qui fonctionne encore.
Vérifiez que votre mécanisme fonctionne bien en tuant durant une exécution de vos benchmark une des deux bases de données.
Il est possible de configurer la base de données primaire pour qu’elle reprenne le contrôle si elle revient en ligne après avoir restaure les données. Il est également possible de s’arranger pour que la primaine devienne la réplique en rejouant le script (légèrement modifié) de création d’une réplique.
Une connexion imparfaite
En situation réelle, les connexions réseaux ont des soucis, sont interrompues, relancées, en fonction des différents problèmes qui peuvent intervenir sur l’un des dizaine d’intermédiaire qui soutient le web mondial.
J’ai voulu simuler une panne en déterrant une fibre optique avec un tractopelle, mais la DSI n’a pas accepté mon projet d’innovation pédagogique.
Par dépit, nous allons simuler un réseau qui tombe en panne via un re-directeur de port que nous allons contrôler.
Pour rediriger un port vers un port nous utilisons
socat
:
socat tcp-l:5430,fork,reuseaddr tcp:127.0.0.1:5432
Vérifiez que votre redirection marche:
psql -h ip-address -p 5430 -U ubuntu -c "SELECT 'youpi ça marche!'"
Il est possible de lancer de manière permanente la commande
socat
:
nohup socat tcp-l:5430,fork,reuseaddr tcp:127.0.0.1:5432 &
- nohup détache le process quand le process parent se ferme.
- le
&
final le met en tache de fond.
Vous pouvez mettre en pause la redirection avec kill
et
le process-id (pid) de socat. Pour le trouver, il suffit de faire
lsof | grep 5430
, c’est le second champ.
kill mon-pid -19
Pour relancer le programme
kill mon-pid -18
Vous pouvez aussi utilisez ctrl+z
et bg
et
fg
via le terminal pour faire ça plus interactivement.
Vous pouvez réutiliser le programme pour déployer un troisième cluster en réplication mais qui cette fois-ci va suivre la primaire sur le port 5430. Pour ça, vous pouvez réutiliser le scripte précédant en lui donnant des arguments.
ssh ubuntu@ip-address "curl -s https://paperman.name/data/scripts/configure_replique.sh | sudo -u postgres sh -s replique2 5430
Le premier argument donne le nom replique2
et le
deuxième le port de la base de données primaire à répliquer.
Verifiez que
replique2
est bien également un réplicat de la base de donnée primaire.Que se passe t’il quand on met
socat
en pause et qu’on essaye d’écrire dansmain
? En analysant attentivement le fichierconfigure_postgresql.sh
déterminez quel option entraîne ce comportement.Modifiez la configuration de la base de donnée primaire pour autoriser la perte de connexion entre elle et
replique2
. Vérifiez quereplique2
rattrape bien son retard quand elle la connexion est rétablie.Le système est dans un état de haute disponibilité (il n’y a jamais d’interruption de service sauf si toutes les machines tombent en même temps). Donnez une séquence d’événements qui entraîne une perte de données.
Compiled the: mar. 17 déc. 2024 14:03:12 CET