Maison  >  Article  >  base de données  >  Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

藏色散人
藏色散人avant
2023-02-15 11:16:251564parcourir

Avant-propos

En avril, un ami s'est rendu à Meituan pour une interview. Il a dit qu'on lui avait demandé comment assurer la cohérence de la double écriture entre Redis et MySQL ? Cette question demande en fait comment assurer la cohérence du cache et de la base de données dans un scénario de double écriture ? Cet article discutera avec vous de la manière de répondre à cette question.

Parlez de cohérence

La cohérence est la cohérence des données Dans un système distribué, elle peut être comprise comme la cohérence des données dans plusieurs. nœuds Les valeurs sont cohérentes.

  • Forte cohérence : ce niveau de cohérence est le plus conforme à l'intuition de l'utilisateur. Ce que le système doit écrire sera ce qui est lu. L'expérience utilisateur est bonne, mais sa mise en œuvre a souvent un grand impact sur les performances de. le système
  • Faible cohérence : Ce niveau de cohérence empêche le système de promettre que la valeur écrite peut être lue immédiatement après la réussite de l'écriture, ni de promettre combien de temps il faudra pour que les données soient cohérentes, mais il fera de son mieux pour garantir qu'après un certain niveau de temps (tel que le niveau des secondes), les données peuvent atteindre un état cohérent
  • Cohérence éventuelle : La cohérence finale est un cas particulier de cohérence faible. Le système garantira la cohérence des données. Cet état peut être atteint dans un certain laps de temps. La raison pour laquelle la cohérence ultime est mentionnée séparément ici est qu'il s'agit d'un modèle de cohérence très respecté en cohérence faible, et c'est également un modèle très respecté dans l'industrie pour la cohérence des données dans les grands systèmes distribués

Trois classiques Le mode mise en cache

la mise en cache peut améliorer les performances et soulager la pression sur la base de données, mais l'utilisation du cache peut également entraîner une incohérence des données. Comment utilisons-nous généralement le cache ? Il existe trois modèles de mise en cache classiques :

  • Modèle de cache-aside
  • Lecture/écriture continue
  • Écriture derrière

Modèle de cache-aside

Modèle de cache-aside, c'est-à-dire Mode de contournement du cache, son Il est proposé de résoudre autant que possible le problème d'incohérence des données entre le cache et la base de données.

Processus de lecture en cache-aside

Modèle en cache-asideLe processus de demande de lecture est le suivant :

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

  1. Lors de la lecture, lisez d'abord le cache. Si le cache atteint, les données seront renvoyées directement.
  2. Si le cache ne fonctionne pas, lisez simplement la base de données, récupérez les données de la base de données, placez-les dans le cache et renvoyez la réponse en même temps.
Processus d'écriture en cache-aside

Modèle de cache-asideLe processus de demande d'écriture est le suivant :

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Lors de la mise à jour,

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

Read-Through/Write-Through (pénétration lecture-écriture)

Read/Write Through mode, le serveur utilise le cache comme stockage de données principal. L'interaction entre l'application et le cache de la base de données s'effectue via la couche de cache abstraite.

Read-Through

Read-ThroughLe bref processus est le suivant

Read Through简要流程

    Lire les données du cache, les lire et les renvoyer directement
  1. Si elles ne peuvent pas être lues, chargez-les à partir de la base de données et écrivez versez-le dans le cache. Renvoyez ensuite la réponse.
Ce bref processus est-il similaire à

Cache-Aside ? En fait, Read-Through n'est qu'une couche supplémentaire de Cache-Provider. Le processus est le suivant :

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Read-Through n'est en fait qu'une couche d'encapsulation au-dessus de

Cache-Aside, ce qui rendra le code du programme plus concis tout en réduisant la charge sur la source de données. En mode

Write-Through

Write-Through, lorsqu'une demande d'écriture se produit, la couche d'abstraction du cache termine également la mise à jour de la source de données et des données mises en cache. Le processus est le suivant : Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Écrire derrière (. écriture de cache asynchrone)

Write Behind est similaire à Read-Through/Write-Through, en ce sens que est responsable de la lecture et de l'écriture du cache et de la base de données. Il y a une grande différence entre eux : Cache ProviderRead/Write Through met à jour le cache et les données de manière synchrone, tandis que Write Behind met uniquement à jour le cache, pas directement la base de données, et met à jour la base de données via batch asynchronous.

Write behind流程

De cette façon, la cohérence entre le cache et la base de données n'est pas forte

Les systèmes ayant des exigences de cohérence élevées doivent être utilisés avec prudence. Mais il convient aux scénarios d’écriture fréquents. Le Mécanisme InnoDB Buffer Pool de MySQL utilise ce mode.

Lors de l'utilisation du cache, devez-vous supprimer le cache ou mettre à jour le cache ?

Dans les scénarios commerciaux généraux, nous utilisons le mode

