Gestion de base de données : focus sur Redis, système Open Source

Temps de lecture : 11 minutes

Cet article fait suite au talk « intelligent session storage using Redis » donné lors du AWS Summit le 2 avril dernier. Redis est un système de gestion de base de données clef-valeur hautes performances qui stocke les informations en mémoire pour un accès rapide. Il peut être utilisé pour gérer les sessions de vos utilisateurs ou le cache de votre site par exemple. Nous verrons dans un premier temps à quels cas d’usage Redis peut répondre, quels sont ses coûts et ses performances, avant d’aborder plus en profondeur ses points forts et ses limites d’usage.

Avant de présenter plus avant Redis, il est important de préciser la notion de « Session Store ». Une « Session Store » ou stockage de session permet de stocker des données utilisateurs, telles que mot de passe, nom, pseudonyme… Ce stockage se situe sur le navigateur dans un cookie. Ce cookie contient aussi un token qui va lier le côté client aux données qui sont côté serveur.

Session Store

La session store peut être définie suivant quatre points:

  • Des données liées à un utilisateur pour un service donné. Un utilisateur n’est pas forcément un individu connecté à un compte du service mais peut être un simple visiteur.
  • La plupart du temps cette connexion entre le serveur et le client persiste à l’aide d’un token.  Le cookie est donné par le serveur et celui-ci vient se stocker dans le navigateur. Quand le client se connecte au serveur celui-ci lui retourne le cookie ce qui permet au serveur de lier le token aux données de l’utilisateur.
  • Les données liées à ce token sont souvent des données très utilisées par l’utilisateur (carte de crédit, mot de passe …).
  • Ces données sont éphémères et pour la plupart dupliquées.

Traditionnellement les stockages de sessions possédaient comme données le nom de l’utilisateur,  son pseudonyme, les préférences ainsi que certaines données utiles. Redis vient offrir une nouvelle notion au modèle traditionnel qui est le comportement de l’utilisateur.

Le comportement peut être analysé en fonction du temps passé sur une page, les interactions avec les contenus, le parcours de ses visites … Mieux connaître le comportement de l’utilisateur, c’est aussi mieux pouvoir le cibler, pouvoir proposer des publicités plus adaptées, des promotions ou des recommandations.

L’exemple d’un site e-commerce

Pour comprendre l’intérêt de Redis, prenons l’exemple de l’évolution d’un site d’e-commerce. Ce site de e-commerce possède une architecture traditionnelle sur le Cloud avec un serveur pour l’application web et une base de données possédant toutes les données ainsi que celle des utilisateurs.

Le site gagne en notoriété et les utilisateurs sont de plus en plus nombreux. Dû à cette augmentation du flux de connexions le serveur sollicite énormément la base de données. Cela se traduit par une mauvaise expérience utilisateur : navigation ralentie, voire à l’extrême le site qui ne répond plus.

Afin de soulager la base de données, les données liées aux tokens des utilisateurs vont être migrées sur un espace de stockage alloué au serveur. L’application se stabilise et tout va bien.

Suite à une campagne de publicité, le nombre de connexions explose à nouveau ! L’équipe IT va alors ajouter de nouveaux serveurs afin que tous les utilisateurs puissent accéder au site sans avoir de problème de latence. Afin de répartir ce nouveau trafic sur les serveurs, l’équipe IT met en place un load balancer.

Se pose alors un nouveau problème. Michel, un utilisateur se connecte au serveur 1. Ses données utilisateur vont alors être stockées auprès de ce serveur. Quand Michel se reconnecte une heure plus tard, c’est auprès du serveur 3. Celui-ci n’ayant pas accès aux données du serveur 1, de nouvelles données utilisateurs sont stockées sur le serveur 3. On pourrait être tenté de mettre en place un EFS, mais celui-ci ne supportera pas un flux conséquent d’utilisateurs.

Une solution serait d’ajouter la notion de sticky-sessions au Load Balancer. Une sticky-session vient se placer sur le Load Balancer afin de renvoyer les utilisateurs en fonction de leurs cookies ou de leurs IP vers le serveur qui possède leurs données. C’est une bonne solution, mais qui présente le risque de rendre plus difficile au Load Balancer de garder les serveurs au même niveau d’utilisation. Si un serveur vient à être surchargé alors le Load balancer renverra certains utilisateurs sur un autre serveur.

