Redis : stockez des clés/valeurs en mémoire (mais pas que)

Redis : stockez des clés/valeurs en mémoire (mais pas que)

Et vous, combien de Mops ?

Avatar de l'auteur
David Legrand

Publié dans

Logiciel

04/11/2021 18 minutes
24

Redis : stockez des clés/valeurs en mémoire (mais pas que)

Lorsque l'on parle de bases de données, on pense assez logiquement à MySQL, PostgreSQL, SQL Server, Oracle et pourquoi pas à MariaDB, MongoDB ou Cassandra. Mais il en est une, un peu spéciale, qui s'est fait remarquer ces dernières années : Redis. Beaucoup utilisée comme cache, elle a bien d'autres atouts.

Redis, pour REmote DIctionnary Server, est un système de gestion de base de données (SGBD) créé en 2009 par Salvatore Sanfilippo. Il s'agit d'un outil open source (licence BSD-3), développé en C, pensé avant tout pour la performance et pour cause : par défaut, il utilise la mémoire du système comme espace de stockage principal.

Utiliser la mémoire pour des millions d'opérations par seconde

Cette dernière a l'avantage d'être très rapide, avec des débits de plusieurs centaines de Go/s sur des systèmes à huit canaux. Mais aussi en latence, qui est de l'ordre de quelques dizaines de nanosecondes. Là où les meilleurs SSD PCIe/NVMe culminent à 8 Go/s et quelques dizaines de millisecondes, à quelques exceptions près.

Bref, ça va vite et c'est très efficace. Mais il y a un prix à payer : les données en mémoire disparaissent lorsque le système redémarre, elles ne sont pas écrites définitivement. Ainsi, Redis est le plus souvent utilisé pour des usages où il faut avant tout de la performance mais où la durabilité des données n'est pas le critère essentiel.

Sur le site officiel, quelques cas d'usages sont évoqués comme la détection de fraude, la gestion d'inventaire, les statistiques et classements, la messagerie entre des services ou la déduplication. « Redis Enterprise a été soumis à un banc d’essai de traitement de plus de 200 millions d’opérations de lecture/écriture par seconde avec des latences inférieures au millième de seconde, avec seulement une grappe de 40 nœuds sur AWS. Ceci fait de Redis Enterprise la base de données NoSQL la plus efficace en matière de ressources du marché » ajoute l'équipe.

Un cache à tout faire

De manière plus générale, on trouve Redis utilisé comme une sorte de cache, à la manière d'un memcached : mis en relation avec un système de fichiers ou une base de données classiques, il permet de placer facilement une donnée dans la mémoire à son premier accès et de la fournir par son biais ensuite, avec une très faible latence. 

Redis est aidé en cela par les Streams, mis en place dans la version 5.0 afin d'assurer ce genre de lien permanent. Mais surtout par son modèle clé/valeur et sa simplicité qui en font un outil facile à prendre en main et sont à la source d'un écosystème qui est devenu assez complet en 12 ans. De très nombreuses bibliothèques permettent d'utiliser Redis dans à peu près tous les langages, des modules, extensions et plugins sont présents pour des tas d'applications, tant pour des usages triviaux comme un blog Wordpress que dans le HPC.

Il est ainsi devenu central dans les architectures en micro-services et bénéficie à plein régime de la montée en puissance du cloud avec l'accès aisé à des instances équipées de larges quantités de mémoire. Mais il a aussi été complété par cet écosystème qui, tout en le gardant simple, en a fait un outil très puissant.

Il est actuellement le 6e SGBD le plus populaire selon le classement de DB-Engines Ranking, le 1er dans le domaine des modèles clé-valeur. Voyons donc ce qu'il permet dans la pratique, avec quelques exemples.

De simples requêtes TCP, bien documentées

Lorsque vous téléchargez Redis, vous installez en réalité un ensemble d'outils, dont un client et un serveur exploitant des sockets TCP sur le port 3739, qui se veut très simple dans ses échanges : vous lui envoyez des commandes sous la forme de texte ; il envoie, de manière très rapide, des réponses sous la forme de texte. 

Si vous le souhaitez, une couche de chiffrement peut être utilisée. Vous pouvez aisément monter des clusters et fournir un service haute-disponibilité : vous vous assurez ainsi à travers plusieurs instances et serveurs que vos données seront accessibles même si certains d'entre eux venaient à tomber en panne.

Les liens ci-dessus vous donnent un aperçu d'un autre élément qui fait la force de Redis : sa documentation est complète, détaillée et saura en général vous apporter les réponses que vous cherchez. C'est l'avantage d'un outil porté par une large communauté. Mais c'est aussi une entreprise commerciale qui fournit un service dédié aux entreprises, avec des fonctionnalités spécifiques, mais aussi une offre d'accès dans le cloud

Cela a d'ailleurs été à l'origine d'un fork, KeyDB. Il a été créé en réponse à certains choix techniques qui déplaisaient à ses initiateurs, comme le fait que Redis soit fondamentalement mono-thread, nécessitant l'utilisation de plusieurs instances pour profiter à plein régime des performances d'un même CPU. Mais aussi pour débrider certaines fonctionnalités réservées aux « pros » comme le très intéressant Redis on Flash (RoF).

Il permet en effet d'utiliser du stockage flash comme périphérique de stockage principal en complément de la mémoire. Une pratique qui a du sens lorsque vous avez besoin de plusieurs To de données, renforcée dans sa pertinence lorsque vous utilisez des SSD comme les Optane d'Intel ou ses modules DIMM PMem qui reposent sur la même technologie, car ils offrent une latence très réduite pour l'accès à de petites quantités données. 

Dans la suite de cet article, nous ne traiterons pas de KeyDB, mais vous trouverez sa documentation ici.

Installer et lancer redis, effectuer vos premières requêtes

Logiciel open source oblige, vous pouvez récupérer le code source de Redis et le compiler. De nombreuses distributions le proposent néanmoins dans leurs dépôts. Dans notre cas nous l'avons installé sous Debian : 

$ sudo apt update
$ sudo apt install redis

Vous pouvez aussi opter pour ce site qui donne accès à une interface en ligne permettant de tester Redis et ses commandes. Elles sont d'ailleurs toutes détaillées dans cette page de la documentation. Il est aussi possible d'opter pour un conteneur Docker ou une solution hébergée chez des fournisseurs de service cloud (CSP).

Une fois l'installation effectuée, vérifiez que tout fonctionne :

$ redis-cli ping

Cela lance un serveur local (répondant sur l'interface 127.0.0.1 uniquement), lui envoie la commande PING et reçoit normalement un PONG. En cas de réussite, vous pouvez commencer à envoyer de premières commandes :

$ redis-cli set ceci_est_une_clé ceci_est_une_valeur
OK

$ redis-cli get ceci_est_une_clé
"ceci_est_une_valeur"

$ redis-cli del ceci_est_une_clé
(integer) 1

$ redis-cli get ceci_est_une_clé
(nil)

Ici on définit une valeur que l'on affiche, avant de la supprimer. En cas de réussite de l'opération le résultat est un simple « 1 ». Si vous cherchez à accéder à cette clé par la suite, elle renvoie alors la valeur nil (la clé n'existe pas).

Notez que vous pouvez simplement lancer redis-cli et enchaîner les commandes les unes derrière les autres. Bien d'autres fonctionnalités sont proposées, comme par exemple l'incrément de valeurs, entières ou non :

> set compteur 0
OK

> incr compteur
(integer) 1

> incrby compteur 9
(integer) 10

> 5 incr compteur
(integer) 11
(integer) 12
(integer) 13
(integer) 14
(integer) 15

> incrbyfloat compteur 0.1
"15.1"

> quit

Les valeurs de base étant considérées comme des Strings, vous pouvez les concaténer, obtenir leur longueur, agir sur une partie seulement ou même combiner certaines actions (GETDEL, GETEX, SETEX). La liste est .

Invalider automatiquement une donnée

La commande SET peut également prendre des arguments pour préciser un délai d'expiration en secondes (EX) ou millisecondes (PX) ou sous la forme d'un temps UNIX (EXAT/PXAT). Sa documentation complète est ici.

Cette fonctionnalité peut être intéressante dans le cas d'un cache, pour déterminer si une donnée peut être obtenue via le serveur Redis depuis un temps plus ou moins long. Un nombre de visiteurs sur un site ne sera en effet pas géré de la même manière qu'une information « froide » comme la date de publication d'un élément.

Si une valeur n'est utile que pour un temps donné, vous pouvez donc la faire expirer : 

> set temporaire va_disparaitre EX 1337
OK

> ttl temporaire
(integer) 1303

> expire temporaire 42
(integer) 1

> ttl temporaire
(integer) 36

> get temporaire
(nil)

Empreintes, (Sorted) Sets et Listes

Pour des structures plus complètes on peut utiliser les Empreintes (hash) qui permettent pour chaque clé de stocker plusieurs champs, chacun associé à une valeur. Imaginons par exemple une base d'utilisateurs :

> hset utilisateurs:1 pseudo toto
(integer) 1

> hset utilisateurs:1 age 42 pays Laponie
(integer 2)

> hget utilisateurs:1 age
"42"

> hgetall utilisateurs:1
1) "pseudo"
2) "toto"
3) "age"
4) "42"
5) "pays"
6) "Laponie"

Nous avons opté pour le nom de clé « utilisateurs:1 » mais cela ne répond à aucune convention particulière, vous pourriez très bien opter pour « utilisateurs-1 » si vous le préférez par exemple. C'est une manière d'organiser les clés comme une autre. On note également que lorsque l'on récupère l'ensemble des données, elles ne sont pas présentées sous la forme d'une association champ/valeur mais les unes à la suite des autres.

Les Empreintes peuvent faire, comme les clés classiques, l'objet d'un incrément d'entier/flottant, on peut demander uniquement la liste des clés, à connaître le nombre d'éléments, etc. Là aussi la documentation détaille tout.

Si vous cherchez simplement à regrouper différentes informations, les Sets peuvent vous aider, prenant la forme d'une clé associée à des valeurs non ordonnées que l'on peut ajouter, retirer, extraire, comparer, déplacer, etc.

> sadd courses "jus de fruit" bacon cheddar
(integer) 3

> smembers courses
1) "cheddar"
2) "jus de fruit"
3) "bacon"

> spop courses 2
1) "jus de fruit"
2) "cheddar"

> smembers courses
1) "bacon"

> sadd courses:old "jus de fruit" bacon cheddar
(integer) 3

> sdiff courses:old courses
1) "jus de fruit"
2) "cheddar"

> smove courses:old courses cheddar
(integer) 1

> smembers courses
1) "cheddar"
2) "bacon"

Il en existe une version ordonnée (Sorted Sets) qui se distingue par un « Z » en début de commande. Chaque valeur est associée à un « score » qui permet de le « ranger » :

> zadd classement 5 Sébastien
(integer 1)

> zadd classement 1 David 150 Harou
(integer 2)

> zrange classement 0 3
1) "David"
2) "S\xc3\xa9bastien"
3) "Harou"

> zrange classement 0 3 withscores
1) "David"
2) "1"
3) "S\xc3\xa9bastien"
4) "5"
5) "Harou"
6) "150"

Outre cette possibilité de classement, ce type de données peut être intéressant par les nombreuses fonctions qu'il propose pour comparer différents Sorted Sets, faire des associations, des croisements, etc. 

Les Listes, elles, sont ordonnées par ordre d'insertion et ont une différence avec les Sets : il peut y avoir plusieurs itérations d'un même élément associé à une clé. On les pousse ou retire, mais on peut également le faire à différentes positions dans la liste, les déplacer, les gérer par leur index, en connaître la longueur, etc.

> lpush todo "Fouetter Séb" "Trouver de la DDR5" "Finir ce papier sur IPv6"
(integer) 3

> LLEN todo
(integer) 3

> lrange todo 0 3
1) "Finir ce papier sur IPv6"
2) "Trouver de la DDR5"
3) "Fouetter S\xc3\xa9b"

> lpush todo "Me faire un café"
(integer 4)

> rpush todo "Lire mes e-mails"
(integer 5)

> lrange todo 0 5
1) "Me faire un caf\xc3\xa9"
2) "Finir ce papier sur IPv6"
3) "Trouver de la DDR5"
4) "Fouetter S\xc3\xa9b"
5) "Lire mes e-mails"

> rpop todo
"Lire mes e-mails"

> lrange todo 0 4
1) "Me faire un caf\xc3\xa9"
2) "Finir ce papier sur IPv6"
3) "Trouver de la DDR5"
4) "Fouetter S\xc3\xa9b"
> ltrim todo 2 3
OK

> lrange todo 0 2
1) "Trouver de la DDR5"
2) "Fouetter S\xc3\xa9b"

> linsert todo after "Trouver de la DDR5" "Finir ce papier sur IPv6"
(integer 3)

> linsert todo after "Trouver de la DDR5" "Finir ce papier sur IPv6"
(integer 4)

> lrange todo 0 3
1) "Trouver de la DDR5"
2) "Finir ce papier sur IPv6"
3) "Finir ce papier sur IPv6"
4) "Fouetter S\xc3\xa9b"

PubSub : échangez des messages

Redis implémente une fonction de messagerie de type « Publish Subscribe » permettant donc de s'abonner à des canaux pour recevoir des informations par leur biais lorsque des messages sont publiés :

> subscribe canal:général canal:privé
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "canal:g\xc3\xa9n\xc3\xa9ral"
3) (integer) 1
1) "subscribe"
2) "canal:priv\xc3\xa9"
3) (integer) 2

Si un message est envoyé avec cette commande par exemple : 

$ redis-cli publish canal:général "Coucou"

Un nouveau message s'affichera :

1) "message"
2) "canal:g\xc3\xa9n\xc3\xa9ral"
3) "Coucou"

Vous pouvez aussi obtenir des informations sur les canaux :

$ redis-cli pubsub channels
1) "canal:priv\xc3\xa9"
2) "canal:g\xc3\xa9n\xc3\xa9ral"

$ redis-cli pubsub numsub canal:général
1) "canal:g\xc3\xa9n\xc3\xa9ral"
2) (integer) 1

Groupez vos commandes

Redis permet de créer une transaction de plusieurs commandes, exécutées en une fois. Il est aussi possible d'utiliser un fichier contenant une liste de commandes à exécuter, pour un import de données par exemple :

> multi
OK

> set compteur 0
QUEUD

> 5 incr compteur
QUEUED
QUEUED
QUEUED
QUEUED
QUEUED

> incrbyfloat compteur 0.1
QUEUED

> exec
exec
1) OK
2) (integer) 1
3) (integer) 2
4) (integer) 3
5) (integer) 4
6) (integer) 5
7) "5.1"

Notez que dans le cas d'un cluster où plusieurs instances peuvent accéder aux données, il est possible d'utiliser la commande WATCH pour indiquer qu'une transaction ne peut être exécutée que si certaines valeurs n'ont pas été modifiées. Si c'est le cas, la transaction complète est alors abandonnée.

Faisons désormais la même opération, mais depuis un fichier commands.txt contenant les commandes :

set compteur 0
5 incr compteur
incrbyfloat compteur 0.1

On peut l'exécuter sous la forme d'un pipe (plusieurs commandes groupées), avec ou sans timeout (en secondes). Cela renverra une erreur parce que la seconde ligne n'est pas reconnue, l'argument -r étant nécessaire avec redis-cli. Il faut donc plutôt placer cinq fois la commande ou exécuter un incrément de 5 directement. 

On obtient alors le résultat suivant :

$ cat commands.txt | redis-cli --pipe
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 7

$ cat commands.txt | redis-cli --pipe-timeout 10
OK
(integer) 1
(integer) 2
(integer) 3
(integer) 4
(integer) 5
"5.1"

Accès aux fichiers

Redis permet de stocker des données plus conséquentes comme des fichiers, par exemple une image. Il faut pour cela utiliser le paramètre -x qui indique que l'on va transmettre des données depuis stdin:

$ redis-cli -x set images:ciel < ciel.jpg

Pour effectuer l'étape inverse on utilisera le paramètre --raw qui permet d'obtenir une sortie brute :

$ redis-cli --raw get images:ciel > sortie.jpg

Cela peut aussi être utile pour lire le contenu d'un fichier texte stocké en mémoire via Redis par exemple :