Cache-Aside. Certains amis peuvent demander : Cache-AsideLors de la rédaction d'une demande, pourquoi supprimer le cache au lieu de mettre à jour le cache ?

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Lorsque nous exploitons le cache, devons-nous supprimer le cache ou mettre à jour le cache ? Regardons d'abord un exemple :

  1. Le Thread A lance d'abord une opération d'écriture, la première étape consiste à mettre à jour la base de données
  2. Le Thread B lance ensuite une opération d'écriture et la deuxième étape met à jour la base de données
  3. En raison de réseau et pour d'autres raisons, le fil B a d'abord mis à jour le cache
  4. Le fil A a mis à jour le cache.

À ce moment, le cache enregistre les données de A (anciennes données) et la base de données enregistre les données de B (nouvelles données). Les données sont incohérentes et des données sales apparaissent. Si supprimez le cache au lieu de mettre à jour le cache, ce problème de données sales ne se produira pas.

La mise à jour du cache présente deux inconvénients par rapport à la suppression du cache :

  • Si la valeur du cache que vous écrivez est obtenue après des calculs complexes. Si le cache est mis à jour fréquemment, les performances seront gaspillées.
  • Lorsqu'il existe de nombreux scénarios d'écriture de base de données et peu de scénarios de lecture de données, les données sont souvent mises à jour avant d'être lues, ce qui gaspille également les performances (en fait, dans les scénarios où il y a beaucoup d'écriture, la mise en cache n'est pas la meilleure solution) Très rentable)

En cas de double écriture, la base de données ou le cache doivent-ils être exploités en premier ?

En mode cache Cache-Aside, certains amis se posent encore des questions lors de la rédaction d'une requête, pourquoi Cache-Aside缓存模式中,有些小伙伴还是有疑问,在写入请求的时候,为什么是先操作数据库呢?为什么不先操作缓存呢?

假设有A、B两个请求,请求A做更新操作,请求B做查询读取操作。Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

  1. 线程A发起一个写操作,第一步del cache
  2. 此时线程B发起一个读操作,cache miss
  3. 线程B继续读DB,读出来一个老数据
  4. 然后线程B把老数据设置入cache
  5. 线程A写入DB最新的数据

酱紫就有问题啦,缓存和数据库的数据不一致了。缓存保存的是老数据,数据库保存的是新数据。因此,Cache-Asideexploiter la base de données en premier

 ? Pourquoi

ne pas utiliser le cache en premier

 ?

Supposons qu'il y ait deux requêtes, A et B, demandant à A d'effectuer l'opération de mise à jour et demandant à B d'effectuer l'opération de requête et de lecture. Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

Thread A Initiez une opération d'écriture, la première étape est de supprimer le cacheComment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

À ce moment, le thread B lance une opération de lecture, le cache manque
  1. Le thread B continue de lire la base de données et lit une ancienne donnée
  2. Ensuite, le thread B définit l'ancienne données dans le cache
  3. thread A écrit les dernières données dans DB

Il y a un problème avec Jiang Zi Les données dans le cache et la base de données sont incohérentes. Le cache stocke les anciennes données et la base de données stocke les nouvelles données

. Par conséquent, le mode de mise en cache Cache-Aside choisit d'exploiter d'abord la base de données au lieu du cache en premier.

Double suppression retardée du cache

Certains amis diront peut-être que vous n'avez pas besoin d'exploiter la base de données en premier, utilisez simplement la stratégie

Double suppression retardée du cache

 ? Qu’est-ce que la double suppression différée ?

Supprimez d'abord le cache

, puis mettez à jour la base de données Veillez 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 ? Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

    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.
  1. Mécanisme de nouvelle tentative de suppression du cache
  2. Qu'il s'agisse d'une
  3. double suppression retardée
  4. ou d'un
  5. Cache-Aside qui exploite d'abord la base de données puis supprime le cache
  6. , si la deuxième étape de suppression du cache échoue, l'échec de la suppression entraînera données sales ~

Si la suppression échoue, supprimez-la plusieurs fois pour vous assurer que la suppression du cache est réussie~ Par conséquent, vous pouvez introduire le

mécanisme de nouvelle tentative de suppression du cache

Comment assurer la cohérence des doubles écritures entre Redis et MySQL ? (Meituan Ermian)

demande d'écriture pour mettre à jour la base de données

La suppression du cache a échoué pour certaines raisons
Mettez la clé qui n'a pas pu être supprimée dans la file d'attente des messages
🎜Consommez les messages de la file d'attente des messages et obtenez la clé à supprimer🎜🎜Réessayez l'opération de suppression du cache🎜🎜🎜Lire le biglog suppression asynchrone du cache🎜🎜Réessayez la suppression Le mécanisme de cache est correct, c'est-à-dire qu'il provoquera de nombreuses intrusions dans le code métier. En fait, vous pouvez également éliminer la clé de manière asynchrone🎜 via le binlog de la base de données. 🎜🎜🎜🎜🎜 En prenant MySQL comme exemple, vous pouvez utiliser le canal d'Alibaba pour collecter et envoyer les journaux binlog à la file d'attente MQ, puis confirmer et traiter le message de mise à jour via le mécanisme ACK, supprimer le cache et assurer la cohérence du cache des données🎜 Apprentissage recommandé : "🎜Tutoriel vidéo Redis🎜》🎜🎜

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