D’où l’utilité de Redis qui propose une base de données « In Memory » avec une latence de réponse de 0,0005 secondes (c’est la durée que Redis considère comme correcte). Ainsi vos serveurs ne surchargeront pas la base de données relationnelle en place et les serveurs n’ont pas besoin d’espace de stockage.

De l’importance de la latence

Pourquoi cette obsession sur la latence? Un utilisateur va avoir l’impression qu’un site « rame » si son temps de réponse est supérieure à 100 ms. À partir du moment ou un site dépasse ce délai, le nombre de connexion diminue. Il y a dix ans déjà, Amazon expliquait que 100 ms en trop leur faisait perdre 1% des ventes.

Tabb Group, groupe international de conseil et de recherche sur les marchés financiers, a estimé que pour un site marchand d’électronique, 5 millisecondes de réponse de latence en plus que ses concurrents peuvent engendrer une perte de 1% de ses utilisateurs. Ce qui revient à 4 millions de dollars par milliseconde (voir cet article pour plus de détails).

La base de données « In Memory »

Redis, outil open source, offre une base de données « In Memory » (les données sont stockées dans la mémoire vive) qui fonctionne sous forme de clé/valeur (No SQL). Redis se distingue particulièrement sur trois points, qui sont la performance, la simplicité de la structure de la donnée et la possibilité d’ajouter des structures de modèles.

Performance de Redis

Un graphique valant toujours mieux qu’un long discours, je vous laisse voir ci-dessous la comparaison de progiciels de base de données No SQL. Ce graphique a été délivré par Avalon Consulting. Vous pouvez trouver plus d’informations sur ce lien.

On voit bien que Redis se démarque des autres bases de données No SQL. Ce scénario est représentatif pour les cas d’usages du type analyse temps réel, transaction de gros volumes de données et ingestion de données type IOT.

Ce graphique représente la différence de coût sur 1 million d’écritures par seconde :

Les coûts annuels ci-dessus représentent les coûts de la mémoire ainsi que les instances de calculs nécessaires pour faire fonctionner ces outils. Dans le contexte les bases de données sont confrontées à 1 million d’écriture par seconde. Ces chiffres sont à prendre avec précautions car nous ne connaissons pas sur quelles persistances des données ont été effectués ces calculs.

Simplicité de la structure de la donnée

Les structures de données peuvent être diverses et variées, voici les plus communes :

  • Les chaînes de caractères: String
  • Les listes: Lists
  • Les listes à valeur unique: Set
  • Les dictionnaires type key/value: Sorted Set
  • Les structures de données probabiliste: HyperLogLog (Nous y reviendrons un peu plus tard)
  • Les streams de données: Streams
  • Plus d’informations ici
     

Elasticité des modèles de données

Avec Redis vous avez la possibilité d’ajouter des librairies afin d’augmenter le nombre de modèles de données qui pourraient être utilisés.

Redis étant un outil très scalable avec de très bonnes performances, vous pouvez créer vos propres modules, ils doivent être développés du C, C++, Rust ou du Zig. Ce qui fait de Redis une base de données multimodèles.

Nous avons pu voir quels étaient les axes principaux de Redis maintenant nous allons nous plonger dans des concepts qui font que Redis est un outil aussi performant.

Bloom Filters

Admettons-vous avez une grande librairie de livres et que vous souhaitez savoir si vous avez déjà « Candide » dans votre base de données. En utilisant Bloom Filter vous allez pouvoir faire un début de recherche dans votre base de données qui ne sera pas coûteuse. Vous obtiendrez une réponse telle que « peut-être » ou une réponse négative. Si la réponse est négative vous n’avez pas besoin de continuer la recherche, si la réponse est « peut-être » alors la requête ira plus en profondeur.

Bloom filters est une structure de donnée lié aux probabilités. Celui-ci offre la possibilité de dire si un objet n’est pas dans un set. Il peut aussi vous permettre de savoir si un objet est peut-être dans le Set.

Le Bloom Filters ne peut pas renvoyer de faux négatifs (c’est-à-dire qu’il ne se trompera jamais en disant que la ressource n’est pas accessible) mais peut renvoyer un faux positif (il se peut qu’il vous dise qu’une donnée est présente alors que non).

HyperLogLogs

Un HyperLogLog est aussi structure de données probabiliste. Ce type de données permet de compter des données uniques telles qu’une adresse IP, une adresse mail ou des termes. Compter des valeurs avec une précision demande une mémoire élevée (proportionnel au nombre de données); étant donné que la mémoire est une ressource limitée, si l’on travaille avec des gros sets de valeurs cela peut vite devenir problématique.