$ echo "Hello, Word !" > hello.txt
$ redis-cli -x set texte < hello.txt
OK
$ redis-cli --raw get texte
"Hello, World !

Statistiques, sauvegarde et persistance

À l'inverse, on peut obtenir des informations sur les données stockées par le serveur et les sauvegarder :

$ redis-cli --stat
------- data ------ --------------------- load -------------------- - child -
keys mem clients blocked requests connections
2178179 12.19G 1 0 94 (+0) 39

Affichera en temps réel l'évolution de la quantité de mémoire utilisée par le serveur, le nombre de clients (bloqués ou non), de requêtes et de connexions. Vous pouvez d'ailleurs surveiller les commandes en temps réel :

$ redis-cli monitor

Ou demander des informations plus particulières :

$ redis-cli --scan
$ redis-cli --scan | head -10

Affichera l'ensemble des clés ou les 10 premières

$ redis-cli --bigkeys

Affichera des statistiques sur les plus gros éléments de la base.

À tout moment, vous pouvez effectuer une sauvegarde de l'ensemble des données dans un fichier au format .rdb :

$ redis-cli --rdb backup-$(date +%s).rdb

Nous utilisons ici la fonction date pour obtenir le timestamp du moment de la sauvegarde et l'utiliser dans le nom du fichier. Vous pouvez la faire localement, mais aussi en montant un dossier distant ou un espace S3 par exemple. Notez que Redis propose des fonctionnalités de persistance au-delà de RoF. Outre la sauvegarde dans une Redis Database (RDB) comme évoquée ci-dessus, il y a l'Append Only File (AOF) et les instantanés, détaillés ici.

Lancer un serveur Redis accessible depuis un client tiers

Jusqu'à maintenant, nous avons utilisé un serveur Redis local, mais l'objectif est en général d'y donner accès depuis une machine distante et pourquoi pas de cumuler plusieurs serveurs entre eux au sein d'un cluster.

La première chose à faire est de déterminer l'interface réseau (et donc l'adresse IP) et le port depuis lesquels vous voulez que votre serveur soit accessible. Vous pouvez le lancer avec ou sans mot de passe exigé. Cela peut passer par un fichier de configuration ou une simple ligne de commande. Et être automatisé au démarrage de Linux.

Commencez par vérifier qu'un serveur n'est pas déjà lancé :

$ redis-cli-shutdown

