String : Redis n'utilise pas directement la représentation sous forme de chaîne traditionnelle du langage C, mais implémente son propre type abstrait appelé simple chaîne dynamique SDS. La chaîne en langage C n'enregistre pas ses propres informations de longueur, mais SDS enregistre les informations de longueur, ce qui réduit le temps nécessaire pour obtenir la longueur de la chaîne de O(N) à O(1), tout en évitant le débordement de tampon et en réduisant le besoin de modification. caractères. Le nombre de réallocations de mémoire requises pour la longueur de la chaîne.
Liste chaînée : la liste chaînée redis est une structure de liste chaînée acyclique bidirectionnelle. De nombreuses fonctions de publication et d'abonnement, de requête lente et de surveillance sont implémentées à l'aide de listes chaînées. Les nœuds de chaque liste chaînée sont représentés par une structure listNode. .Chaque nœud Il y a des pointeurs vers le nœud précédent et le nœud suivant, et les nœuds précédent et suivant du nœud d'en-tête pointent vers NULL.
Table de hachage de dictionnaire : une structure de données abstraite utilisée pour enregistrer des paires clé-valeur. Redis utilise des tables de hachage comme implémentation sous-jacente. Chaque dictionnaire dispose de deux tables de hachage pour une utilisation quotidienne et un rehachage. La table de hachage utilise la méthode d'adresse de chaîne pour résoudre les conflits de clés et est affectée à plusieurs paires clé-valeur à la même position d'index. -way est formée lorsque la table de hachage est étendue ou réduite, pour des raisons de disponibilité du service, le processus de rehachage n'est pas terminé en une seule fois, mais progressivement.
Liste de sauts : la liste de sauts est l'une des implémentations sous-jacentes des ensembles ordonnés. Les listes de sauts sont utilisées dans Redis pour implémenter les clés d'ensembles ordonnés et la structure interne des nœuds de cluster. La table de saut Redis se compose de zskiplist et de zskiplistNode. zskiplist est utilisé pour enregistrer les informations de la table de saut (en-tête, nœud de queue, longueur, etc.). zskiplistNode est utilisé pour représenter les nœuds de saut de table. La hauteur de couche de chaque table de saut est aléatoire à partir de 1. à 32. Nombre, dans une même table de sauts, plusieurs nœuds peuvent contenir le même score, mais l'objet membre de chaque nœud doit être unique. Les nœuds sont triés selon la taille du score. Si les scores sont identiques, ils sont triés. sont triés en fonction de la taille de l'objet membre.
Integer set intset : une structure de données abstraite de collection utilisée pour enregistrer des valeurs entières. Il n'y aura pas d'éléments en double. L'implémentation sous-jacente est un tableau.
Ziplist de liste compressée : la liste compressée est une structure de données séquentielle développée pour économiser de la mémoire. Elle peut contenir plusieurs nœuds, et chaque nœud peut enregistrer un tableau d'octets ou une valeur entière.
Sur la base de ces structures de données de base, redis encapsule son propre système d'objets, y compris la chaîne d'objets chaîne, la liste d'objets de liste, le hachage d'objet de hachage, l'ensemble d'objets de collection et l'objet de collection ordonné zset, dont chacun est utilisé au moins un élément de base structure des données.
redis définit la forme d'encodage de l'objet via l'attribut encoding pour améliorer la flexibilité et l'efficacité. Redis effectuera automatiquement des optimisations en fonction de différents scénarios. L'encodage des différents objets est le suivant :
String chaîne d'objet : int entier, chaîne dynamique simple codée embstr, chaîne dynamique simple brute
List liste d'objets : ziplist, linkedlist
Hash hachage d'objet : ziplist, hashtable
Ensemble d'objets de collection : intset, hashtable
Objet de collection ordonné zset : ziplist, skiplist
redis est très rapide. Un seul redis peut prendre en charge des dizaines de milliers de simultanéités par seconde. Par rapport à MySQL, les performances sont des dizaines de fois supérieures à celles de MySQL. Les principales raisons de la vitesse rapide sont :
Entièrement basé sur les opérations de mémoire
Implémentation du langage C, structure de données optimisée, basée sur plusieurs structures de données de base, redis a fait beaucoup d'optimisation et les performances sont extrêmement high
Utilisez un seul thread, aucun coût de changement de contexte
Basé sur un mécanisme de multiplexage d'E/S non bloquant
redis utilise le multi-threading Les threads n'abandonnent pas complètement les threads uniques. Redis utilise toujours un modèle à thread unique pour traiter les demandes des clients. Il utilise uniquement plusieurs threads pour gérer la lecture et l'écriture des données et l'analyse du protocole.
Le but de ceci est que le goulot d'étranglement des performances de Redis réside dans les E/S du réseau plutôt que dans le processeur. L'utilisation du multithreading peut améliorer l'efficacité de la lecture et de l'écriture des E/S, améliorant ainsi les performances globales de Redis.
Le soi-disant problème de raccourci clavier est qu'il y a soudainement des centaines de milliers de demandes pour accéder à une clé spécifique sur Redis, ce qui entraînera une trop grande concentration du trafic et atteindra la limite supérieure de la carte réseau physique, provoquant le problème. serveur redis pour planter et déclencher une avalanche.
Solution pour les touches de raccourci :
Répartissez les touches de raccourci sur différents serveurs à l'avance pour réduire la pression
Ajoutez le cache de deuxième niveau et chargez les données des touches de raccourci dans la mémoire à l'avance. Si Redis est en panne, aller à la requête de mémoire
Le concept de panne du cache est que l'accès simultané à une seule clé est trop élevé. Lorsqu'elle expire, toutes les demandes seront touchées directement. à la base de données. Ceci est similaire à hot. Le problème de clé est similaire, sauf que l'expiration entraîne l'envoi de toutes les requêtes à la base de données.
Solution :
Verrouiller la mise à jour, par exemple, demander d'interroger A et constater qu'il n'est pas dans le cache, verrouiller la clé A, et accédez à La base de données interroge les données, les écrit dans le cache, puis les renvoie à l'utilisateur, afin que les requêtes ultérieures puissent obtenir les données du cache.
Écrivez la combinaison du délai d'expiration dans la valeur et actualisez continuellement le délai d'expiration de manière asynchrone pour éviter ce genre de phénomène.
La pénétration du cache signifie interroger des données qui n'existent pas dans le cache. Chaque requête atteindra la base de données, comme si c'était le cas. le cache n'existe pas.
Pour résoudre ce problème, ajoutez une couche de filtre Bloom. L'étape de fonctionnement du filtre Bloom consiste à mapper les données en K points dans le tableau de bits via une fonction de hachage, et à définir ces points sur 1 pour stocker les données.
De cette façon, lorsque l'utilisateur interroge à nouveau A et que la valeur du filtre Bloom de A est 0, elle sera renvoyée directement, et aucune demande de panne ne sera générée et n'atteindra la base de données.
Évidemment, il y aura un problème après avoir utilisé le filtre Bloom, ce qui est une erreur de jugement. Parce qu'il s'agit d'un tableau lui-même, il peut y avoir plusieurs valeurs tombant dans la même position. car plus la longueur du tableau est longue, plus la probabilité d'une erreur de jugement sera faible. Ce problème doit être traité en fonction de la situation réelle.
Lorsqu'une panne de cache à grande échelle se produit à un moment donné, par exemple lorsque votre service de cache est en panne, un grand nombre de requêtes arrivent et frappent le DB directement. Cela peut conduire à l’effondrement de l’ensemble du système, appelé avalanche. Contrairement aux problèmes de panne et de raccourci clavier, le problème d'avalanche fait référence à l'expiration simultanée de caches à grande échelle.
Plusieurs solutions en cas d'avalanche :
Définissez des délais d'expiration différents pour différentes clés afin d'éviter une expiration simultanée
#🎜🎜 ##🎜 🎜#Alors que dois-je faire si les clés expirées ne sont pas supprimées régulièrement ou paresseusement ?
# 🎜 🎜#volatile-ttl : Supprimez la clé sur le point d'expirer de la clé avec un délai d'expiration défini Sélectionnez la clé à éliminer
allkeys-lru : Sélectionnez la clé la moins récemment utilisée clé de la clé pour l'élimination
allkeys -random : Sélectionnez aléatoirement les clés parmi les clés pour l'élimination
noeviction : Lorsque la mémoire atteint le seuil, une erreur sera signalée pour les nouvelles opérations d'écriture
Quelles sont les méthodes de persistance ? Quelle est la différence ?
Avant la fin de chaque boucle d'événement sur le serveur, la fonction flushAppendOnlyFile sera appelée pour déterminer s'il faut enregistrer le contenu de aof_buf dans le fichier AOF. Cela peut être déterminé en configurant appendfsync.
always ##aof_buf内容写入并同步到AOF文件 everysec ##将aof_buf中内容写入到AOF文件,如果上次同步AOF文件时间距离现在超过1秒,则再次对AOF文件进行同步 no ##将aof_buf内容写入AOF文件,但是并不对AOF文件进行同步,同步时间由操作系统决定
Si elle n'est pas définie, l'option par défaut sera Everysec, car bien que ce soit toujours le plus sûr (une seule commande d'écriture de la boucle d'événement sera perdue), les performances sont médiocres et le mode Everysec ne peut perdre qu'une seconde. données d'horloge, tandis que l'efficacité du mode aucun est similaire à celle de chaque seconde, mais toutes les données de commande d'écriture après la dernière synchronisation du fichier AOF seront perdues.
Pour atteindre une haute disponibilité, une seule machine ne suffit certainement pas. Pour garantir une haute disponibilité, redis propose 2 options.
Le mode maître-esclave est la solution la plus simple pour atteindre une haute disponibilité, et le cœur est la synchronisation maître-esclave. Le principe de la synchronisation maître-esclave est le suivant :
l'esclave envoie la commande de synchronisation au maître
Une fois que le maître a reçu la synchronisation, il exécute bgsave et génère un fichier RDB complet
le maître enregistre la commande d'écriture de l'esclave dans le cache
Une fois bgsave exécuté, envoyez le fichier RDB à l'esclave, et l'esclave l'exécute. Le maître envoie la commande d'écriture dans le cache à l'esclave, et l'esclave l'exécute. La commande que j'ai écrite ici est sync. après que la version redis2.8, psync a été utilisée pour remplacer sync, la raison en est que la commande sync consomme des ressources système et que psync est plus efficace.
Les défauts de la solution maître-esclave sont encore très évidents. Si le maître est en panne, alors les données ne peuvent pas être écrites, alors l'esclave perdra sa fonction et l'architecture entière sera indisponible à moins que vous ne basculiez manuellement. La raison principale est qu'il n'existe pas de mécanisme de basculement automatique. La fonction de Sentinel est beaucoup plus complète que celle d'une simple architecture maître-esclave. Elle possède des fonctions telles que le basculement automatique, la surveillance du cluster et la notification des messages.
Initialisez le dictionnaire maître et les informations du serveur, les informations du serveur enregistrent principalement ip:port et enregistrent l'adresse et ID de l'instance
Créez deux connexions avec le maître, une connexion de commande et une connexion d'abonnement, et abonnez-vous à la chaîne sentinel:hello
Envoyez la commande info au maître toutes les 10 secondes pour obtenir les informations actuelles du maître et de tous ses esclaves
Quand Après avoir découvert que le maître a un nouvel esclave, la sentinelle établit également deux connexions avec le nouvel esclave et envoie une commande d'information toutes les 10 secondes pour mettre à jour les informations du maître
Sentinelle envoie une commande ping à tous les serveurs toutes les secondes. Si un certain serveur renvoie continuellement des réponses invalides dans le temps de réponse configuré, il sera marqué comme hors ligne.
Élisez une sentinelle leader. de plus de la moitié des sentinelles.
La sentinelle chef sera sélectionnée parmi le maître hors ligne et convertissez-le en maître
Laissez tous les esclaves copier les données du nouveau maître
. Définissez le maître d'origine comme serveur esclave du nouveau maître, lorsque le maître d'origine reprend la connexion, il devient le serveur esclave du nouveau maître
sentinel enverra une commande ping à toutes les instances (y compris le serveur maître-esclave et autres sentinelles) toutes les 1 seconde, et jugez s'il est hors ligne en fonction de la réponse. Cette méthode est appelée hors ligne subjective. Lorsqu'il est jugé subjectivement hors ligne, d'autres sentinelles de surveillance seront interrogées. Si plus de la moitié des votes estiment qu'il est hors ligne, il sera marqué comme objectivement hors ligne et un basculement sera déclenché.
Node
Le nœud A reçoit la commande cluster meet du client
A envoie un message de rencontre à B en fonction de l'adresse IP et du numéro de port reçus
Le nœud B reçoit le message de rencontre et renvoie pong
A sait que B a reçu le message de rencontre, renvoie un message ping et la poignée de main est réussie
Enfin, le nœud A diffusera les informations du nœud B aux autres nœuds du cluster via le protocole Gossip, et les autres nœuds serreront également la main de B
slot
slot est un tableau de bits, la longueur du tableau est de 16384/8 = 2048, et chaque bit du tableau est représenté par 1 à traiter par le nœud, et 0 représente non traité. Comme le montre la figure, cela signifie. ce nœud A traite les emplacements 0 à 7.
Lorsque le client envoie une commande au nœud, s'il s'avère que l'emplacement appartient au nœud actuel, le nœud exécutera la commande. Sinon, une commande MOVED sera renvoyée au client pour guider le client vers le nœud. nœud correct. (Le processus MOVED est automatique)
Si vous ajoutez ou supprimez des nœuds, il est également très pratique de réattribuer des emplacements. Redis fournit des outils pour aider à réaliser la migration des emplacements. L'ensemble du processus est entièrement en ligne et n'a pas besoin d'arrêter le service.
Si le nœud A envoie un message ping au nœud B et que le nœud B ne répond pas au pong dans le délai spécifié, alors le nœud A marquera le nœud B comme pfail et suspecté d'être hors ligne, et en même temps, envoyer l'état de B sous la forme d'un message. Envoyé à d'autres nœuds. Si plus de la moitié des nœuds marquent B comme pfail, B sera marqué comme échec hors ligne. À ce moment, un basculement se produira et un nœud esclave avec plus de réplication. Les données seront sélectionnées en premier pour devenir le nœud maître et prendront en charge l'emplacement du nœud hors ligne. L'ensemble du processus est très similaire à celui de Sentinel et est basé sur le protocole Raft pour l'élection.
redis implémente le mécanisme de transaction via MULTI, EXEC, WATCH et d'autres commandes. Le processus d'exécution de la transaction exécute une série de plusieurs commandes en séquence en même temps, et pendant l'exécution, la transaction ne sera pas interrompue, ni le client. exécuter Des requêtes supplémentaires sont effectuées jusqu'à ce que toutes les commandes aient été exécutées. Le processus d'exécution de la transaction est le suivant :
Le serveur reçoit la requête du client, et la transaction commence par MULTI
Si le client est dans l'état de transaction, la transaction sera mise en file d'attente et renvoyée au client QUEUED, sinon il sera directement Exécuter cette commande
Lors de la réception de la commande EXEC du client, la commande WATCH surveille si la clé dans l'ensemble de la transaction a été modifiée. Si tel est le cas, elle renvoie une réponse vide au client. pour indiquer un échec. Sinon, redis parcourra toute la file d'attente des transactions et exécutera Toutes les commandes enregistrées dans la file d'attente renverront finalement les résultats au client. Le mécanisme WATCH lui-même est un mécanisme CAS. Les clés surveillées seront enregistrées dans une liste chaînée. une clé est modifiée, le flag REDIS_DIRTY_CAS sera ouvert, moment auquel le serveur refusera d'exécuter la transaction.
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!