Répondre en un clin d'œil
Le site d'une librairie doit savoir qui est connecté à chaque clic. Il doit aussi compter les visiteurs et retenir les cinq dernières pages vues par chacun.
Une base de données classique sait le faire, mais elle ralentit quand des milliers de personnes cliquent ensemble. Un magasin clé-valeur garde ces petits faits en mémoire et répond en une fraction de milliseconde.
À la fin de cette leçon
Remarque
Je peux choisir un magasin clé-valeur pour le bon usage.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Magasin clé-valeur | une base de données qui garde une valeur sous un nom | |
| Clé | le nom qui sert à retrouver une valeur | session:lea |
| Expiration | l'instant où une clé est retirée toute seule | |
| Atomique | fait en une seule étape, qu'on ne peut pas couper en deux | |
| Liste | plusieurs valeurs dans l'ordre, sous une seule clé | |
| Hash | des champs nommés rangés sous une seule clé |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un magasin clé-valeur ressemble à un dictionnaire
Un magasin clé-valeur garde une valeur sous une clé et la rend quand vous donnez la clé. Il ressemble à un dictionnaire Python, mais sur un serveur que de nombreux programmes partagent.
Valkey est un magasin libre qui garde tout en mémoire. Vous lui envoyez une commande comme SET ou GET. Chaque réponse commence par un symbole : + pour une réponse courte, $ pour du texte, : pour un nombre. * annonce une liste de réponses.
Exemple : lire les réponses
| Vous envoyez | Réponse | Cela veut dire |
|---|---|---|
| SET stock:tasse 40 | +OK | Enregistré |
| GET stock:tasse | $2, puis 40 | Un texte de longueur 2, qui vaut 40 |
| INCR visites | :1 | Un nombre, la nouvelle valeur |
| GET cle-absente | $-1 | Il n'y a rien |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Fabriquer un petit client nommé v
v() ( printf '%s\r\n' "$*" | nc -w 1 valkey 6379 )Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ranger le stock de tasses
v SET stock:tasse 40Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le redemander
v GET stock:tasseAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une clé peut expirer toute seule
Une session de connexion ne doit pas durer toujours. Avec EX 60, une clé vit 60 secondes, puis le magasin la retire. Vous n'écrivez aucun code de nettoyage.
TTL demande combien de secondes restent. Quand la clé a disparu, GET répond $-1.
Ranger une session pour une minute
v SET session:lea jeton123 EX 60Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Demander le temps qui lui reste
v TTL session:leaAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Demander une clé qui n'existe pas
v GET session:absenteAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Quand une clé cesse-t-elle d'exister ?
# Une clé avec expiration est une valeur et l'instant où elle disparaît.
entree = ["jeton123", 1060]
for maintenant in [1000, 1059, 1060, 1100]:
if maintenant < entree[1]:
print(maintenant, "encore là :", entree[0])
else:
print(maintenant, "expirée")
# Remplacez 1060 par 1090 puis relancez.
Compteurs et listes travaillent pour vous
INCR ajoute 1 à un nombre et rend la nouvelle valeur. C'est atomique : mille visiteurs en même temps sont tous comptés. Une lecture, un ajout et une écriture séparés pourraient en perdre.
Une liste garde des valeurs dans l'ordre sous une clé. RPUSH ajoute à la fin et LLEN donne la longueur. Un hash garde des champs nommés, comme un profil.
Compter des visites à la main
# Compter les pages vues dans un dictionnaire : lire, ajouter, écrire.
visites = {}
for page in ["accueil", "panier", "accueil", "accueil"]:
if page in visites:
visites[page] = visites[page] + 1
else:
visites[page] = 1
print(visites)
# Un magasin clé-valeur fait cet ajout en une seule étape : plusieurs écrivains ne se gênent pas.
Compter une visite de la page d'accueil
v INCR visites:accueilAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Noter trois pages vues par Léa
v RPUSH recent:lea accueil panier paiementAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Demander quel genre de valeur est rangé
v TYPE recent:leaAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ranger le profil de Léa dans un hash
v HSET client:lea nom Lea ville LyonAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Relire tous les champs du profil
v HGETALL client:leaAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
On croit souvent qu'un magasin clé-valeur est un lieu sûr pour toutes les données. La mémoire est limitée, et une clé peut expirer. Gardez la fiche de référence dans une base de données. Servez-vous du magasin pour des faits rapides et de courte durée.
Pour aller plus loin : limiter les connexions
Une page de connexion doit refuser plus de cinq essais par minute pour un même compte. Avec INCR et EXPIRE, écrivez les commandes que la page envoie à chaque essai, sur une clé comme essais:lea.
Envoyez-les six fois dans le terminal. Quelle réponse donne le sixième essai, et que doit faire la page ? Que se passe-t-il une minute plus tard ?