Si vous utilisez Systemd (comme c'est le cas sous Debian), un service Redis peut-être présent et actif :

$ systemctl status redis

Vous pouvez éditer son fichier de configuration : 

$ sudo nano /etc/redis/redis.conf

Il contient toute la documentation nécessaire pour utiliser ce fichier et ses différents paramètres. Désactivez ce service s'il n'est pas nécessaire ou que vous voulez procéder autrement :

$ systemctl stop redis
$ systemctl disable redis

Vous pouvez créer un fichier de configuration et restreindre son accès (puisqu'il contient un mot de passe) :

$ sudo touch /etc/redis-6380.conf
$ sudo chmod 700 /etc/redis-6380.conf
$ sudo nano /etc/redis-6380.conf

Placez-y les paramètres suivants (à adapter à vos besoins)

bind 192.168.0.42
port 6380
dir /var/lib/redis

protected-mode yes
requirepass votre_mot_de_passe

maxmemory 1gb
rdbcompression yes
rdbchecksum yes

loglevel notice
logfile /var/log/redis/redis-server.log

tcp-backlog 511
timeout 0
tcp-keepalive 300

Notez que le paramètre bind peut prendre plusieurs adresses IP si vous disposez de plusieurs interfaces.

Pour lancer le serveur il suffit ensuite de taper la commande suivante :

$ sudo redis-server /etc/redis/redis-6380.conf

Pour vous y connecter depuis une machine de votre réseau local, tapez :

$ redis-cli -h 192.168.0.42 -p 6380

Une fois connectez, identifiez-vous :

> auth votre_mot_de_passe
OK

Vous pouvez créer plusieurs serveurs au sein d'une même machine en utilisant différents ports et aller plus loin en créant des clusters d'instances, un script étant prévu à cet effet. Mais aussi à travers la réplication qui permet d'avoir une instance maître dont les données sont copiées sur d'autres, esclaves. 

Performances et latence

Si vous voulez connaître les performances de votre serveur Redis, local ou distant, vous avez plusieurs moyens à votre disposition. Tout d'abord pour mesurer la latence à différents niveaux : 

$ redis-cli --latency
$ redis-cli --latency --raw

Dans le premier cas, vous obtiendrez une mesure de latence en continu, avec un minimum, un maximum et une moyenne. La seconde commande effectue le test 1 seconde et affiche un résultat. --csv est aussi utilisable.

$ redis-cli --latency-history
$ redis-cli --latency-history -i 1

Cette fois on effectue un relevé continu, mais avec un relevé régulier. Toutes les 15 secondes par défaut mais on peut modifier cette valeur avec le paramètre -i.

$ redis-cli --latency-dist -i 5

Affiche le résultat sous la forme d'un spectre coloré, toutes les 5 secondes (1 seconde par défaut).

$ redis-cli --intrinsic-latency 5

Cette commande, à exécuter uniquement depuis le serveur Redis, puisqu'elle permet d'isoler la latence qui est propre au système et son scheduleur ou à l'hyperviseur en cas de virtualisation. 

Un outil de mesure de performances permet de connaître le nombre de requêtes pouvant être encaissées par le système avec de nombreux paramètres pouvant être modifiés : types de requêtes, nombre, taille, etc.

$ redis-benchmark -t get,set -n 1000000 -q

Pour utiliser les pipes avec jusqu'à 32 commandes groupées, des paquets de 100 ko et 500 connexions :

$ redis-benchmark -t get,set -n 1000000 -q -P 32 -d 100000 -c 500

Des interfaces graphiques pour gérer vos serveurs Redis

Notez enfin qu'outre le client redis-cli, bien d'autres outils permettent de gérer un serveur Redis, notamment de manière graphique. C'est par exemple le cas de Redis Insight, mais aussi de nombreux outils open source. Des services en ligne comme redsmin proposent un service similaire, avec un modèle freemium.

Redsmin

Écrit par David Legrand

Tiens, en parlant de ça :

Sommaire de l'article

Introduction

Utiliser la mémoire pour des millions d'opérations par seconde

Un cache à tout faire

De simples requêtes TCP, bien documentées

Installer et lancer redis, effectuer vos premières requêtes

Invalider automatiquement une donnée

Empreintes, (Sorted) Sets et Listes

PubSub : échangez des messages

Groupez vos commandes

Accès aux fichiers

Statistiques, sauvegarde et persistance

Lancer un serveur Redis accessible depuis un client tiers

Performances et latence

Des interfaces graphiques pour gérer vos serveurs Redis

next n'a pas de brief le week-end

Le Brief ne travaille pas le week-end.
C'est dur, mais c'est comme ça.
Allez donc dans une forêt lointaine,
Éloignez-vous de ce clavier pour une fois !

Fermer

Commentaires (24)


Vous donnez toutes les briques pour monter une startup en 2021. ;-)


On y travaille :D


Super article, merci ! Ca doit prendre du temps de se plonger la-dedans.


Si peu :transpi: et encore j’use de certaines facilités pour réduire la voilure sur des sujets qu’on creusera en second temps ou qui prendraient trop de temps/place à détailler dans un article comme celui-ci (comme tout ce qui est cluster/replica par exemple)


David_L

Si peu :transpi: et encore j’use de certaines facilités pour réduire la voilure sur des sujets qu’on creusera en second temps ou qui prendraient trop de temps/place à détailler dans un article comme celui-ci (comme tout ce qui est cluster/replica par exemple)


vous utilisez redis pour nextinpact ? je me demande pourquoi ce sujet en particulier ;)


Le plus compliqué avec redis, qui ne gère pas la notion de connexion, c’est encore de gérer l’absence de redis au moment où tu en as besoin…



cognitys a dit:


vous utilisez redis pour nextinpact ? je me demande pourquoi ce sujet en particulier ;)




De mémoire oui, mais ce n’est pas moi qui développe Next INpact :transpi: Pour le choix du sujet, c’est notamment parce que c’est lié à des choses qu’on a en cours, mais bon, j’essaie de présenter régulièrement des sujets de ce genre pour sortir un peu de ce que l’on trouve partout ailleurs.



