Maison  >  Article  >  base de données  >  Comment synchroniser les données MySQL avec le cache Redis

Comment synchroniser les données MySQL avec le cache Redis

王林
王林avant
2023-05-27 09:08:101348parcourir

1 Mysql vérifie les données puis les écrit de manière synchrone sur Redis

Inconvénient 1 : cela entraînera un retard dans l'interface, car l'écriture synchrone sur Redis elle-même a un retard et doit être réessayée si l'écriture Redis échoue, elle doit être réessayée. Réessayez, cela prendra plus de temps.

Inconvénient 2 : Pas de découplage. Si Redis plante, le fil sera directement bloqué.

Inconvénient 3 : Si quelqu'un est la base de données, elle ne peut pas être synchronisée à moins que le Redis correspondant ne soit supprimé manuellement, mais le processus de suppression de Redis a également. Décalage horaire

2 Mysql vérifie les données et synchronise Redis dans le thread consommateur en envoyant MQ

Inconvénient 1 : Il y a plus de couches de MQ, ce qui signifie qu'il y a une forte probabilité de provoquer des problèmes de délai de synchronisation.

Inconvénient 2 : Il nécessite Empêcher la disponibilité de MQ

Inconvénient 3 : Si un humain est la base de données, elle ne peut pas être synchronisée

Avantage 1 : Cela peut réduire considérablement le problème du retour retardé de l'interface

Avantage 2 : MQ lui-même dispose d'un mécanisme de nouvelle tentative , aucun travail manuel n'est requis Allez écrire le code de nouvelle tentative

Avantage 3 : Découplage, séparant complètement la requête Mysql et la synchronisation Redis sans interférer les unes avec les autres

3 Abonnez-vous au fichier Mysql Binlog (peut être fait avec l'aide de Canal)

CanalServer se déguisera en bibliothèque esclave MysqlServer. Abonnez-vous au fichier Binlog de la bibliothèque principale MysqlServer

Canal configurera le message MQ correspondant (RabbitMQ, RocketMQ, Kafka) lors de son démarrage Lorsqu'il détectera des changements dans le Binlog. fichier, il convertira l'instruction SQL modifiée au format json et l'utilisera comme message. Le contenu est envoyé à MQ

Dans le projet, tant que vous surveillez le MQ correspondant, vous pouvez obtenir le contenu des modifications de Binlog. les données ont un type d'opération clair (CURD) et les données correspondantes. Synchronisez simplement les données correspondantes avec redis

Inconvénient 1 : l'ensemble du processus opérationnel d'abonnement au canal à Binlog est monothread, donc face à une concurrence ultra-élevée, les performances peuvent ne pas être excellentes. Vous pouvez déployer plusieurs canaux et plusieurs consommateurs, mais vous devez faire attention pour éviter les problèmes de consommation répétés et effectuer une vérification d'idempotence

Avantage 1 : Même si la base de données est modifiée manuellement, elle sera surveillée et synchronisée

Avantage 2 : Synchronisation asynchrone , il n'y aura pas de délai supplémentaire dans le retour de l'interface

4 Double suppression retardée

Avant d'exécuter le SQL modifié, supprimez d'abord les données Redis

Exécutez la mise à jour SQL

Délai pendant un certain temps

Supprimez à nouveau les données Redis

// 延迟双删伪代码
deleteRedisCache(key);   // 删除redis缓存
updateMysqlSql(obj);        // 更新mysql
Thread.sleep(100);           // 延迟一段时间
deleteRedisCache(key);   // 再次删除该key的缓存

Inconvénients : ce délai est difficile à contrôler. La durée du délai est difficile à évaluer

Si vous n'utilisez pas la double suppression différée, vous supprimez simplement le cache puis modifiez les données MySQL. Quels problèmes surviendront s’il n’y a que ces deux étapes ?

5. Requête unique, un seul thread ne pose pas de problème, mais des problèmes se produiront en cas de concurrence élevée et de multithreading

6 Si le thread Thread1 souhaite mettre à jour les données, le thread Thread1 nettoiera Redis à ce moment-là

7. cette fois, le thread Thread2 arrive, mais Thread1 n'a pas fini de mettre à jour mysql

8. La requête de Thread2 sur redis doit être nulle à ce moment-là, Thread2 vérifiera mysql, puis écrira les données trouvées dans le cache

9. n'a pas eu le temps de modifier les données mysql, donc les données trouvées par Thread2 à ce moment sont [anciennes données], et Thread2 écrit à nouveau les anciennes données sur Redis

10 À ce moment-là, le thread Thread3 arrive, et quand il interroge. Redis et découvre qu'il y a des données, il récupère directement les données mises en cache à ce moment-là [Thread3 a découvert les anciennes données] et les a renvoyées directement avec les anciennes données. C'est le problème

11. est d'empêcher Thread2 d'écrire à nouveau les anciennes données. Avec une double suppression retardée, Supprimer, lorsque Thread3 interroge Redis, il est toujours nul et il obtiendra les dernières données de mysql

12. temps écoulé entre la vérification du cache par Thread2 et l'obtention des données MySQL, puis leur enregistrement dans Redis, comme le temps de retard de Thread1, mais le temps de traitement de Thread2 sera affecté par de nombreux facteurs, il est donc difficile de déterminer combien de temps il sera

5 Double écriture retardée

// 延迟双写伪代码
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存

Le défaut de code ci-dessus ;

  • Sous forte concurrence, deux threads exécutent le code ci-dessus en même temps et modifient mysql, et le contenu de la modification est bloqué, ce qui peut conduire à une incohérence entre Redis et les données Mysql

  • Le thread T1 termine l'exécution de updateMysqlSql et libère le verrou de ligne. À ce moment, le thread T2 exécute updateMysqlSql et addRedis, et enfin T1 en exécutant addRedis, cette situation entraînera la modification de la base de données en données du T2. thread, mais Redis sont les données du thread T1

Optimisation

// 完美延迟双写伪代码
开启事务
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存
提交事务

Correction du code ci-dessus :

Mettez les deux lignes de code en une seule transaction, uniquement Lorsque T1 a fini d'exécuter Mysql et Redis, T2 peut commencer à s'exécuter , garantissant ainsi la cohérence des données. Il est recommandé d'utiliser le verrouillage distribué

Inconvénient de la double écriture : Mysql et Redis sont monothread. Les performances ne sont pas bonnes, il n'est donc pas recommandé de l'utiliser

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