Master 2, Bases de données avancées, année 2023
Suite du TP sur Redis
L’objectif de l’examen est de vérifier votre compréhension des concepts suivant:
- Key Value Store
- Écrire des requetes SQL standard
- Le Sharding
Les questions sont essentiellement indépendantes de celles du TP2,
nous allons créer un key-value store avec PostgreSQL pour remplacer
redis
.
Rendu du TP2
Préparer ce que vous avez fait dans le TP2 pour être rendu.
Je veux avoir un unique archive (format zip
ou
tar.gz
) avec:
- Un répertoire racine
prenom.nom
- Un readme
- Un sous repertoire
TP2
- Un sous repertoire
Exam
Vous pouvez prendre un peu de temps pour remettre en forme votre TP mais attention, c’est du temps que vous ne mettrez pas sur le reste de l’examen.
Dans le repertoire Exam, vous pouvez copier vos fichiers de TP2 et repartir de cette base pour continuer.
La note prendra en compte la qualité des rendus dans Exam ET la qualité de TP2.
Le rendu est à faire par mail
Dans le README:
Ajoutez des commentaire qui m’aideront à évaluer votre travail (difficultés particulières, choses non réalisées, bugs mais qui pourrait marcher avec un peu plus de travail).
Ajoutez l’IP de votre VM du premier TP. En théorie, je dois pouvoir m’y connecter si vous avez bien executer le script.
Si ce n’est pas le cas, executer le script suivant dans une nouvelle VM
ssh ubuntu@ip-address "curl -s https://paperman.name/data/scripts/prepare.sh | sh"
ssh: Could not resolve hostname ip-address: Name or service not known
- Ajoutez le contenu du fichier
/etc/machine-id
De Redis à PostgreSQL
Nous allons remplacer la base de donnée Redis
par une
base de données PostgreSQL
.
Pour ce faire, vous allez réaliser les taches suivantes:
- Créer une base de données dans votre instance principale de PostgreSQL
- Créer un schéma SQL pour modéliser une instance Redis.
Vous pouvez tout mettre dans une seule table, mais vous devez modéliser le fait qu’on peut héberger plusieurs BDD redis sur une instance Redis numérotées de 0 a 16.
Les valeurs doivent être des blob binaires, vous pouvez utiliser pour
ça le type PostgreSQL BYTEA
, pour Byte Array.
- On ignore la durée limitées de certaines clefs.
- Les type de données complexe de Redis (List et HashMap) peuvent être
encoder en texte au format
json
.
import json
= ["je suis", 1, "Liste"]
L = json.dumps(L)
s print(s)
["je suis", 1, "Liste"]
Et
= json.loads(s)
K print(L == K)
True
De même pour les dictionnaires:
= {"je":"suis", "un":"dict"}
d = json.dumps(d)
s print(s)
{"je": "suis", "un": "dict"}
Et
= json.loads(s)
K print(d == K)
True
- Écrire dans votre
middleware
une classeKeyValueStore
qui permet de récupérer, d’ajouter et de supprimer des clefs dans la base de donnée PostgreSQL.
Vous pouvez utiliser le template de code suivant en remplaçant
...
par un code qui execute une requête à l’aide de l’objet
cursor et qui retourne le résultat quand cela est nécessaire
(principalement pour le getitem
).
from collections.abc import MutableMapping
import psycopg
def wrap_connect(fct):
def _f(self, *args):
with psycopg.connect(**self.db_connect) as db:
with db.cursor() as cursor:
return fct(self, cursor, *args)
return _f
class KeyValueStore(MutableMapping):
def __init__(self, db_index, **kwargs):
self.db_connect = kwargs
self.db_index = db_index
@wrap_connect
def __delitem__(self, cursor, key):
""" Doit supprimer la clef de self.db_index """
...
@wrap_connect
def __setitem__(self, cursor, key, value):
""" Doit associer key a value dans self.db_index """
...@wrap_connect
def __getitem__(self, cursor, key):
""" Récupère la valeur de key dans self.db_index """
...= cursor.fetchone()
x if x is None:
raise KeyError()
return x
@wrap_connect
def __iter__(self, cursor):
""" Retourne la liste de toutes les clefs de self.db_index """
...
@wrap_connect
def __len__(self, cursors):
""" Retourne le nombre de clefs dans self.db_index """
...
L’usage de cette classe devient alors:
= KeyValueStore(0, port=5432, host="localhost") # retourne la db 0
db0 = KeyValueStore(1, port=5432, host="localhost") # retourne la db 1 db1
Intégrer
Modifier votre middleware pour utiliser la classe KeyValueStore en place de Redis. Vérifier que cette dernière marche toujours.
Sharding
Créez une deuxième base de données PostgreSQL sur la même VM.
Vous pouvez utiliser la commande
pg_createcluster 14 main2
par exemple, en tant
qu’utilisateur postgres
Pour connaitre le port
vous pouvez utiliser la commande
pg_lsclusters
Nous allons implémenter un mécanisme de Sharding
avec
cette nouvelle base. Creez une classe KeyValueStoreSharding
en éditant le template suivant:
class KeyValueStoreSharding(MutableMapping):
def __init__(self, K1: KeyValueStore, K2: KeyValueStore):
...
def __delitem__(self, key):
...
def __setitem__(self, key, value):
...
def __getitem__(self, key):
...
def __iter__(self):
...
def __len__(self):
...
Pour aller plus loin
- Adapter la classe précédante pour ajouter un nombre quelconque de
KeyValueStore
- Implémenter le Rendez vous hashing pour permettre l’ajoute dynamique de base de données.
Compiled the: mar. 17 déc. 2024 14:03:12 CET