Surtout que ce sont des sujets pour lesquels ont trouve pas mal de petites ressources éparpillées, mais jamais de présentation complète sans être découpée en 200 sous-vidéos YouTube pour faire plein de vues pendant des années à peu de frais :D




Krystanos a dit:


Le plus compliqué avec redis, qui ne gère pas la notion de connexion, c’est encore de gérer l’absence de redis au moment où tu en as besoin…




C’est pour ça qu’il y a les fonctionnalités de HA/Cluster non ? Parce que c’est un peu pareil avec un serveur web sinon, s’il ne répond pas, ça pose quelques problèmes pour l’accès :D


ok, effectivement présentation intéressante :yes:


Dans certains contextes (Drupal notamment), le clustering est … compliqué à gérer :D
Merci en tout cas pour cet article, je ne connaissais pas la fonctionnalité du pubSub par exemple !! :chinois:


l352

Dans certains contextes (Drupal notamment), le clustering est … compliqué à gérer :D
Merci en tout cas pour cet article, je ne connaissais pas la fonctionnalité du pubSub par exemple !! :chinois:


Là c’est la faute à Drupal ;), j’avais eu ce soucis y’a pas longtemps. Redis c’est vraiment une techno super bien faite et stable.


Certes, mais c’est pas parce que c’est censé fonctionner que
1/ ça fonctionnera
2/ OSEF de ce qui se produit quand ça arrive :)



Classiquement dans les SGBD tu as un système de connexion qui te prévient quand la connexion est coupée.
Ici, rien ne l’indique. Tu fais ta requête et ça passe ou ça casse.
Il faut donc juste penser à traiter ce cas, et réagir proprement…



Typiquement, quand tu as un petit malin qui joue avec les security groups et du terraform tu n’es pas loin d’avoir des soucis :)


Redis est utiliser par le forum NXI pour gérer la recherche.


J’ai déployé du Redis en 2014 pour un client dans l’audiovisuel (partie VOD avec les box), en mode 1 maître et 3 esclave : on écrit sur le maître et on lit sur les esclaves. Le temps d’arrivée des données sur les esclaves se compte en millisecondes (quelques-unes voire à peine une).
Il y avait un mécanisme d’élection d’un nouveau maître parmi les esclaves, si le maître tombait.



Pour l’époque c’était un gros cluster car chaque VM avait 64 G de RAM dont 40 ou 60 consacré à la base Redis ; la sauvegarde RDB régulière prenait un peu de temps, même sur une baie performante (EMC avec FibreChannel).



A l’époque ça faisait sourire, la plus belle référence en terme de performances pour Redis, c’était le site YouPorn, qui arrivait à 300 000 requêtes par seconde (énorme pour l’époque).




Krystanos a dit:


Le plus compliqué avec redis, qui ne gère pas la notion de connexion, c’est encore de gérer l’absence de redis au moment où tu en as besoin…




Comment ça, Redis ne gère pas le notion de connexion ?


Non, ils utilisent un protocole (RESP) qui fonctionne peu ou prou comme HTTP sur le principe. Une requête, une connexion.
Quand tu créé un client, il ne se connecte pas, il le fait juste à l’envoi des requêtes.
Du coup tu dois recréer la notion de connexion si tu en as besoin…


Intéressant !
Y’a plus qu’à se trouver un beau sujet pour aller au delà.



Krystanos a dit:


Classiquement dans les SGBD tu as un système de connexion qui te prévient quand la connexion est coupée.




Si le serveur est down t’as un timeout à la connexion ou requête, je ne vois pas la différence avec n’importe quel SGBD


La différence est dans les temps de réponse. Dans un cas, tu peux dire immédiatement qu’il y a un problème. Dans l’autre, il faut attendre le timeout, qui peut atteindre plusieurs secondes voir dizaine de secondes.



Dans un cas, tu peux détecter le souci sans faire de requête explicite et prévenir l’utilisateur en amont. Dans l’autre, il faut envoyer obligatoirement la requête, et tu vois le problème si tu n’obtiens pas de réponse.


