Maison > Article > base de données > Parlons de l'avalanche de cache, de la panne du cache et de la pénétration du cache dans Redis
Dans l'article précédent, nous avons principalement parlé de quelques connaissances de base de Redis. Il n'y a pas eu de combat réel ni de problèmes rencontrés dans la pratique. Aujourd'hui, je vais parler de combat réel.
Je crois que ces trois questions ont été discutées par de nombreux partenaires sur Internet, mais aujourd'hui je tiens quand même à dire que je ferai plus de photos pour permettre à chacun d'approfondir son compréhension. Mon impression est que ces trois questions sont également fréquemment posées lors des entretiens, mais être capable de les expliquer clairement nécessite des compétences. [Recommandations associées : Tutoriel vidéo Redis]
Lorsque nous parlons de ces trois questions, parlons d'abord du processus de demande normal. Regardez l'image pour parler :
La signification de l'image ci-dessus est à peu près la même. suit :
Tout d'abord, vous devrez dans le code, qu'il s'agisse de Tomcat ou de votre service rpc, déterminer d'abord si les données souhaitées existent dans le cache. Si elles sont stockées, elles seront alors renvoyées directement à l'extrémité appelante. .S'il n'existe pas, vous devez interroger la base de données.Après avoir interrogé les résultats, continuez à les mettre en cache dans le cache, puis renvoyez les résultats à l'appelant. La prochaine fois que vous interrogerez, le cache sera atteint.
Définition
Je me souviens que lorsque je faisais le système de recommandation auparavant, certaines données étaient calculées par des algorithmes hors ligne. La demande était de recommander des produits similaires après avoir vu ce produit. être stockés dans hbase et stockés dans redis en même temps Comme ils sont tous générés par un algorithme par lots, lorsqu'ils sont stockés dans redis, si le délai d'expiration est défini sur le même, un grand nombre de clés deviendront invalides en même temps. temps, puis il y aura un grand nombre de clés. La demande sera envoyée à la base de données en arrière-plan, car le débit de la base de données est limité, il est très probable que la base de données tombe en panne. Cette situation est une avalanche de cache. sur l'image pour parler :
Cela illustre principalement un cache Dans les scénarios où des avalanches se produisent, en particulier lors de la configuration des caches par lots pour des tâches planifiées, vous devez faire attention aux paramètres de délai d'expiration.
Comment prévenir les avalanches
C'est en fait très simple. Lorsque vous définissez la durée du cache par lots, définissez un nombre aléatoire pour la durée du cache définie (par exemple, le nombre aléatoire peut être un nombre dans les 10 minutes, un nombre aléatoire. number La génération peut être générée à l'aide de Java's Random), de sorte qu'un grand nombre de clés n'apparaissent pas et échouent collectivement en même temps. Regardez l'image et parlez :
Que faire si une avalanche se produit réellement. ?
Le trafic n'est pas très important, la base de données peut y résister, ok, félicitations pour votre évasion.
Le trafic est très important, dépassant la limite du nombre de requêtes que la base de données peut traiter. Félicitations pour avoir obtenu un ticket d'incident P0.
Le trafic est très important. Si votre base de données a un schéma de limitation de courant, lorsque les paramètres de limitation de courant sont atteints, la requête sera rejetée, protégeant ainsi la base de données en arrière-plan. Voici quelques mots sur la limitation de courant.
Vous pouvez limiter le grand nombre de requêtes atteignant le côté base de données en définissant le nombre de requêtes par seconde ici, ou le nombre de concurrence, n'est pas le nombre actuel de requêtes par seconde pour le. data.Il peut être configuré pour interroger une certaine clé.Le nombre correspondant de requêtes par seconde.Le but est d'empêcher un grand nombre de requêtes avec la même clé d'atteindre la base de données back-end, de sorte que la plupart des requêtes. peut être intercepté.
Regardez l'image et parlez :
De cette façon, la plupart des demandes pour la même clé seront limitées, protégeant ainsi la base de données.
En fait, la limitation de courant est divisée en deux types : la limitation de courant locale et la limitation de courant distribuée. Dans les articles suivants, je présenterai la limitation de courant locale et la limitation de courant distribué implémentées par redis.
Définition
Par exemple, lorsqu'un site Web effectue Double Eleven ou mène des ventes flash et d'autres activités opérationnelles, le trafic du site Web sera généralement très important à ce moment-là, et un certain produit sera être promu en raison de la promotion Il deviendra un produit phare et le trafic sera très important. Si ce produit, pour une raison quelconque, échoue dans le cache à ce moment-là, le trafic de cette clé sera transféré vers la base de données en un instant. , et la base de données ne pourra finalement pas survivre si elle tombe en panne, les conséquences peuvent être imaginées. Normalement, d'autres données ne peuvent pas être interrogées.
Regardez l'image et parlez :
La clé Huawei Pro dans Redis est soudainement tombée en panne. Elle a peut-être expiré ou a été éliminée en raison d'une mémoire insuffisante. Ensuite, un flux important de demandes arrivera. redis, et on constate que redis n'a pas Avec cette clé, le trafic sera transféré vers la base de données pour interroger le huawei pro correspondant. À ce moment, la base de données ne peut plus le supporter et tombe en panne.
Comment résoudre
En fait, en dernière analyse, il suffit de ne pas permettre à plus de trafic d'atteindre la base de données, il suffit donc de limiter le trafic vers la base de données.
1. La limitation de courant
est similaire à ce qui a été mentionné ci-dessus. Elle limite principalement le trafic d'une certaine clé lorsque cette clé est pénétrée, un seul trafic est restreint pour entrer dans la base de données, et les autres sont rejetés ou. attendez une nouvelle opération. Essayez d'interroger Redis.
Pour le schéma de limitation de courant, veuillez vous référer au schéma de limitation de courant de panne de cache.
Cela sera également divisé en limitation de courant locale et limitation de courant distribué.
Qu'est-ce que la limitation du trafic local ? Cela signifie limiter le trafic de cette clé dans le cadre d'une seule instance locale. Elle n'est valable que pour l'instance actuelle.
Qu'est-ce que la limitation de courant distribuée ? Cela signifie que dans un environnement distribué, dans le cadre de plusieurs instances, la limite de trafic cumulé de cette clé est le trafic de plusieurs instances. Lorsque la limite est atteinte, toutes les instances limiteront le trafic à la limite de courant distribuée. DB.
2. Utiliser des verrous distribués
Voici une brève introduction à la définition des verrous distribués. Dans les scénarios simultanés, les verrous doivent être utilisés pour fournir un accès mutuellement exclusif aux ressources partagées afin de garantir la sécurité des threads de la même manière, dans les scénarios distribués. , Un mécanisme est également nécessaire pour garantir un accès mutuellement exclusif aux ressources partagées multi-nœuds, et le mécanisme de mise en œuvre est constitué de verrous distribués.
La ressource partagée ici est Huawei Pro dans l'exemple. Autrement dit, lors de l'accès à Huawei Pro dans la base de données, il est nécessaire de s'assurer qu'un seul thread ou un seul flux est accédé pour obtenir l'effet de verrouillage distribué.
Regardez l'image et parlez :
Allez récupérer le verrou :
Après qu'un grand nombre de requêtes n'aient pas obtenu la valeur de la clé Huawei Pro, elles sont prêtes à se rendre dans la base de données pour obtenir les données . À ce stade, le code pour obtenir la base de données ajoute un verrou distribué, puis chaque requête et chaque thread acquerra le verrou distribué de Huawei Pro (le verrouillage distribué est implémenté à l'aide de redis dans la figure. J'aurai un article séparé plus tard pour le présenter. la mise en œuvre du verrouillage distribué, qui ne se limite pas à Redis).
Après avoir acquis le verrou :
À ce moment, le thread A acquiert le verrou distribué de Huawei Pro, puis le thread A ira dans la base de données pour charger les données, puis le thread A placera à nouveau Huawei Pro dans le cache, puis renvoyez les données.
D'autres threads ne l'ont pas obtenu. Une façon consiste à renvoyer directement une valeur nulle au client, et une autre méthode consiste à attendre 50 à 100 ms, car interroger la base de données et la mettre dans Redis sera très rapide. et interrogez à nouveau. Le résultat peut être disponible. Sinon, null sera renvoyé directement. Bien sûr, vous pouvez également réessayer. Bien sûr, dans les grands scénarios de concurrence, vous souhaitez toujours pouvoir renvoyer les résultats rapidement et éviter également. de nombreuses tentatives.
3. Les tâches planifiées mettent à jour les clés de point d'accès
C'est facile à comprendre, pour parler franchement, il s'agit d'une tâche planifiée qui surveille régulièrement le délai d'expiration de certaines clés de point d'accès pour voir si elles ont expiré, puis effectue la mise à jour. lorsqu'elle est sur le point d'expirer, prolongez simplement la durée de cache de la clé dans le cache.
Vérifiez et mettez à jour le délai d'expiration à l'aide d'une interrogation à fil unique, voir image :
Méthode multi-thread, veuillez noter qu'il ne doit pas y avoir trop de clés de point d'accès, un certain fil en ouvrira plusieurs, s'il y en a existe de nombreuses clés de point d'accès, vous pouvez utiliser la méthode du pool de threads, voir l'image :
Implémentation de la file d'attente différée
La méthode ci-dessus le dit sans détour, qu'il s'agisse d'un seul thread ou de plusieurs threads, l'interrogation sera utilisé (à chaque fois en vain CPU gaspillé) pour vérifier si la clé est sur le point d'expirer. Cette méthode de vérification entraînera un temps de contrôle inexact, ce qui peut entraîner des retards ou des inexactitudes. Pendant que vous attendez le prochain contrôle, la clé sera. disparu, alors une panne s'est déjà produite à ce moment-là. Bien que la probabilité que cette situation se produise, cela se produit, alors, comment pouvons-nous l'éviter ? Je ne parlerai pas de cette file d'attente en profondeur ici. Le principe, vous pouvez Baidu ou Google), la file d'attente dite différée est que vous envoyez des messages à cette file d'attente, dans l'espoir de consommer en fonction du temps que vous avez défini. La consommation ne sera pas. fait avant que le temps soit écoulé, et la consommation se fera lorsque le temps sera écoulé. D'accord Parlons-en en regardant les photos :
1. Lorsque le programme est démarré pour la première fois, le délai d'expiration est indiqué. des clés de la liste est obtenue.
2. Réglez le temps de consommation du délai clé dans l'ordre. Notez que le temps de consommation est antérieur au délai d'expiration.
3. Retardez l'expiration de la file d'attente et le consommateur consommera la clé.
4. Le consommateur consomme des messages et retarde le délai d'expiration de la clé du cache.
5. Envoyez à nouveau le nouveau délai d'expiration de la clé à la file d'attente différée et attendez le prochain délai d'expiration du cache retardé.
4. Le réglage de la clé n'expire pas
En fait, la clé peut être éliminée en raison d'une mémoire insuffisante. Vous pouvez penser aux circonstances dans lesquelles la clé sera éliminée.
Définition
La soi-disant pénétration consiste à accéder à une clé qui n'existe pas dans le cache ou dans la base de données. Puis à ce moment-là, le trafic atteint directement la base de données, puis quelques voleurs. Vous pouvez profiter de cette vulnérabilité et flasher follement votre interface, détruisant ainsi votre base de données, et votre entreprise ne pourra plus fonctionner normalement.
Comment le résoudre ?
1. Définir une valeur nulle ou spéciale
Nous pouvons définir une valeur nulle ou spécifique dans redis sans expiration. Ensuite, la prochaine fois que nous reviendrons, nous pourrons obtenir la valeur nulle ou spéciale directement à partir de redis.
Cette solution ne peut pas résoudre le problème fondamental. Si ce trafic peut forger un grand nombre de clés inutiles, il sera inutile quel que soit le nombre de valeurs nulles ou spéciales que vous définissez. Alors, comment devrions-nous le résoudre ?
2. Filtre Bloom
Le filtre Bloom est appelé bloomfiler en anglais. Ici, nous donnerons juste une brève introduction. Pour des raisons d'espace, il y aura un article séparé pour le présenter plus tard.
Par exemple, si notre base de données stocke des dizaines de millions de données sku, notre exigence actuelle est que si la bibliothèque a ce sku, interrogez redis. Si redis n'existe pas, interrogez la base de données, puis mettez à jour redis. Pensez à cela, c'est de mettre les données sku dans une hashmap, et la clé est sku. Parce qu'il y a beaucoup de sku, l'espace mémoire occupé par cette hashmap sera très grand, et cela peut faire éclater la mémoire. L'emporte sur la perte. Alors, comment économiser de la mémoire, nous pouvons utiliser un tableau de bits pour stocker l'état de l'existence du sku. 0 représente la non-existence et 1 représente l'existence. Nous pouvons utiliser une fonction de hachage pour calculer la valeur de hachage du sku. , puis extrayez la valeur de hachage du sku du tableau de bits Modulo, recherchez la position du tableau, puis définissez-la sur 1. Lorsque la demande arrive, nous calculerons si la position du tableau correspondant à la valeur de hachage du sku est 1. s'il vaut 1, cela signifie qu'il existe, et s'il vaut 0, cela signifie qu'il n'existe pas. Un bloomfilter aussi simple est implémenté. Bloomfiler a un taux d'erreur. Vous pouvez envisager d'augmenter la longueur du tableau et le nombre de fonctions de hachage pour assurer la précision. Plus précisément, vous pouvez utiliser Baidu ou Google, je n'en parlerai pas ici aujourd'hui.
Jetons un coup d'œil au processus d'utilisation de bloomfiler pour empêcher la pénétration du cache. Regardez l'image pour parler :
L'initialisation de bloomfiler peut lire la base de données via une tâche planifiée et initialiser la taille du tableau de bits. est 0, ce qui signifie qu'il n'existe pas, puis calculez la position du tableau correspondant à la valeur de hachage pour chaque élément, puis insérez-la dans le tableau de bits.
Processus de demande, voir photo :
Si vous n'utilisez pas le filtre bloomfiler, pour une clé qui n'existe pas dans la base de données, vous perdrez en fait deux IO, une pour interroger redis, et un pour interroger la base de données sans bloomfiler, ces deux E/S inutiles sont enregistrées et le gaspillage des ressources redis et base de données back-end est réduit.
Aujourd'hui, nous avons parlé des problèmes et des solutions rencontrés lors des entretiens à haute fréquence et du combat réel contre le cache Redis.
Avalanche de cache
Solution :
Lors de la définition du délai d'expiration, ajoutez un nombre aléatoire de temps, cela peut prendre quelques minutes.
En plus de la question de savoir quoi faire en cas d'avalanche, la limitation de courant peut être utilisée.
Verrouillage du cache
Solution :
Limitation de courant
Verrouillage distribué
Mettez régulièrement à jour les clés de point d'accès. Ici, nous nous concentrons sur la file d'attente de retard. "Définir l'heure sans expiration"
Plus de connaissances liées à la programmation, veuillez visiter :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!