Maison > Article > base de données > Introduction au mécanisme d'invalidation du cache Redis
L'histoire de l'échec du cache Redis commence avec la commande EXPIRE. EXPIRE permet aux utilisateurs de spécifier un délai d'attente pour une clé. Lorsque ce délai est dépassé, la valeur correspondant à la clé sera effacée. Code source Redis Le site Web ci-dessus examine les problèmes liés à l'échec du cache Redis du point de vue d'un concepteur Redis.
Mécanisme d'invalidation du cache Redis
Le mécanisme d'invalidation du cache Redis est conçu pour traiter un scénario très courant dans les applications de mise en cache, parlons d'un scénario :
Afin de réduire la pression sur la base de données back-end, nous avons volontiers utilisé le service Redis pour charger les données qui ne changent pas très fréquemment à partir du chargement de la base de données et les mettre dans le cache. Par conséquent, dans un certain temps, nous pouvons obtenir des données directement à partir du cache, mais nous espérons qu'après un certain temps, nous chargerons à nouveau les données actuelles de la base de données dans le cache.
Une question a été soulevée. Comment résoudre ce problème ? Eh bien, nous connaissons très bien les outils linguistiques disponibles et nous croyons fermement que nous pouvons écrire rapidement une telle logique : nous enregistrons la dernière fois que nous avons chargé des données à partir de la base de données, puis déterminons si le délai a expiré à chaque fois. nous répondons au service. Voulez-vous recharger depuis la base de données... ? Bien sûr, cette méthode est également possible. Cependant, lorsque nous avons vérifié le document de commande Redis, nous avons constaté que nous avions fait quelque chose que nous n'avions pas besoin de faire. Redis lui-même fournit ce mécanisme. Nous pouvons facilement le faire avec l'aide de. Commande EXPIRE :
EXPIRE key 30
La commande ci-dessus définit un délai d'expiration de 30 secondes pour la clé. Passé ce délai, nous ne devrions pas pouvoir accéder à cette valeur. Jusqu'à présent, nous avons à peu près compris ce qu'est le mécanisme d'invalidation du cache. et quel est le mécanisme d'invalidation du cache. Certains scénarios d'application, continuons à approfondir ce problème. Comment le mécanisme d'invalidation du cache Redis est-il implémenté ?
Mécanisme d'invalidation retardée
Le mécanisme d'invalidation retardée signifie que lorsque le client demande à utiliser une certaine clé, Redis vérifiera la période de validité de la clé demandée par le client. Si le traitement correspondant est effectué uniquement après l'expiration de la clé, le mécanisme de défaillance retardée est également appelé mécanisme de défaillance passive. Jetons un coup d'œil à la pile d'exécution côté serveur pour le traitement des requêtes get sous le composant t_string :
getCommand -> getGenericCommand -> lookupKeyReadOrReply -> lookupKeyRead -> expireIfNeeded
Le point clé est expireIfNeed. Avant que Redis n'obtienne la clé, il déterminera si la valeur associée à la clé est. invalid. Insérez-le ici d'abord. Un petit épisode, regardons à quoi ressemble l'endroit réel où stocker les valeurs dans Redis :
typedef struct redisDb { dict *dict; /* The keyspace for this DB */ dict *expires; /* Timeout of keys with a timeout set */ dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */ dict *ready_keys; /* Blocked keys that received a PUSH */ dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */ int id; long long avg_ttl; /* Average TTL, just for stats */} redisDb;
Ce qui précède est une structure définie dans Redis dict est un dictionnaire. implémenté par Redis, c'est-à-dire que chaque base de données comprendra les cinq champs ci-dessus. Nous ne nous soucions ici que de deux dictionnaires, l'un est dict et l'autre expire :
dict est utilisé pour stocker des données normales. si nous exécutons la clé set "hahaha", ces données sont stockées dans dict.
expires est utilisé pour stocker les clés associées au délai d'expiration. Par exemple, si nous exécutons la clé d'expiration 1 sur la base de ce qui précède, un enregistrement sera ajouté à expire à ce moment.
En regardant le processus d'expirationIfNeeded, c'est à peu près le suivant :
Trouver le délai d'expiration de la clé d'expiration. Si elle n'existe pas, cela signifie que la clé correspondante n'existe pas. avoir un délai d'expiration défini et revient directement.
S'il s'agit d'une machine esclave, elle sera renvoyée directement, car afin d'assurer la cohérence des données et une mise en œuvre simple, Redis donne l'initiative d'invalidation du cache à la machine Maître, et la machine esclave n'a pas le autorité pour invalider la clé.
S'il s'agit actuellement de la machine maître et que la clé expire, le maître fera deux choses importantes : 1) Écrivez la commande de suppression dans le fichier AOF. 2) Informez l'esclave que la clé actuelle n'est pas valide et peut être supprimée.
Master supprime la valeur de la clé du dictionnaire local.
Mécanisme d'invalidation actif
Le mécanisme d'invalidation actif est également appelé mécanisme d'invalidation actif, c'est-à-dire que le serveur vérifie régulièrement le cache invalide et effectue les opérations correspondantes en cas d'échec .
Nous savons tous que Redis est monothread et piloté par les événements. Il existe un EventLoop dans Redis. EventLoop est responsable du traitement de deux types d'événements :
Un type est celui des événements IO. type d'événement Il est séparé du multiplexeur sous-jacent.
Le premier type est celui des événements planifiés, qui sont principalement utilisés pour l'exécution planifiée d'une certaine tâche.
Il semble que la fonction EventLoop de Redis soit à peu près similaire à la fonction EventLoop de Netty et JavaScript. D'une part, elle gère les événements d'E/S réseau, et d'autre part, elle peut également en faire. petites tâches.
Pourquoi parlons-nous du modèle monothread de Redis Parce que la logique du mécanisme de défaillance actif de Redis est traitée comme une tâche planifiée et exécutée par le thread principal :
if(aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) { redisPanic("Can't create the serverCron time event."); exit(1); }
serverCron est ce timing. Le pointeur de fonction de la tâche, adCreateTimeEvent enregistre la tâche serverCron dans EventLoop et définit le temps d'exécution initial à 1 milliseconde plus tard. Ensuite, tout ce que nous voulons savoir se trouve dans serverCron. serverCron fait beaucoup de choses. Nous ne nous soucions que des parties liées à cet article, c'est-à-dire comment l'invalidation du cache est implémentée. Je pense que la pile d'appels est relativement intuitive en fonction de ce que fait le code :
aeProcessEvents ->processTimeEvents ->serverCron -> databasesCron -> activeExpireCycle -> activeExpireCycleTryExpire
EventLoop. Grâce au traitement des tâches planifiées, l'exécution de la logique serverCron est déclenchée, et enfin la logique du traitement de l'expiration des clés est exécutée. Il convient de mentionner que la logique activeExpireCycle ne peut être effectuée que par le maître.
Pour plus de connaissances sur Redis, veuillez prêter attention à la colonne Tutoriel d'introduction à Redis.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!