et pourtant. la gestion de la déconnexion est centralisée pour le SGBD, et tu le sais avant d’envoyer des requêtes.
là, ce n’est pas le cas. il faut donc faire du code pour traiter ce cas proprement…


Krystanos

et pourtant. la gestion de la déconnexion est centralisée pour le SGBD, et tu le sais avant d’envoyer des requêtes.
là, ce n’est pas le cas. il faut donc faire du code pour traiter ce cas proprement…


Tu pourrais nous définir ce que tu entends par “déconnexion” ? Parce que le fait d’avoir un problème de connexion couvre pleins de possibilités qui sont très loin d’être trivial à détecter rapidement. Tu peux avoir des problèmes momentané où la connexion est bien établie et fonctionnelle mais la bande passante est tellement basse qu’il vaut mieux abandonner et considérer que la connexion est down. Ton outil va probablement dire que c’est up et tu vas attendre gentiment indéfiniment que ta requête arrive et encore attendre indéfiniment que sa réponse te revienne. Ou bien il va te dire que c’est down, mais quelle est sa limite de bande passante acceptable ? C’est très dépendant de ton besoin spécifique ça, et tu pourrais à l’inverse avoir ton tool qui te dit que c’est down alors que non, c’est juste lent. Comment il te détecte le fait que ton SGBD crash ou que la machine qui le host se coupe avant de t’avoir répondu ? Il te l’a pas dit avant d’ouvrir la connexion.



Tu pourrais nous expliquer comment tu détectes le “manque de connexion” sans timeout et avant même d’essayer d’envoyer la moindre requête ? Je pense que l’ensemble des dev rêvent d’apprendre ta solution miracle, surtout si ça détecte aussi magiquement que le souci momentané qui t’embête quelque part dans le réseau est résolu et qu’on peut recommencer, toujours sans avoir eu à envoyer quoique ce soit :O



Au fond, tu dois envoyer ta requête pour savoir si le service est down et tu as soit des erreurs franches (mauvaise config réseau interne, status 500, …) soit c’est ton timeout qui te dit que c’est down.


Bon, c’est pour critiquer un peu :) , mais j’ai toujours du mal avec la comparaisons avec memcached.



L’un est un pur cache alors que l’autre est une base de données en mémoire.
Alors certes ça ce marche un peu sur les pied, mais cette confusion que l’on retrouve chez presque tous les dev fait des dégâts énormes avec des archis où l’on retrouve des memcached utilisés comme base de données et des redis sans gestion d’expiration et de rotation de clés comme cache.



D’ailleurs nous utilisons les deux dans notre produit (aka la où je boss) sous des charges disons plus haute que la moyenne, c’est pas pour le plaisir de maintenir deux systèmes mais bien parce qu’ils ne sont pas deux produits concurrents mais complémentaires.


D’où le “à la manière de” dans le passage ou je parle de l’utilisation spécifique comme cache. Les deux sont parfois utilisés de la même manière c’est un fait, même si on est d’accord que sur le fond ils ne sont pas similaires. Après memcached s’utilise de manière proche pour l’usage de base (get, set, add, etc.) ce qui participe sans doute à la confusion



Krystanos a dit:


Non, ils utilisent un protocole (RESP) qui fonctionne peu ou prou comme HTTP sur le principe. Une requête, une connexion. Quand tu créé un client, il ne se connecte pas, il le fait juste à l’envoi des requêtes. Du coup tu dois recréer la notion de connexion si tu en as besoin…




Heu non, on a une connexion TCP persistante dès qu’on utilise Redis sérieusement depuis une application. Si on devait se connecter à chaque fois, on n’aurait pas des capacités à plusieurs dizaines (voire centaines) de milliers de transactions par seconde.



Krystanos a dit:


Classiquement dans les SGBD tu as un système de connexion qui te prévient quand la connexion est coupée.




Quel est ce “système de connexion” (à part TCP) ?




fofo9012 a dit:


Si le serveur est down t’as un timeout à la connexion ou requête, je ne vois pas la différence avec n’importe quel SGBD




Idem.


Jolie présentation :)



Je dispense des formations Redis (en plus de l’utiliser massivement dans mes projets, j’ai commencé à Skyblog ça fait un bail), et c’est vraiment le moteur de cache / “noSQL” à connaître :)