Maison  >  Article  >  base de données  >  Quelle est la stratégie de mise à jour pour la cohérence de la base de données MySQL et du cache Redis ?

Quelle est la stratégie de mise à jour pour la cohérence de la base de données MySQL et du cache Redis ?

WBOY
WBOYavant
2023-05-27 15:11:24739parcourir

    1. Stratégie de mise à jour

    1 S'il y a des données dans Redis, elles doivent être identiques à la valeur. dans la base de données.

    2. S'il n'y a aucune donnée dans Redis, Redis doit être mis à jour de manière synchrone avec la dernière valeur de la base de données.

    2. Cache de lecture et d'écriture

    1. Stratégie d'écriture directe synchrone

    L'écriture dans la base de données écrit également les données dans le cache Redis, le cache et base de données de manière synchrone Cohérent ; pour le cache en lecture-écriture, pour garantir la cohérence des données dans le cache et la base de données, il est nécessaire d'assurer une stratégie d'écriture directe synchrone.

    2. Stratégie d'écriture lente asynchrone

    Lors de certaines opérations commerciales, après la mise à jour des données MySQL, la synchronisation des données Redis est autorisée après une certaine période de temps, comme les systèmes logistiques .

    Lorsqu'une situation anormale se produit, l'action qui a échoué doit être à nouveau corrigée et réécrite à l'aide de RabbitMQ ou Kafka.

    3. Vérifiez à nouveau la stratégie de verrouillage

    Plusieurs threads interrogent ces données dans la base de données en même temps, nous pouvons alors utiliser une interaction sur la première demande de données de requête. Utilisez le verrou pour le verrouiller.

    Les autres threads attendront d'atteindre ce point et ne pourront pas obtenir le verrou, attendront que le premier thread interroge les données, puis les mettront en cache.

    Les discussions ultérieures arrivent et découvrent qu'il existe déjà un cache, elles vont donc directement au cache.

    public String get(String key){
        // 从Redis缓存中读取
        String value = redisTemplate.get(key);
    
        if(value != null){
            return value;
        }
    
        synchronized (RedisTest.class){
            // 重新尝试从Redis缓存中读取
            value = redisTemplate.get(key);
            if(value != null){
                return value;
            }
    
            // 从MySQL数据库中查询
            value = studentDao.get(key);
            // 写入Redis缓存
            redisTemplate.setnx(key,value,time);
            return value;
        }
    }

    4. Stratégie de mise à jour pour la cohérence de la base de données et du cache

    1 Mettez d'abord à jour la base de données, puis mettez à jour Redis

    Si vous faites preuve de bon sens, Cela devrait être le cas, non ? Alors, quel est le problème dans ce cas ?

    Que se passe-t-il si une exception se produit avant la mise à jour de Redis après une mise à jour réussie de la base de données ?

    La base de données est incohérente avec les données mises en cache dans Redis.

    2. Mettez d'abord à jour le cache, puis mettez à jour la base de données

    Dans les situations multithread, il y aura des problèmes.

    Par exemple

    • Thread 1 met à jour redis = 200; 2 Mise à jour redis = 100;

    • Thread 2 mise à jour MySQL = 100 ;

    • Le résultat est, Redis=100, MySQL=200 ; Oh mon Dieu !

    • 3. Supprimez d'abord le cache, puis mettez à jour la base de données
    • Thread 1 supprime les données du cache Redis, puis met à jour la base de données MySQL

      n'a pas attendu ; la mise à jour MySQL doit être terminée. , le thread 2 vient lire les données mises en cache ;
    • Cependant, la base de données MySQL n'a pas été mise à jour pour le moment, le thread 2 lit l'ancienne valeur dans MySQL, puis le thread 2 écrit l'ancienne. valeur à Redis comme cache de données ;
    Après que le thread 1 ait mis à jour les données MySQL, il a constaté qu'il y avait déjà des données dans Redis, qui avaient été supprimées auparavant, donc je ne les mettrai pas à jour

    C'est fini ; .

    Double suppression retardée

    La double suppression retardée peut résoudre le problème ci-dessus, à condition que le temps de veille soit supérieur au temps nécessaire au thread 2 pour lire les données, puis les écrire dans le cache. C'est-à-dire que l'opération de nettoyage du cache secondaire du thread 1 doit être effectuée après que le thread 2 ait écrit dans le cache, afin de garantir que les données du cache Redis sont à jour.

    /**
     * 延时双删
     * @autor 哪吒编程
     */
    public void deleteRedisData(Student stu){
        // 删除Redis中的缓存数据
        jedis.del(stu);
    
        // 更新MySQL数据库数据
        studentDao.update(stu);
    
        // 休息两秒
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        // 删除Redis中的缓存数据
        jedis.del(stu);
    }

    Le plus gros problème de la double suppression retardée est le sommeil. Aujourd'hui, où l'efficacité est reine, il vaut mieux ne pas utiliser le sommeil.

    Je pense que vous êtes lent même si vous ne dormez pas, mais vous vous endormez quand même... 🎜🎜#

    Le fil de discussion 1 met d'abord à jour la base de données, puis supprime le cache Redis ;

    Le thread 2 lance une requête avant que le thread 1 ne supprime le cache Redis et n'obtienne le résultat non supprimé du cache Redis

    # ; 🎜🎜#Thread 1 supprime uniquement les données du cache Redis pour le moment ;

    Comment résoudre cette situation ?

      Présentation du middleware de messages pour résoudre la bataille, examinons-la à nouveau en détail.
    1. Mettre à jour la base de données
    2. La base de données écrit les informations sur l'opération dans le journal binlog ; ##🎜 🎜#
    3. Le programme d'abonnement extrait la clé et les données

    Tentative de suppression de l'opération de cache et a constaté que la suppression a échoué ;

    #🎜🎜 #

    Envoyer ces informations de données au middleware de message ;

    1. Récupérez les données du middleware de message et ré-opérer; #🎜 🎜#

    2. 5 Résumé
    3. Nezha recommande la quatrième méthode, qui consiste à mettre à jour d'abord la base de données, puis à supprimer le cache.

    4. Les défauts de la méthode ① et de la méthode ② sont trop évidents pour être pris en compte
    5. Le sommeil dans la méthode ③ est toujours un casse-tête

      La méthode ④ est cependant une solution plus globale ; , les coûts d'apprentissage et les coûts de maintenance augmentent en raison de l'ajout d'un middleware de messages.

    6. 5. Principe de fonctionnement de la réplication maître-esclave MySQL
    7. 1. Lorsque les données sur le serveur maître changent, alors Écrivez les modifications dans le fichier journal des événements binaires ;

      2. Le serveur esclave salve détectera le journal binaire sur le serveur maître dans un certain intervalle de temps pour détecter s'il a changé, #🎜 🎜## 🎜🎜#S'il est détecté que le journal des événements binaires du serveur maître a changé, un thread d'E/S sera démarré pour demander le journal des événements binaires maître
    8. 3. le serveur maître lancera un thread de vidage pour lui envoyer les journaux d'événements binaires ;

      4 L'esclave enregistre le journal des événements binaires reçu du serveur dans son propre fichier journal de relais local ; 🎜🎜#

      5. Le serveur esclave Salve démarrera SQL Thread pour lire le journal binaire du journal du relais et le relire localement pour rendre ses données cohérentes avec celles du serveur principal.

      6 Enfin, le thread d'E/S et le thread SQL entreront. l'état de sommeil. En attendant d'être réveillé la prochaine fois.

    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!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer