Golden Nine et Silver Ten arrivent bientôt. Cet article partagera avec vous 20 questions d'entretien classiques Redis. J'espère que cela vous sera utile !
Redis, le nom anglais complet est Remote Dictionary Server (Remote Dictionary Service), est une base de données de valeurs-clés de type journal open source écrite en langage ANSI C, prend en charge le réseau, peut être basée sur la mémoire et peut être persistant et fournit une API dans plusieurs langues. [Recommandations associées : Tutoriel vidéo Redis]
Différentes de la base de données MySQL, les données Redis sont stockées en mémoire. Ses vitesses de lecture et d'écriture sont très rapides et peuvent gérer plus de 100 000 opérations de lecture et d'écriture par seconde. Par conséquent, Redis est largement utilisé dans la mise en cache. De plus, Redis est également souvent utilisé pour les verrous distribués. De plus, Redis prend en charge les transactions, la persistance, les scripts LUA, les événements pilotés par LRU et diverses solutions de cluster.
2. Parlons des types de structure de données de base de RedisChaîne ( string)
Introduction : La chaîne est le type de structure de données le plus basique de Redis. Elle est binaire et peut stocker des images ou des objets sérialisés. La valeur maximale stockée est de 512 Mdéfinir la valeur de la clécode>, <code>get key
, etc.
set key value
、get key
等int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)
C语言的字符串是char[]
实现的,而Redis使用SDS(simple dynamic string) 封装,sds源码如下:
struct sdshdr{ unsigned int len; // 标记buf的长度 unsigned int free; //标记buf中未使用的元素个数 char buf[]; // 存放元素的坑 }
SDS 结构图如下:
Redis为什么选择SDS结构,而C语言原生的 char[]
不香吗?
举例其中一点,SDS中,O(1)时间复杂度,就可以获取字符串长度;而C 字符串,需要遍历整个字符串,时间复杂度为O(n)
hset key field value
、hget key field
ziplist(压缩列表)
、hashtable(哈希表)
字符串和哈希类型对比如下图:
lpush key value [value ...]
、lrange key start end
int (entier long de 8 octets)/embstr (inférieur ou égal à une chaîne de 39 octets)/raw (chaîne supérieure à 39 octets)
char[]
, et Redis utilise le package zadd user:ranking:2021-03-03 Jay 3
Pourquoi Redis a-t-il choisi la structure
SDSEt lechar[]
natif du langage C n'est-il pas bon ?Par exemple, en SDS, la longueur de la chaîne peut être obtenue avec une complexité temporelle O(1) ; tandis que pour les chaînes C, la chaîne entière doit être parcourue et la complexité temporelle est O(n)< h4 data- id="heading-5">Hash (Hash)
Exemple d'utilisation simple :- Introduction : Dans Redis, le type de hachage fait référence à v (valeur) lui-même qui est également une structure de paire clé-valeur (k-v)
hset key field value
,hget key field
ziplist (liste compressée)
, hashtable (table de hachage)< /code ></h4><p>Scénarios d'application : mise en cache des informations utilisateur, etc. <img src="https://img.php.cn/upload/image/656/664/457/1631501863989751.png" title="1631501863989751.png" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p>🎜Remarque🎜 : Si hgetall est utilisé dans le développement et qu'il existe de nombreux éléments de hachage, cela peut entraîner le blocage de Redis. Vous pouvez utiliser hscan. Si vous souhaitez uniquement obtenir certains champs, il est recommandé d'utiliser hmget. 🎜🎜🎜La comparaison entre les types de chaîne et de hachage est la suivante : 🎜🎜<img src="https://img.php.cn/upload/image/984/524/946/16315018485778Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" title="1631501848577830 .png " alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/>🎜<h4 data-id="heading-6">Liste (liste)🎜🎜🎜Introduction : Le type liste (liste) est utilisé pour stocker plusieurs chaînes ordonnées, une liste peut stocker jusqu'à 2 ^ 32-1 éléments. 🎜🎜Exemples simples et pratiques : <code> lpush key value [value ...]
, lrange key start end
🎜🎜Encodage interne : ziplist (liste compressée), linkedlist (liste chaînée )🎜 🎜Scénarios d'application : file d'attente de messages, liste d'articles, 🎜🎜🎜Une image pour comprendre l'insertion et le pop-up du type de liste : 🎜🎜🎜🎜🎜Les scénarios d'application de liste font référence à ce qui suit : 🎜🎜🎜🎜lpush+lpop= Stack (stack)🎜🎜lpush +rpop=Queue (file d'attente)🎜🎜lpsh+ltrim=Capped Collection (collection limitée)🎜🎜lpush+brpop=Message Queue (file d'attente des messages)🎜🎜🎜🎜Set (set)🎜🎜🎜🎜sadd key element [element ...]
, smembers key
sadd key element [element ...]
、smembers key
intset(整数集合)
、hashtable(哈希表)
zadd key score member [score member ...]
,zrank key member
ziplist(压缩列表)
、skiplist(跳跃表)
intset (ensemble d'entiers)
, hashtable (table de hachage)
Notes : smembers, lrange et hgetall sont des commandes relativement lourdes. S'il y a trop d'éléments et qu'il existe une possibilité de bloquer Redis, vous pouvez utiliser sscan pour le terminer. zadd key score member [ score membre ...]
, membre clé zrank
ziplist (liste compressée)
, skiplist (liste ignorée)</code > code><h2 data-id="heading-10"></h2>Scénarios d'application : classements, besoins sociaux (tels que les likes des utilisateurs). <p><img src="https://img.php.cn/upload/image/701/100/216/1631501869718890.png" title="1631501869718890.png" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p>2.2 Trois types de données spéciaux de Redis<h3 data-id="heading-11"></h3><p>Geo : Introduit par Redis3.2, le positionnement géographique est utilisé pour stocker des informations de localisation géographique et opérer sur les informations stockées. </p><h3 data-id="heading-12">HyperLogLog : une structure de données utilisée pour les algorithmes statistiques de cardinalité, tels que UV pour les sites Web statistiques. </h3><p>Bitmaps : utilisez un bit pour mapper l'état d'un élément. Dans Redis, sa couche inférieure est basée sur le type de chaîne. Vous pouvez transformer les bitmaps en un tableau avec des bits comme unité</p><p><img src="https://img.php.cn/upload/image/959/396/733/1631501874129651.png" title="1631501874129651.png" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/>3. </p><h4 data-id="heading-13"></h4><p><img src="https://img.php.cn/upload/image/879/413/599/16315018818874Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" title="16315018818874Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/>3.1 Implémentation basée sur le stockage en mémoire</p><blockquote>Nous savons tous que la lecture et l'écriture en mémoire sont beaucoup plus rapides que la base de données Redis basée sur le stockage en mémoire, par rapport à la base de données MySQL où les données sont stockées sur le disque, élimine l'I/du disque. Ô consommation. <ul><li>3.2 Structure de données efficace</li><li>Nous savons que afin d'améliorer l'efficacité, l'index Mysql choisit la structure de données arborescente B+. En fait, une structure de données raisonnable peut rendre votre application/programme plus rapide. Jetons d'abord un coup d'œil à la structure des données et au diagramme d'encodage interne de Redis : </li><li></li><li></li>Chaîne dynamique simple SDS </ul></blockquote><h4 data-id="heading-14"></h4><p></p><h4 data-id="heading-15">Traitement de la longueur de chaîne : Redis obtient la longueur de la chaîne, la complexité temporelle est O(1) , et En langage C, il doit être parcouru depuis le début, et la complexité est O(n); </h4><p>Pré-allocation d'espace : plus la chaîne est modifiée fréquemment, plus l'allocation de mémoire sera fréquente, ce qui consomme des performances, et la modification SDS et l'expansion de l'espace nécessiteront une allocation supplémentaire. L'espace inutilisé réduit la perte de performances. <img src="https://img.php.cn/upload/image/349/649/661/163150189098463Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" title="163150189098463Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p> Libération d'espace paresseuse : lorsque SDS est raccourci, au lieu de recycler l'espace mémoire excédentaire, free enregistre l'espace excédentaire. S'il y a des modifications ultérieures, l'espace enregistré en free sera directement utilisé pour réduire l'allocation. <blockquote><ul>Sécurité binaire : Redis peut stocker certaines données binaires, chaînes rencontrées en langage C'<blockquote><ul><li>String : Si des nombres sont stockés, un encodage de type int est utilisé ; si des non-nombres sont stockés, une chaîne inférieure ou égale à 39 octets est embstr ; si elle est supérieure à 39 octets, un encodage brut est utilisé. </li><li>Liste : Si le nombre d'éléments dans la liste est inférieur à 512 et que la valeur de chaque élément de la liste est inférieure à 64 octets (par défaut), utilisez le codage ziplist, sinon utilisez le codage liste liée </li><li>Hash : Le nombre de Les éléments de type de hachage sont inférieurs à 512 , si toutes les valeurs sont inférieures à 64 octets, utilisez le codage ziplist, sinon utilisez le codage table de hachage. </li><li>Ensemble : si les éléments de l'ensemble sont tous des entiers et que le nombre d'éléments est inférieur à 512, utilisez le codage intset, sinon utilisez le codage table de hachage. </li><li>Zset : lorsque le nombre d'éléments dans l'ensemble ordonné est inférieur à 128 et que la valeur de chaque élément est inférieure à 64 octets, utilisez l'encodage ziplist, sinon utilisez l'encodage skiplist (skip list) </li></ul></blockquote><h3 data-id="heading-17">3.4 Modèle de thread raisonnable </h3> <p> <strong>Multiplexage d'E/S</strong></p><p><img src="https://img.php.cn/upload/image/222/494/553/1631501897175981.png" title="1631501897175981.png" alt="Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p><blockquote><p>La technologie de multiplexage d'E/S multiples permet à un seul thread de gérer efficacement plusieurs demandes de connexion, et Redis utilise epoll comme technologie de multiplexage d'E/S. De plus, le modèle de traitement des événements de Redis convertit les connexions, les lectures, les écritures et les arrêts dans epoll en événements, sans perdre trop de temps en E/S réseau. </p></blockquote><p>Qu'est-ce que le multiplexage d'E/S ? </p><blockquote><ul><li>E/S : E/S réseau</li><li>Multiple : plusieurs connexions réseau</li><li>Multiplexage : réutilisation du même fil. </li><li>Le multiplexage IO est en fait un modèle IO synchrone, qui implémente un thread capable de surveiller plusieurs descripteurs de fichiers ; une fois qu'un descripteur de fichier est prêt, il peut demander à l'application d'effectuer les opérations de lecture et d'écriture correspondantes sans descripteur de fichier. Lorsqu'il est prêt, le multiplexage IO est en fait un modèle IO synchrone, qui implémente un thread capable de surveiller plusieurs descripteurs de fichiers ; une fois qu'un descripteur de fichier est prêt, il peut demander à l'application d'effectuer les opérations de lecture et d'écriture correspondantes sans descripteur de fichier. l'application sera bloquée et le CPU sera remis. </li></ul></blockquote><p><strong>Modèle monothread</strong></p><ul><li>Redis est un modèle monothread, et le monothread évite les changements inutiles de contexte CPU et la consommation de verrouillage de concurrence. Précisément parce qu'il s'agit d'un seul thread, si une certaine commande est exécutée trop longtemps (comme la commande hgetall), cela provoquera un blocage. Redis est une base de données pour des scénarios d'exécution rapide. , les commandes telles que smembers, lrange, hgetall, etc. doivent donc être utilisées avec prudence. </li><li>Redis 6.0 introduit le multithreading pour accélérer, et son exécution de commandes et d'opérations de mémoire est toujours un seul thread. </li></ul><h3 data-id="heading-18">3.5 Mécanisme de mémoire virtuelle</h3><p>Redis construit directement le mécanisme de la VM par lui-même. Il n'appellera pas les fonctions système comme les systèmes ordinaires et ne perdra pas un certain temps en déplacements et en requêtes. </p><p><strong>Quel est le mécanisme de mémoire virtuelle de Redis ? </strong></p><blockquote><p>Le mécanisme de mémoire virtuelle échange temporairement les données rarement consultées (données froides) de la mémoire vers le disque, libérant ainsi un espace mémoire précieux pour d'autres données auxquelles il faut accéder (données chaudes). La fonction VM peut réaliser la séparation des données chaudes et froides, de sorte que les données chaudes soient toujours dans la mémoire et que les données froides soient enregistrées sur le disque. Cela peut éviter le problème de vitesse d'accès lente causée par une mémoire insuffisante. </p></blockquote><h2 data-id="heading-19">4. Qu'est-ce que la panne de cache, la pénétration du cache, l'avalanche de cache ? </h2><h3 data-id="heading-20">4.1 Problème de pénétration du cache</h3><p> Examinons d'abord une manière courante d'utiliser le cache : lorsqu'une demande de lecture arrive, vérifiez d'abord le cache s'il y a un succès dans le cache, il reviendra directement si le cache ne répond pas ; , vérifiez la base de données, puis placez la base de données. La valeur est mise à jour dans le cache puis renvoyée. </p><p><img src="https://img.php.cn/upload/image/546/664/907/1631501902654880.png" title="1631501902654880.png" alt="1Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p><p><strong>Pénétration du cache</strong> : fait référence à l'interrogation de données qui n'existent certainement pas. Puisque le cache n'atteint pas, il doit être interrogé à partir de la base de données. Si les données ne sont pas trouvées, elles ne seront pas écrites. Le cache. Cela entraînera la suppression des données inexistantes. Chaque requête doit être interrogée dans la base de données, ce qui exerce une pression sur la base de données. </p><blockquote><p>Pour faire simple, lors de l'accès à une requête de lecture, ni le cache ni la base de données n'ont une certaine valeur, ce qui entraînera la pénétration de chaque requête pour cette valeur dans la base de données. </p></blockquote><p>La pénétration du cache est généralement causée par les situations suivantes : </p><ul><li><strong>Conception commerciale déraisonnable</strong>, par exemple, la plupart des utilisateurs n'ont pas de garde activé, mais chaque demande que vous faites va au cache et interroge un certain identifiant utilisateur. voir s'il y a une protection. </li><li><strong>Erreurs commerciales/d'exploitation et de maintenance/développement</strong>, telles que la suppression accidentelle des données du cache et de la base de données. </li><li><strong>Attaque de demandes illégales par des pirates</strong>, par exemple, les pirates informatiques fabriquent délibérément un grand nombre de demandes illégales pour lire des données commerciales inexistantes. </li></ul><p><strong>Comment éviter la pénétration du cache ? </strong> Généralement, il existe trois méthodes. </p><ul><li>1. S'il s'agit d'une demande illégale, nous vérifierons les paramètres à l'entrée de l'API et filtrerons les valeurs illégales. </li><li>2. Si la base de données de requêtes est vide, nous pouvons définir une valeur nulle ou une valeur par défaut pour le cache. Cependant, si une demande d'écriture arrive, le cache doit être mis à jour pour garantir la cohérence du cache. Dans le même temps, le délai d'expiration approprié est finalement défini pour le cache. (Couramment utilisé en entreprise, simple et efficace) </li><li>3. Utilisez le filtre Bloom pour déterminer rapidement si les données existent. Autrement dit, lorsqu'une requête de requête arrive, elle juge d'abord si la valeur existe via le filtre Bloom, puis continue de vérifier si elle existe. </li></ul><blockquote><p>Principe du filtre Bloom : Il se compose d'un tableau bitmap avec une valeur initiale de 0 et de N fonctions de hachage. Effectuez N algorithmes de hachage sur une clé pour obtenir N valeurs. Hachez ces N valeurs dans le tableau de bits et définissez-les sur 1. Puis lors de la vérification, si ces positions spécifiques sont toutes à 1, alors filtrage Bloom Le serveur détermine que la clé existe. . </p></blockquote><h3 data-id="heading-21">4.2 Problème de snowrun du cache</h3><p><strong>Cache snowrun : </strong> fait référence au délai d'expiration d'une grande quantité de données dans le cache, et les données de requête sont énormes, et les requêtes accèdent directement à la base de données, provoquant une pression excessive sur la base de données et même des temps d'arrêt. </p><ul><li>Les chutes de neige dans le cache sont généralement causées par l'expiration d'une grande quantité de données en même temps. Pour cette raison, elles peuvent être résolues en définissant le délai d'expiration de manière uniforme, c'est-à-dire en rendant le délai d'expiration relativement discret. Si vous utilisez une valeur fixe plus grande + une valeur aléatoire plus petite, 5 heures + 0 à 1800 secondes. </li><li>Un échec de Redis peut également provoquer des chutes de neige dans le cache. Cela nécessite la construction d'un cluster haute disponibilité Redis. </li></ul><h3 data-id="heading-22">4.3 Problème de panne de cache</h3><p><strong> Panne de cache : </strong> fait référence au moment où la clé du hotspot expire à un certain moment, et il se trouve qu'il y a un grand nombre de demandes simultanées pour cette clé à ce moment, donc un un grand nombre de requêtes sont atteintes dans la base de données. </p><p>La panne du cache semble un peu similaire. En fait, la différence entre eux est que le crash du cache signifie que la base de données est soumise à une pression excessive, voire en panne, et qu'elle est simplement due à un grand nombre de requêtes simultanées au niveau de la base de données. On peut considérer que la panne est un sous-ensemble du cache snowrun. Certains articles estiment que la différence entre les deux réside dans le fait que la panne vise un certain cache de touches de raccourci, tandis que Xuebeng cible de nombreuses clés. </p><p>Il existe deux solutions : </p><ul><li><strong>1. Utilisez le schéma de verrouillage mutex</strong>. Lorsque le cache échoue, au lieu de charger immédiatement les données de la base de données, vous utilisez d'abord certaines commandes d'opération atomiques avec un retour réussi, telles que (setnx de Redis) pour fonctionner. En cas de succès, chargez les données de la base de données et configurez le cache. Sinon, essayez à nouveau de récupérer le cache. </li><li><strong>2. "N'expire jamais"</strong> signifie qu'aucun délai d'expiration n'est défini, mais lorsque les données du hotspot sont sur le point d'expirer, le thread asynchrone se met à jour et définit le délai d'expiration. </li></ul><h2 data-id="heading-23">5. Quel est le problème de touche de raccourci et comment résoudre le problème de touche de raccourci</h2><p><strong>Qu'est-ce que la touche de raccourci</strong> ? Dans Redis, nous appelons les touches à fréquence d'accès élevée comme touches de raccourci. </p><p>Si une demande pour une certaine clé de hotspot est envoyée à l'hôte du serveur, en raison d'un volume de requêtes particulièrement important, cela peut entraîner des ressources hôte insuffisantes ou même des temps d'arrêt, affectant ainsi les services normaux. </p><p><img src="https://img.php.cn/upload/image/681/859/235/163150190722212Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" title="163150190722212Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" alt="1Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p><p>Et comment la clé de hotspot est-elle générée ? Il y a deux raisons principales : </p><blockquote><ul><li>Les données consommées par les utilisateurs sont bien supérieures aux données produites, comme les ventes flash, les actualités brûlantes et d'autres scénarios où il y a plus de lecture et moins d'écriture. </li><li>Le partage des demandes est concentré, dépassant les performances d'un seul serveur Redi. Par exemple, les clés de nom fixe et les hachages tombent sur le même serveur, et la quantité d'accès instantané est énorme, dépassant le goulot d'étranglement de la machine et provoquant des problèmes de touches de raccourci. </li></ul></blockquote><p>Alors, comment identifier les raccourcis clavier dans le développement quotidien ? </p><blockquote><ul><li>Déterminez quelles touches de raccourci sont basées sur l'expérience ; </li><li>Rapport de statistiques sur les clients </li><li>Rapport à la couche d'agent de service</li></ul></blockquote><p>Comment résoudre le problème de touche de raccourci ? </p><blockquote><ul><li>Extension du cluster Redis : ajoutez des copies de fragments pour équilibrer le trafic de lecture ; </li><li>distribuez les touches de raccourci à différents serveurs ; </li><li>utilisez le cache de deuxième niveau, c'est-à-dire le cache local JVM, pour réduire les demandes de lecture Redis. </li></ul></blockquote><h2 data-id="heading-24">6. Stratégie d'expiration Redis et stratégie d'élimination de la mémoire</h2><p><img src="https://img.php.cn/upload/image/196/230/831/163150191159182Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" title="163150191159182Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)" alt="1Résumé et partage de 20 questions dentretien classiques sur Redis (avec analyse des réponses)"/></p><h3 data-id="heading-25">6.1 Stratégie d'expiration Redis</h3><p>Nous sommes là<code>set key
的时候,可以给它设置一个过期时间,比如expire key 60
. Spécifiez que cette clé expirera après 60 secondes. Comment Redis la gérera-t-il après 60 secondes ? Introduisons d'abord plusieurs stratégies d'expiration : Chaque clé avec un délai d'expiration doit créer une minuterie, et la clé sera effacée immédiatement lorsque le délai d'expiration est atteint. Cette stratégie peut immédiatement effacer les données expirées et est très économe en mémoire ; cependant, elle occupera une grande quantité de ressources CPU pour traiter les données expirées, affectant ainsi le temps de réponse et le débit du cache.
Seulement lors de l'accès à une clé, il sera jugé si la clé a expiré, et elle sera effacée si elle expire. Cette stratégie peut économiser au maximum les ressources du processeur, mais elle est très peu respectueuse de la mémoire. Dans des cas extrêmes, un grand nombre de clés expirées ne seront plus accessibles, ne seront donc pas effacées et occuperont une grande quantité de mémoire.
À chaque fois, un certain nombre de clés dans le dictionnaire d'expiration d'un certain nombre de bases de données seront analysées et les clés expirées seront effacées. Cette stratégie est un compromis entre les deux premières. En ajustant l'intervalle de temps des analyses planifiées et la consommation de temps limitée de chaque analyse, l'équilibre optimal entre les ressources CPU et mémoire peut être atteint dans différentes circonstances.
Le dictionnaire expire enregistrera les données d'heure d'expiration de toutes les clés avec une heure d'expiration définie, où clé est un pointeur vers une clé dans l'espace clé et valeur est l'heure d'expiration représentée par l'horodatage UNIX de la clé avec une précision de la milliseconde. L'espace clé fait référence à toutes les clés enregistrées dans le cluster Redis.
Redis utilise à la fois l'expiration paresseuse et l'expiration périodiquedeux stratégies d'expiration.
Mais si la suppression régulière manque un grand nombre de clés expirées, la suppression paresseuse ne sera pas utilisée. Il y aura beaucoup de clés expirées accumulées dans la mémoire, ce qui provoquera directement l'explosion de la mémoire. Ou parfois, lorsque le volume d'activité augmente, les clés Redis sont beaucoup utilisées, la mémoire n'est tout simplement pas suffisante et le responsable de l'exploitation et de la maintenance oublie d'augmenter la mémoire. Redis pourrait-il raccrocher comme ça ? Non! Redis se protège avec 8 stratégies d'élimination de mémoire ~
- volatile-lru : lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites, utilisez LRU (la moins récemment utilisée) à partir de la clé avec un délai d'expiration set ) algorithme d'élimination ;
- allkeys-lru : lorsque la mémoire est insuffisante pour accueillir les données nouvellement écrites, l'algorithme LRU (le moins récemment utilisé) est utilisé pour l'élimination de toutes les clés.
- volatile-lfu : nouvellement ajouté dans la version 4.0, lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites, l'algorithme LFU est utilisé pour supprimer les clés parmi les clés expirées.
- allkeys-lfu : Nouveau dans la version 4.0, lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites, l'algorithme LFU est utilisé pour éliminer de toutes les clés
- volatile-random : Lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites ; données nouvellement écrites, de Dans la clé avec un délai d'expiration défini, les données sont éliminées de manière aléatoire ;.
- allkeys-random : lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites, les données sont éliminées de manière aléatoire de toutes les clés.
- volatile-ttl : Lorsque la mémoire n'est pas suffisante pour accueillir les données nouvellement écrites, la clé avec un délai d'expiration défini sera éliminée en fonction du délai d'expiration, et plus la date d'expiration sera éliminée en premier
- noeviction : La stratégie par défaut, lorsque la mémoire est insuffisante Pour accueillir les données nouvellement écrites, la nouvelle opération d'écriture signalera une erreur.
Lorsque nous parlons de Redis, nous pensons naturellement au cache. Les sites Web de taille moyenne et grande au pays et à l'étranger sont indissociables du cache. Une utilisation raisonnable du cache, telle que la mise en cache des données des points d'accès, peut non seulement améliorer la vitesse d'accès du site Web, mais également réduire la pression sur la base de données. De plus, par rapport à Memcached, Redis fournit également des structures de données riches et des mécanismes de persistance tels que RDB et AOF, qui sont parmi les plus puissants.
Dans les applications Internet d'aujourd'hui, il existe différents classements, tels que les classements mensuels des ventes des sites de commerce électronique, les classements des cadeaux des applications sociales, les classements des votes des mini-programmes, etc. Le type zset
data fourni par Redis peut implémenter ces classements complexes.
Par exemple, si les utilisateurs mettent en ligne des vidéos tous les jours, la liste de classement des likes peut être conçue comme ceci :
zadd user:ranking:2021-03-03 Jay 3
zincrby user:ranking:2021-03-03 Jay 1
zrem user:ranking:2021-03-03 John
zrevrangebyrank user:ranking:2021-03-03 0 2
各大网站、APP应用经常需要计数器的功能,如短视频的播放数、电商网站的浏览数。这些播放数、浏览数一般要求实时的,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
如果一个分布式Web服务将用户的Session信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。实际上,可以使用Redis将用户的Session进行集中管理,每次用户更新或者查询登录信息都直接从Redis中集中获取。
几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适保存 这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。
用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。
Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
Redis提供了RDB和AOF两种持久化机制,它持久化文件加载流程如下:
RDB,就是把内存数据以快照的形式保存到磁盘上。
什么是快照?可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。
RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb
文件,Redis 重启的时候,通过加载dump.rdb
文件来恢复数据。RDB触发机制主要有以下几种:
RDB 的优点
RDB缺点
AOF (ajouter uniquement le fichier) Persistance, utilisation du formulaire de journal pour enregistrer chaque opération d'écriture, ajouter au fichier et réexécuter le fichier AOF lorsque commande de redémarrage pour récupérer les données. Il résout principalement le problème en temps réel de la persistance des données. La valeur par défaut n'est pas activée.
Le flux de travail d'AOF est le suivant :
Avantages d'AOF
Inconvénients d'AOF
Nous utilisons Redis dans le projet, et nous ne déploierons certainement pas le service Redis à un seul moment. Car une fois le déploiement en point unique interrompu, il n’est plus disponible. Afin d'obtenir une haute disponibilité, une pratique courante consiste à copier plusieurs copies de la base de données et à les déployer sur différents serveurs. Si l'une d'entre elles tombe en panne, elle peut continuer à fournir des services. Redis dispose de trois modes de déploiement pour atteindre une haute disponibilité : Mode maître-esclave, mode sentinelle et mode cluster.
En mode maître-esclave, Redis déploie plusieurs machines, avec un nœud maître responsable des opérations de lecture et d'écriture et un nœud esclave responsable uniquement des opérations de lecture. Les données du nœud esclave proviennent du nœud maître. Le principe de mise en œuvre est le mécanisme de réplication maître-esclave
La réplication maître-esclave comprend la réplication complète et la réplication incrémentielle. Généralement, lorsque l'esclave commence à se connecter au maître pour la première fois, ou lorsque l'on considère que c'est la première fois qu'il se connecte, la copie complète est utilisée. Le processus de copie complète est le suivant :
Après redis2.8. version, il a été utilisé psync pour remplacer sync, car la commande sync consomme des ressources système et psync est plus efficace.
Une fois l'esclave entièrement synchronisé avec le maître, si les données sur le maître sont à nouveau mises à jour, la réplication incrémentielle sera déclenchée.
Lorsque les données augmentent ou diminuent sur le nœud maître, replicationFeedSalves()
函数,接下来在 Master节点上调用的每一个命令会使用replicationFeedSlaves()
sera déclenché pour se synchroniser avec le nœud esclave. Avant d'exécuter cette fonction, le nœud maître déterminera si la commande exécutée par l'utilisateur a des mises à jour des données. S'il y a une mise à jour des données et que le nœud esclave n'est pas vide, cette fonction sera exécutée. La fonction de cette fonction est : Envoyer la commande exécutée par l'utilisateur à tous les nœuds esclaves, et laisser le nœud esclave l'exécuter. Le processus est le suivant :
En mode maître-esclave, une fois que le nœud maître ne peut pas fournir de services en raison d'une panne, il est nécessaire de promouvoir manuellement le nœud esclave en nœud maître, et à en même temps, informez l'application de mettre à jour l'adresse du nœud maître. De toute évidence, cette méthode de gestion des pannes est inacceptable dans la plupart des scénarios commerciaux. Redis a officiellement fourni l'architecture Redis Sentinel depuis la version 2.8 pour résoudre ce problème.
Mode Sentinel, un système Sentinel composé d'une ou plusieurs instances Sentinel, qui peut surveiller tous les nœuds maîtres et nœuds esclaves Redis, et lorsque le nœud maître surveillé entre dans l'état hors ligne, supprime automatiquement le maître hors ligne Un nœud esclave sous le serveur est mis à niveau vers un nouveau nœud maître. Cependant, si un processus sentinelle surveille un nœud Redis, des problèmes peuvent survenir (Problème à point unique). Par conséquent, plusieurs sentinelles peuvent être utilisées pour surveiller les nœuds Redis, et chaque sentinelle se surveillera également mutuellement.
En termes simples, le mode sentinelle a trois fonctions :
Supposons que le serveur principal soit en panne et que Sentinel 1 détecte ce résultat en premier. Le système n'effectuera pas immédiatement le processus de basculement. C'est simplement que Sentinel 1 croit subjectivement que le serveur principal est indisponible. Lorsque les sentinelles suivantes détectent également que le serveur principal est indisponible et que le nombre atteint une certaine valeur, un vote aura lieu entre les sentinelles. Le résultat du vote sera initié par une sentinelle pour effectuer une opération de basculement. Une fois le changement réussi, chaque sentinelle utilisera le mode publication-abonnement pour basculer le serveur esclave qu'elle surveille vers l'hôte. Ce processus est appelé objectif hors ligne. De cette façon, tout est transparent pour le client. Le mode de fonctionnement de Sentinel est le suivant : Chaque Sentinel envoie une commande PING au maître, à l'esclave et aux autres instances Sentinel qu'il connaît une fois par seconde. Si le temps écoulé depuis la dernière réponse valide à la commande PING dépasse la valeur spécifiée par l'option down-after-milliseconds, l'instance sera marquée comme subjectivement hors ligne par Sentinel. Si un Maître est marqué comme subjectif hors ligne, toutes les Sentinelles qui surveillent ce Maître doivent confirmer une fois par seconde que le Maître est effectivement entré dans l'état subjectif hors ligne. Lorsqu'un nombre suffisant de Sentinelles (supérieur ou égal à la valeur spécifiée dans le fichier de configuration) confirment que le Maître est effectivement entré dans un état subjectif hors ligne dans la plage de temps spécifiée, le Maître sera marqué comme objectivement hors ligne. Dans des circonstances normales, chaque Sentinelle enverra des commandes INFO à tous les maîtres et esclaves qu'elle connaît une fois toutes les 10 secondes. Lorsque le maître est marqué comme objectivement hors ligne par Sentinel, la fréquence à laquelle Sentinel envoie des commandes INFO à tous les esclaves du maître hors ligne passera d'une fois toutes les 10 secondes à une fois toutes les secondes S'il n'y en a pas assez Sentinelles doivent accepter Si le maître est hors ligne, le statut hors ligne objectif du maître sera supprimé ; si le maître renvoie à nouveau une réponse valide à la commande PING de Sentinel, le statut hors ligne subjectif du maître sera supprimé. Le mode Sentinelle est basé sur le mode maître-esclave et réalise la séparation en lecture et en écriture. Il peut également basculer automatiquement et la disponibilité du système est plus élevée. Cependant, les données stockées dans chaque nœud sont les mêmes, ce qui gaspille de la mémoire et n'est pas facile à développer en ligne.
Par conséquent, le cluster Cluster a vu le jour. Il a été ajouté dans Redis 3.0 et a implémenté le stockage distribué de Redis. Segmentez les données, ce qui signifie stocker différents contenus sur chaque nœud Redis pour résoudre le problème de l'expansion en ligne. De plus, il offre également des capacités de réplication et de basculement. Un cluster Redis se compose de plusieurs nœuds Comment chaque nœud communique-t-il entre eux ? Grâce au Protocole Gossip ! Le cluster Redis Cluster communique via le protocole Gossip. Les nœuds échangent en continu des informations, notamment les pannes de nœud, l'adhésion de nouveaux nœuds, les informations de changement de nœud maître-esclave, les informations d'emplacement, etc. Les messages de potins couramment utilisés sont divisés en quatre types : ping, pong, rencontre et échec. Spécialement, chaque nœud communique avec d'autres nœuds via le bus cluster. Lors de la communication, utilisez un numéro de port spécial, c'est-à-dire le numéro de port du service externe plus 10 000. Par exemple, si le numéro de port d'un nœud est 6379, alors le numéro de port qu'il utilise pour communiquer avec d'autres nœuds est 16379. La communication entre les nœuds utilise un protocole binaire spécial. Puisqu'il s'agit d'un stockage distribué, l'algorithme distribué utilisé par le cluster Cluster est Consistent Hash ? Non, c'est l'algorithme Hash Slot. Algorithme de slotL'ensemble de la base de données est divisé en 16384 slots (slots). Chaque paire clé-valeur entrant dans Redis est hachée en fonction de la clé et attribuée à l'un de ces 16384 slots. La carte de hachage utilisée est également relativement simple. Elle utilise l'algorithme CRC16 pour calculer une valeur de 16 bits, puis modulo 16384. Chaque clé de la base de données appartient à l'un de ces 16 384 emplacements, et chaque nœud du cluster peut gérer ces 16 384 emplacements. Chaque nœud du cluster est responsable d'une partie des emplacements de hachage. Par exemple, le cluster actuel a les nœuds A, B et C, et le nombre d'emplacements de hachage sur chaque nœud = 16384/3, alors il y a : Dans le cluster Redis Cluster, il faut s'assurer que 16384 emplacements correspondent. Tous les nœuds fonctionnent normalement. Si un nœud tombe en panne, l'emplacement dont il est responsable deviendra également invalide et l'ensemble du cluster ne fonctionnera pas. Ainsi, afin d'assurer une haute disponibilité, le cluster Cluster introduit la réplication maître-esclave, et un nœud maître correspond à un ou plusieurs nœuds esclaves. Lorsque d'autres nœuds maîtres envoient une requête ping à un nœud maître A, si plus de la moitié des nœuds maîtres communiquent avec A expirent, alors le nœud maître A est considéré comme étant en panne. Si le nœud maître tombe en panne, le nœud esclave sera activé. Sur chaque nœud de Redis, il y a deux choses, l'une est l'emplacement et sa plage de valeurs est 016383. L'autre est le cluster, qui peut être compris comme un plug-in de gestion de cluster. Lorsque la clé à laquelle nous accédons arrive, Redis obtiendra une valeur de 16 bits basée sur l'algorithme CRC16, puis prendra le résultat modulo 16384. Chaque clé dans Jiangzi correspond à un emplacement de hachage numéroté entre 016383. Utilisez cette valeur pour trouver le nœud correspondant à l'emplacement correspondant, puis accédez automatiquement au nœud correspondant pour les opérations d'accès. Bien que les données soient stockées séparément sur différents nœuds, pour le client, l'ensemble du cluster est considéré comme un tout. Le client se connecte à n’importe quel nœud et ressemble à l’exploitation d’une seule instance de Redis. Lorsque la clé actionnée par le client n'est pas affectée au bon nœud, Redis renverra l'instruction de redirection et pointera finalement vers le bon nœud. C'est un peu comme le saut de redirection 302 de la page du navigateur. Le cluster Redis atteint une haute disponibilité Lorsqu'un nœud du cluster tombe en panne, failover est utilisé pour garantir que le cluster peut fournir des services externes normaux. Le cluster Redis réalise la découverte de pannes via des messages ping/pong. Cet environnement comprend subjectif hors ligne et objectif hors ligne. Hors ligne subjectif : Un nœud pense qu'un autre nœud n'est pas disponible, c'est-à-dire qu'il est dans un état hors ligne. Cet état n'est pas la détermination finale du défaut et ne peut représenter que l'opinion d'un nœud, et il peut y avoir une erreur de jugement. Objectif hors ligne : Indique qu'un nœud est véritablement hors ligne. Plusieurs nœuds du cluster pensent que le nœud est indisponible, parvenant ainsi à un consensus. Si le nœud maître détenant l'emplacement tombe en panne, un basculement doit être effectué pour le nœud. Le processus est le suivant : Récupération après panne : Une fois la panne découverte, si le nœud hors ligne est le nœud maître, vous devez choisir l'un de ses nœuds esclaves pour le remplacer afin d'assurer le niveau élevé disponibilité du cluster. Le processus est le suivant : Le verrouillage distribué est une implémentation d'un verrou qui contrôle différents processus dans un système distribué pour accéder conjointement aux ressources partagées. Les scénarios commerciaux tels que passer des commandes flash, récupérer des enveloppes rouges, etc. nécessitent tous l'utilisation de verrous distribués. Redis est souvent utilisé comme verrou distribué dans nos projets. 选了Redis分布式锁的几种实现方法,大家来讨论下,看有没有啥问题哈。 如果执行完 笔者看过有开发小伙伴是这么实现分布式锁的,但是这种方案也有这些缺点: 这个方案可能存在这样的问题: 在这里,判断当前线程加的锁和释放锁是不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁。 一般也是用lua脚本代替。lua脚本如下: 这种方式比较不错了,一般情况下,已经可以使用这种实现方式。但是存在锁过期释放了,业务还没执行完的问题(实际上,估算个业务处理的时间,一般没啥问题了)。 分布式锁可能存在锁过期释放,业务没执行完的问题。有些小伙伴认为,稍微把锁过期时间设置长一些就可以啦。其实我们设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。 当前开源框架Redisson就解决了这个分布式锁问题。我们一起来看下Redisson底层原理是怎样的吧: 只要线程一加锁成功,就会启动一个 Redis一般都是集群部署的,假设数据在主从同步过程,主节点挂了,Redis分布式锁可能会有哪些问题呢?一起来看些这个流程图: 如果线程一在Redis的master节点上拿到了锁,但是加锁的key还没同步到slave节点。恰好这时,master节点发生故障,一个slave节点就会升级为master节点。线程二就可以获取同个key的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。 为了解决这个问题,Redis作者 antirez提出一种高级的分布式锁算法:Redlock。Redlock核心思想是这样的: 搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。 我们假设当前有5个Redis master节点,在5台服务器上面运行这些Redis实例。 RedLock的实现步骤:如下 Les étapes simplifiées sont les suivantes : Qu'est-ce que la double suppression différée ? L'organigramme est le suivant : Supprimez d'abord le cache puis mettez à jour la base de données Dormez pendant un moment (par exemple 1 seconde) et supprimez à nouveau le cache. Combien de temps faut-il habituellement pour dormir pendant un certain temps ? Sont-ils tous 1 seconde ? Ce temps de veille = le temps nécessaire pour lire les données de la logique métier + quelques centaines de millisecondes. Afin de garantir la fin de la demande de lecture, la demande d'écriture peut supprimer les données sales mises en cache qui peuvent être apportées par la demande de lecture. Cette solution n'est pas mauvaise. Ce n'est que pendant la période de sommeil (par exemple, seulement 1 seconde) qu'il peut y avoir des données sales, et les entreprises générales l'accepteront. Mais que se passe-t-il si la suppression du cache échoue une deuxième fois ? Les données du cache et de la base de données peuvent toujours être incohérentes, n'est-ce pas ? Que diriez-vous de définir un délai d’expiration naturel pour la clé et de la laisser expirer automatiquement ? L’entreprise doit-elle accepter des incohérences de données pendant la période d’expiration ? Ou existe-t-il une autre meilleure solution ? En raison d'une double suppression retardée, la deuxième étape de suppression du cache peut échouer, entraînant une incohérence des données. Vous pouvez utiliser cette solution pour optimiser : si la suppression échoue, supprimez-la simplement quelques fois de plus pour vous assurer que la suppression du cache est réussie. Vous pouvez donc introduire un mécanisme de nouvelle tentative de suppression du cache demande d'écriture pour mettre à jour le base de données Le cache est dû à un certain Pour certaines raisons, la suppression a échoué Mettez la clé qui n'a pas pu être supprimée dans la file d'attente des messages Consommez le message dans la file d'attente des messages et obtenez la clé à supprimer Réessayez l'opération de suppression du cache réessayez le mécanisme de suppression du cache est correct, mais il provoquera de nombreuses intrusions dans le code métier. En fait, il peut également être optimisé de cette manière : éliminer les clés de manière asynchrone via le binlog de la base de données. Prenons MySQL comme exemple L'utilisation du multi-threading par Redis ne signifie pas qu'il abandonne complètement le monothreading. Redis utilise toujours un modèle monothread pour traiter les demandes des clients. Il utilise uniquement le multithreading pour gérer la lecture et l'écriture des données et l'analyse des protocoles. il utilise toujours un seul thread pour exécuter les commandes. 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. Redis implémente le mécanisme de transaction via un ensemble de commandes telles que MULTI, EXEC, WATCH. Les transactions prennent en charge l'exécution de plusieurs commandes à la fois, et toutes les commandes d'une transaction seront sérialisées. Pendant le processus d'exécution de la transaction, les commandes dans la file d'attente seront exécutées en série dans l'ordre et les demandes de commandes soumises par d'autres clients ne seront pas insérées dans la séquence de commandes d'exécution de la transaction. En bref, une transaction Redis est l'exécution séquentielle, unique et exclusived'une série de commandes dans une file d'attente. Le processus d'exécution des transactions dans Redis est le suivant : Redis est une base de données K-V en mémoire, qui utilise un hachage global pour enregistrer toutes les paires clé-valeur. Cette table de hachage est composée de plusieurs compartiments de hachage. L'élément d'entrée dans le compartiment de hachage stocke les pointeurs key et value, où *key pointe vers la clé réelle et *value pointe vers la valeur réelle. La vitesse de recherche des tables de hachage est très rapide, quelque peu similaire à HashMap en Java, ce qui nous permet de trouver rapidement des paires clé-valeur dans une complexité temporelle O(1). Tout d'abord, calculez la valeur de hachage via la clé, recherchez l'emplacement du compartiment de hachage correspondant, puis localisez l'entrée et recherchez les données correspondantes dans l'entrée. Qu'est-ce qu'une collision de hachage ? Conflit de hachage : la même valeur de hachage est calculée via différentes clés, ce qui donne le même compartiment de hachage. Afin de résoudre les conflits de hachage, Redis utilise Chain Hash. Le hachage en chaîne signifie que plusieurs éléments du même compartiment de hachage sont stockés dans une liste chaînée et qu'ils sont connectés tour à tour à l'aide de pointeurs. Certains lecteurs peuvent encore avoir des questions : les éléments de la chaîne de conflits de hachage ne peuvent être recherchés qu'un par un via des pointeurs puis exploités. Lorsqu'une grande quantité de données est insérée dans la table de hachage, plus il y aura de conflits, plus la liste chaînée des conflits sera longue et l'efficacité des requêtes sera réduite. Afin de maintenir l'efficacité, Redis effectuera une opération de rehachage sur la hash table, ce qui signifie ajouter des compartiments de hachage et réduire les conflits. Afin de rendre le rehachage plus efficace, Redis utilise également deux tables de hachage globales par défaut, une pour l'utilisation actuelle, appelée table de hachage principale, et une pour l'expansion, appelée table de hachage de sauvegarde. 18. Lors de la génération RDB, Redis peut-il gérer les requêtes d'écriture en même temps ? , Redis fournit deux instructions pour générer du RDB, à savoir save et bgsave. RESP présente principalement les avantages d'une mise en œuvre simple, d'une vitesse d'analyse rapide et d'une bonne lisibilité 20. Filtre Bloom Filtre Bloom. Qu'est-ce qu'un filtre bloom ? Un filtre Bloom est une structure de données qui prend très peu de place. Il se compose d'un long vecteur binaire et d'un ensemble de fonctions de mappage de hachage. Il est utilisé pour récupérer si un élément est dans un ensemble, l'efficacité spatiale et le temps de requête. Ils sont bien meilleurs que les algorithmes ordinaires. Les inconvénients sont un certain taux de mauvaise reconnaissance et des difficultés de suppression. Quel est le principe du filtre Bloom ? k , chaque élément de A est mappé à différentes positions dans un tableau B d'une longueur d'un bit, et les nombres binaires à ces positions sont tous définis sur 1. Si l'élément à vérifier est mappé par ces k fonctions de hachage et qu'il s'avère que les nombres binaires à ses k positions sont tous 1, cet élément appartient probablement à l'ensemble A. Au contraire, ne doit pas appartenir à l'ensemble A. . Regardons un exemple simple. Supposons que l'ensemble A comporte 3 éléments, à savoir {d1, d2, d3 Hash1. Mappez maintenant chaque élément de A à un tableau B de longueur 16 bits. Nous mappons maintenant d1. En supposant que Hash1(d1) = 2, nous changeons la grille avec l'indice 2 dans le tableau B en 1, comme suit : Nous mappons maintenant d2
Ensuite, nous mappons également d3
Par conséquent, nous devons confirmer si un élément dn est dans l'ensemble A. Il nous suffit de calculer l'indice d'index obtenu par Hash1 (dn). Tant qu'il est 0, cela signifie que cet élément n'est pas dans l'ensemble A. . Et si l'indice d'index est 1 ? Alors l’élément peut être un élément de A. Parce que vous voyez, les valeurs d'indice obtenues par d1 et d3 peuvent toutes deux être 1, ou elles peuvent être mappées par d'autres nombres. Le filtre Bloom a cet inconvénient : il y aura des faux positifs causés par une collision de hachage, là. est une erreur de jugement. Comment réduire cette erreur ? Nous ajoutons une autre fonction Hash2hash map. Supposons que Hash2(d1)=6, Hash2(d3)=8 ne seront pas en conflit, comme suit : Même s'il y a une erreur, nous pouvons trouver. , le filtre Bloom ne stocke pas les données complètes, il utilise simplement une série de fonctions de carte de hachage pour calculer la position, puis remplit le vecteur binaire. Si le nombre est grand, le filtre Bloom peut économiser beaucoup d'espace de stockage grâce à un très faible taux d'erreur, ce qui est assez rentable. Actuellement, les filtres Bloom disposent déjà de bibliothèques open source qui implémentent les implémentations correspondantes, telles que la et la bibliothèque de classes Algebird de Twitter, qui sont facilement disponibles, ou vous pouvez implémenter votre propre conception basée sur les Bitmaps fournis avec Redis. . Pour plus de connaissances sur 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!9.3 Mode cluster cluster
Communication des nœuds du cluster
Algorithme Hash Slot
Cluster Redis Cluster
Failover
10. Verrou distribué Redis ? Quels sont les points auxquels il faut prêter attention ?
10.1 命令setnx + expire分开写
if(jedis.setnx(key,lock_value) == 1){ //加锁
expire(key,100); //设置过期时间
try {
do something //业务请求
}catch(){
}
finally {
jedis.del(key); //释放锁
}
}
setnx
加锁,正要执行expire设置过期时间时,进程crash掉或者要重启维护了,那这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以分布式锁不能这么实现。10.2 setnx + value值是过期时间
long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间
String expiresStr = String.valueOf(expires);
// 如果当前锁不存在,返回加锁成功
if (jedis.setnx(key, expiresStr) == 1) {
return true;
}
// 如果锁已经存在,获取锁的过期时间
String currentValueStr = jedis.get(key);
// 如果获取到的过期时间,小于系统当前时间,表示已经过期
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
// 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间(不了解redis的getSet命令的小伙伴,可以去官网看下哈)
String oldValueStr = jedis.getSet(key_resource_id, expiresStr);
if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
// 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才可以加锁
return true;
}
}
//其他情况,均返回加锁失败
return false;
}
jedis.getSet()
,最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。10.3: set的扩展命令(set ex px nx)(注意可能存在的问题)
if(jedis.set(key, lock_value, "NX", "EX", 100s) == 1){ //加锁
try {
do something //业务处理
}catch(){
}
finally {
jedis.del(key); //释放锁
}
}
10.4 set ex px nx + 校验唯一随机值,再删除
if(jedis.set(key, uni_request_id, "NX", "EX", 100s) == 1){ //加锁
try {
do something //业务处理
}catch(){
}
finally {
//判断是不是当前线程加的锁,是才释放
if (uni_request_id.equals(jedis.get(key))) {
jedis.del(key); //释放锁
}
}
}
if redis.call('get',KEYS[1]) == ARGV[1] then
return redis.call('del',KEYS[1])
else
return 0
end;
11. 使用过Redisson嘛?说说它的原理
watch dog
看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。12. 什么是Redlock算法
13. Table de saut de Redis
14. Comment MySQL et Redis assurent-ils la cohérence des doubles écritures
14.1 Double suppression retardée ?
14.2 Mécanisme de nouvelle tentative de suppression du cache
14.3 Lire le biglog Le mécanisme de suppression asynchrone du cache
15 Pourquoi Redis a-t-il changé. au multi-thread après 6.0 ?
16. Parlons du mécanisme de transaction Redis
Commande
Description
EXEC
Exécuter toutes les commandes dans le bloc de transaction
DISCARD
Annuler la transaction et abandonner l'exécution de toutes les commandes dans le bloc de transaction
MULTI
Marquer le début d'un bloc de transaction
UNWATCH
Annuler La commande WATCH surveille toutes les touches.
WATCH
Clé de surveillance. Si la clé est modifiée par d'autres commandes avant l'exécution de la transaction, la transaction sera interrompue.
17. Comment gérer les conflits de hachage dans Redis
RESP, le nom anglais complet est Redis Serialization Protocol, qui est un ensemble de protocoles de sérialisation spécialement conçus pour redis. Ce protocole est en fait apparu dans la version 1.2 de redis. mais ce n'est qu'avec Redis2.0 qu'il est finalement devenu la norme pour le protocole de communication Redis.
pénétration du cache
, nous pouvons utiliser le