L’hyperloglog va diminuer la précision au grès de la mémoire. Il va rendre possible d’estimer des ensembles possédants plus que 10^9 valeurs avec une possibilité d’erreur de 2% et n’utilisant que 1.5 kilobytes de mémoire.

Pour un HyperLogLog de Redis celui-ci va consommer 12 kb (cela n’inclue pas les bytes nécessaires pour stocker la clé) de mémoire et faire des approximations de 0.81%.

Bit counting (time series)

Bit counting est un concept simple, c’est une liste de bits. Prenons un exemple, vous cherchez à savoir si un utilisateur est un utilisateur régulier de votre application. Vous allez créer un bit counting et chaque jour sera représenté par un byte. Disons que le premier jour celui-ci ne se connecte pas alors le premier byte sera 0, si celui-ci vient le lendemain alors le deuxième byte sera 1. Vous pouvez mettre en place un système afin de savoir si votre utilisateur est actif ou non en fonction du nombre de jours d’inactivité consécutifs.

Ce n’est qu’un exemple de cas d’usage mais vous pouvez ainsi imaginer d’autres cas d’usages. Vous pouvez en faire une liste d’octet et compter le nombre de connexions à l’heure. C’est une structure qui prend peu de place et peut servir pour différents cas d’usage.

Bien maitrisés, ces outils vous aideront à rendre ces sessions de stockage « intelligentes ». Vous pourrez analyser les habitudes de vos utilisateurs sans utiliser des espaces de mémoire trop importante.

La persistance des données

Quelle stratégie de persistance ? Vos données survivront tant que les serveurs fonctionnent, donc si elles ne sont pas critiques, tout va bien. Dans le cas contraire, si vous cherchez à ajouter de la persistance à vos données, alors vous avez deux possibilités :

La persistance type RDB

Redis produit des snapshots qui permettent des retours sur le temps sur le dataset. Vous pouvez configurer ces snapshots pour qu’ils se produisent par exemple toutes les 2 minutes et si il y a au moins 100 écritures dessus. Ce fichier est enregistré en fichier .rdb.

La durabilité des snapshots peut être configurée et les snapshots sont sauvegardés toutes les 15 minutes. Ce qui laisse un laps de temps de 15 minutes durant lequel les données peuvent être perdues en cas de crash d’instance Redis. RDB peut consommer de la latence si le dataset est volumineux, et peut du coup ne pas répondre au client entre la milliseconde jusqu’à 1 seconde (gros dataset et CPU pas très performant). Ces fichiers peuvent être stockés et chiffrés dans S3.

La persistance type AOF

C’est un mode bien plus consistant qui permet de synchroniser de manière plus régulière la donnée. L’AOF par défaut synchronise la donnée à la seconde. Il faut savoir que ce type de persistance est en général plus lente que celle de la RDB et doit être utilisé avec parcimonie. Le temps de la synchronisation peut être modifié et rendre l’AOF aussi rapide que la RDB lors de flux important. Le fichier que génère l’AOF est incorruptible car c’est un fichier qui n’autorise que l’écriture et la lecture. Le seul problème que l’on peut avoir c’est en cas de surtension, et du coup avoir une écriture non terminée dans le fichier. Les fichiers générés par l’AOF sont plus lourds que par le type RDB.

La bonne pratique consiste à varier le type de persistance, en fonction de la valeur de vos données. Si ces données n’ont d’importance que le temps de la session, n’utilisez pas de persistance dessus, si vous pouvez perdre quelques minutes sur vos données utilisez RDB, sinon employez de l’AOF.

Apache Ignite

Je vous conseille aussi de comparer Redis avec Apache Ignite qui peut être bon compromis.

Apache Ignite est une alternative à Redis utile si vous utilisez beaucoup de calculs. Si vous avez des besoins avancés tels que du machine learning, de l’analyse en streaming et deep learning, Apache Ignite est une option. Il existe d’autres features dans Redis pour ce type de cas d’usage, mais on sort du cadre open source de Redis.

Dans le cas où Redis à plus d’option qu’il ne vous en faut, je vous conseille de vous renseigner sur Memcached. Memcached est un service de cache de mémoire distribué et hautes performances, celui-ci a été conçu dans une optique de simplicité et de scalabilité horizontale.

Pour aller plus loin :

Commentaires :

A lire également sur le sujet :