Maison > Article > base de données > Explication du principe de la stratégie de suppression de clé expirée de Redis
Apprentissage recommandé : Tutoriel vidéo Redis
Le serveur Redis utilise en fait deux stratégies : la suppression paresseuse et la suppression régulière : en utilisant ces deux stratégies de suppression ensemble, le serveur peut utiliser de manière raisonnable le temps CPU et trouver un équilibre entre évitant le gaspillage d'espace mémoire.
La stratégie de suppression paresseuse est la plus conviviale pour le temps CPU : le programme ne vérifiera l'expiration de la clé que lorsque la clé sera retirée, ce qui peut garantir que l'opération de suppression des clés expirées ne sera effectuée que lorsqu'elle sera retirée. doit être effectuée et que la cible de suppression est limitée aux clés actuellement traitées, cette stratégie ne perdra pas de temps CPU à supprimer d'autres clés expirées non pertinentes.
L'inconvénient de la stratégie de suppression paresseuse est qu'elle est la moins conviviale pour la mémoire : si une clé a expiré et que la clé est toujours conservée dans la base de données, alors tant que la clé expirée n'est pas supprimée, la mémoire qu'elle occupe sera ne sera pas supprimé sera libéré.
Lorsque vous utilisez la stratégie de suppression paresseuse, s'il y a beaucoup de clés expirées dans la base de données et que ces clés expirées ne sont pas accessibles, elles risquent de ne jamais être supprimées (à moins que l'utilisateur n'exécute manuellement FLUSHDB), nous même cette situation peut être considérée comme une fuite de mémoire - les données inutiles occupent beaucoup de mémoire, mais le serveur ne les libère pas tout seul. Ce n'est certainement pas le cas pour un serveur Redis dont l'état de fonctionnement dépend fortement de la mémoire. bonnes nouvelles.
Par exemple, pour certaines données temporelles, telles que les journaux, après un certain temps, l'accès à celles-ci sera considérablement réduit, voire même plus accessible si ces données expirées sont retardées en grande quantité, dans la base de données. , l'utilisateur pense que le serveur les a automatiquement supprimées, mais en fait ces clés existent toujours, et la mémoire occupée par les clés n'a pas été libérée, les conséquences doivent donc être très graves.
D'après la discussion ci-dessus sur la suppression paresseuse, cette méthode de suppression présente des défauts évidents lorsqu'elle est utilisée seule :
La suppression paresseuse gaspille trop de mémoire et risque de fuites de mémoire. La stratégie de suppression périodique est une intégration et un compromis des deux premières stratégies :
La stratégie de suppression périodique effectue la suppression des clés expirées de temps en temps, et réduit l'impact des opérations de suppression sur le temps CPU en limitant la durée et la fréquence des opérations. opérations de suppression. De plus, en supprimant régulièrement les clés expirées, la stratégie de suppression régulière réduit efficacement le gaspillage de mémoire provoqué par les clés expirées. La difficulté de la stratégie de suppression périodique est de déterminer la durée et la fréquence de l'opération de suppression :
Si l'opération de suppression est exécutée trop fréquemment, ou que le temps d'exécution est trop long, la stratégie de suppression périodique dégénérera en une stratégie de suppression programmée, ce qui consommera trop de temps CPU. Beaucoup de temps est consacré à la suppression des clés expirées.
Si l'opération de suppression est exécutée trop rarement ou si le temps d'exécution est trop court, la stratégie de suppression régulière sera la même que la stratégie de suppression paresseuse, entraînant un gaspillage de mémoire. Par conséquent, si une stratégie de suppression régulière est adoptée, le serveur doit raisonnablement définir la durée d'exécution et la fréquence de l'opération de suppression en fonction de la situation.
La stratégie de suppression paresseuse des clés expirées est implémentée par la fonction db.c/expireIfNeeded Toutes les commandes Redis qui lisent et écrivent dans la base de données appelleront la fonction expireIfNeeded pour vérifier la clé d'entrée avant l'exécution :
Si la clé d'entrée a expiré, la fonction expireIfNeeded supprimera la clé d'entrée de la base de données.
Si la clé de saisie n'a pas expiré, la fonction expireIfNeeded n'agira pas.
La fonction expireIfNeeded est comme un filtre, qui peut filtrer les clés de saisie expirées avant que la commande ne soit réellement exécutée, empêchant ainsi la commande de toucher les touches expirées.
De plus, étant donné que chaque clé accédée peut être supprimée par la fonction expireIfNeeded en raison de l'expiration, la fonction d'implémentation de chaque commande doit être capable de gérer à la fois l'existence de la clé et son absence :
Lorsque la clé existe , la commande est exécutée en fonction de l'existence de la clé.
Lorsque la clé n'existe pas ou que la clé est supprimée par la fonction expireIfNeeded en raison de l'expiration, la commande est exécutée comme si la clé n'existait pas.
La stratégie de suppression périodique des clés expirées est implémentée par la fonction redis.c/activeExpireCycle Chaque fois que la fonction redis.c/serverCron de l'opération périodique du serveur Redis est exécutée, la fonction activeExpireCycle est appelée. Au cours d'une période donnée, parcourez chaque base de données du serveur plusieurs fois, vérifiez de manière aléatoire le délai d'expiration de certaines clés du dictionnaire d'expiration de la base de données et supprimez les clés expirées.
L'ensemble du processus peut être décrit en pseudo-code comme suit
Le mode de fonctionnement de la fonction activeExpireCycle peut être résumé comme suit :
Chaque fois que la fonction s'exécute, elle supprime un certain nombre de clés aléatoires d'un certain nombre de bases de données. Vérifiez et supprimez les clés expirées.
La variable globale current_db enregistrera la progression de la vérification de la fonction activeExpireCycle en cours et continuera à traiter la progression précédente lorsque la prochaine fonction activeExpireCycle sera appelée. Par exemple, si la fonction activeExpireCycle actuelle revient lors du parcours de la base de données n° 10, la prochaine fois que la fonction activeExpireCycle sera exécutée, elle recherchera et supprimera les clés expirées à partir de la base de données n° 11.
Alors que la fonction activeExpireCycle continue de s'exécuter, toutes les bases de données du serveur seront vérifiées. À ce moment, la fonction réinitialise la variable current_db à 0, puis recommence une nouvelle série de travaux de vérification.
Lorsque le serveur fonctionne en mode réplication, la suppression des clés expirées du serveur esclave est contrôlée par le serveur maître :
Après la suppression d'une clé expirée, le serveur maître enverra explicitement une commande DEL à tous les serveurs esclaves pour informer Supprimer cette clé expirée du serveur.
Lorsque le serveur esclave exécute la commande de lecture envoyée par le client, même s'il rencontre une clé expirée, il ne supprimera pas la clé expirée, mais continuera à traiter la clé expirée comme le serait une clé non expirée. supprimé uniquement après l'envoi de la commande DEL depuis le serveur.
En contrôlant le serveur maître pour supprimer uniformément les clés expirées des serveurs esclaves, la cohérence des données du serveur maître-esclave peut être assurée. C'est pour cette raison que lorsqu'une clé expirée existe encore dans la base de données du serveur maître, la clé expirée est La réplique sur le serveur esclave continuera également d'exister. Par exemple, il existe une paire de serveurs maître-esclave et leurs bases de données stockent toutes les mêmes trois clés message, xxx et yyy, où message est la clé expirée, comme le montre la figure.
Si un client envoie le message de commande GET au serveur esclave à ce moment-là, le serveur esclave constatera que la clé de message a expiré, mais le serveur esclave ne supprimera pas la clé de message, mais continuera à renvoyer le valeur de la clé de message au client. fin, comme si la clé de message n'avait pas expiré
En supposant qu'après cela, un client envoie le message de commande GET au serveur principal, alors le serveur principal trouvera que la clé Le message a expiré : le serveur principal supprimera la clé de message et l'enverra au client. Le client renvoie une réponse vide et envoie une commande de message DEL au serveur esclave. Après avoir reçu la commande de message DEL du serveur maître, le serveur esclave le fera. supprimez également la clé de message de la base de données. Après cela, les messages de clé expirés des serveurs maître et esclave ne sont plus enregistrés
Apprentissage recommandé :
Tutoriel vidéo RedisCe 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!