Maison  >  Article  >  Java  >  Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?

Java学习指南
Java学习指南avant
2023-07-26 14:53:291748parcourir

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?


Dans les grands systèmes, des mécanismes de mise en cache sont généralement introduits pour réduire la pression sur la base de données. Une fois la mise en cache introduite, il est facile de provoquer une incohérence entre les données du cache et celles de la base de données, ce qui amène les utilisateurs à voir les anciennes données. .

Afin de réduire l'incohérence des données, le mécanisme de mise à jour du cache et de la base de données est particulièrement important. Ensuite, je vous guiderai à travers les pièges.

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?

Cache de côté

Cache de côté C'est-à-dire Contourner le cache , est une stratégie de mise en cache couramment utilisée. Cache aside也就是旁路缓存,是比较常用的缓存策略。

(1)读请求(1)Demande de lectureProcessus communs

🎜
Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
Cache mis à part la demande de lecture

L'application déterminera d'abord si le cache contient les données. Si le cache atteint, les données seront renvoyées directement. Si le cache manque, le cache pénétrera dans la base de données et interrogera les données. de la base de données, puis réécrivez-le dans le cache, et enfin renvoyez les données au client.

(2)Demande d'écritureCommun Processus写请求常见流程

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
Cache aside 写请求

首先更新数据库,然后从缓存中删除该数据。

看了写请求的图之后,有些同学可能要问了:为什么要删除缓存,直接更新不就行了?这里涉及到几个坑,我们一步一步踩下去。

Cache aside踩坑

Cache aside策略如果用错就会遇到深坑,下面我们来逐个踩。

踩坑一:先更新数据库,再更新缓存

如果同时有两个写请求需要更新数据,每个写请求都先更新数据库再更新缓存,在并发场景可能会出现数据不一致的情况。

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
先更新数据库,再更新缓存

如上图的执行过程:

(1)写请求1更新数据库,将 age 字段更新为18;

(2)写请求2

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?🎜Cache mis à part la demande d'écriture🎜🎜🎜Mettre à jour en premier base de données et supprimez les données du cache. 🎜🎜Après avoir regardé l'image de la demande d'écriture, certains étudiants peuvent se demander : Pourquoi devons-nous supprimer le cache ? Ne pouvons-nous pas simplement le mettre à jour directement ? Il y a plusieurs pièges impliqués ici, passons-les en revue étape par étape. 🎜

Piège de cache mis à part

🎜Une stratégie de mise à côté du cache sera rencontrée si elle est utilisée incorrectement. C'est un problème profond fosse, entrons-y un par un. 🎜🎜🎜 Piège 1 : Mettez d'abord à jour la base de données, puis mettez à jour le cache🎜🎜S'il y a deux Demande d'écriture doit mettre à jour les données. Chaque demande d'écriture met d'abord à jour la base de données, puis le cache. Une incohérence des données peut survenir dans des scénarios simultanés. 🎜🎜Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?🎜Mettez d'abord à jour la base de données, puis mettez à jour le cache🎜🎜🎜Exécution comme indiqué ci-dessus Processus : 🎜🎜(1)Demande d'écriture 1Mettez à jour la base de données et mettez à jour le champ d'âge à 18 ; 🎜🎜(2)<code style="font-size : 14px;padding : 2px 4px;border-radius : 4px;margin-right : 2px;margin-left : 2px; couleur d'arrière-plan : rgba(27, 31, 35, 0.05);famille de polices : " operator mono consolas monaco menlo monospace de mot break-all rgb>Ecrire la requête 2Mettre à jour la base de données et mettre à jour le champ âge à 20 ;🎜

(3)Write request 2Mise à jour du cache , l'âge du cache est fixé à 20 ; 写请求2更新缓存,缓存 age 设置为20;

(4)写请求1更新缓存,缓存 age 设置为18;

执行完预期结果是数据库 age 为20,缓存 age 为20,结果缓存 age为18,这就造成了缓存数据不是最新的,出现了脏数据。

踩坑二:先删缓存,再更新数据库

如果写请求的处理流程是先删缓存再更新数据库,在一个读请求和一个写请求并发场景下可能会出现数据不一致情况。

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
先删缓存,再更新数据库

如上图的执行过程:

(1)写请求删除缓存数据;

(2)读请求查询缓存未击中(Hit Miss),紧接着查询数据库,将返回的数据回写到缓存中;

(3)写请求

(4) Le flux de traitement de la demande d'écriture est Supprimez d'abord le cache puis mettez à jour la base de données, dans un Demande de lecture et un Demande d'écriture Une incohérence des données peut se produire dans des scénarios simultanés. 🎜
Supprimez d'abord le cache, puis mettez à jour la base de données
🎜Le processus d'exécution comme indiqué ci-dessus :🎜🎜(1)Demande d'écritureSupprimer les données mises en cache ; 🎜🎜(2)Demande de lecture Interroger l'échec du cache (Hit Miss), puis interroger la base de données , réécrivez les données renvoyées dans le cache 🎜🎜(3)Ecrire une requête pour mettre à jour la base de données. 🎜

Après tout le processus, j'ai trouvé que âge dans la base de données est 20, <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05) ;font-family : " operator mono consolas monaco menlo monospace break-all rgb>CacheL'âge est 18, cache Il est incohérent avec les données de la base de données et des données sales apparaissent dans le cache. 数据库中age为20,缓存中age为18,缓存和数据库数据不一致,缓存出现了脏数据。

踩坑三:先更新数据库,再删除缓存

在实际的系统中针对写请求还是推荐先更新数据库再删除缓存,但是在理论上还是存在问题,以下面这个例子说明。

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
先更新数据库,再删除缓存

如上图的执行过程:

(1)读请求先查询缓存,缓存未击中,查询数据库返回数据;

(2)写请求更新数据库,删除缓存;

(3)读请求回写缓存;

整个流程操作下来发现数据库age为20缓存age为18

Piège 3 : Mettez d'abord à jour la base de données, puis supprimez le cache

Dans le système actuel, Demande d'écriture ou recommandéMettez d'abord à jour la base de données, puis supprimez le cache, mais il y a toujours des problèmes en théorie, comme le montre l'exemple suivant. 🎜
Mettez d'abord à jour la base de données, puis supprimez le cache
🎜Le processus d'exécution comme indiqué ci-dessus :🎜🎜(1)Demande de lecture interroge d'abord le cache, si le cache n'est pas atteint, interroge le base de données pour renvoyer les données ; 🎜🎜 (2)Demande d'écritureMettre à jour la base de données, supprimer le cache ; 🎜🎜(3)<code style="font-size : 14px;padding : 2px 4px;border-radius : 4px;margin-right : 2px;margin-left : 2px;background- couleur : rgba(27, 31, 35, 0.05) ; famille de polices : « Operator Mono », Consolas, Monaco, Menlo, monospace ; saut de mot : break-all ; couleur : rgb (0, 0, 153) ; >Demande de lecture Cache de réécriture ; 🎜🎜Une fois l'ensemble du processus terminé, il s'avère que L'âge du cache est de 18 code>, c'est-à-dire que la base de données et le cache sont incohérents, ce qui fait que les données lues par l'application à partir du cache sont des données anciennes. 🎜🎜Mais si nous y réfléchissons attentivement, la probabilité que le problème ci-dessus se produise est en fait très faible, car les opérations de mise à jour de la base de données prennent généralement plusieurs ordres de grandeur de plus que les opérations de mémoire. La dernière étape de l'image ci-dessus consiste à réécrire le fichier. cache (défini sur l'âge de 18 ans) très rapidement. Ceci est généralement effectué avant la mise à jour de la base de données. 🎜<p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;text-align: justify;font-size: 15px;">Et si ce scénario extrême se produisait ? Nous devons penser à une solution : <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0,05) ; famille de polices : " operator mono consolas monaco menlo monospace mot-break break-all couleur rgb>Délai d'expiration des paramètres de données du cache . Habituellement, dans le système, une petite quantité de données peut être incohérente pendant une courte période de temps. 缓存数据设置过期时间。通常在系统中是可以允许少量的数据短时间不一致的场景出现。

Read through

在 Cache Aside 更新模式中,应用代码需要维护两个数据源头:一个是缓存,一个是数据库。而在 Read-Through 策略下,应用程序无需管理缓存和数据库,只需要将数据库的同步委托给缓存提供程序 Cache Provider 即可。所有数据交互都是通过抽象缓存层完成的。

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
Read-Through流程

如上图,应用程序只需要与Cache Provider交互,不用关心是从缓存取还是数据库。

在进行大量读取时,Read-Through 可以减少数据源上的负载,也对缓存服务的故障具备一定的弹性。如果缓存服务挂了,则缓存提供程序仍然可以通过直接转到数据源来进行操作。

Read-Through 适用于多次请求相同数据的场景

Lecture

En mode de mise à jour Cache Aside, le code de l'application doit conserver deux Il existe deux sources de données : l’une est le cache et l’autre la base de données. Et dans Stratégie de lecture, appliquée le programme n'a pas besoin de gérer le cache et la base de données, il lui suffit de confier la synchronisation de la base de données au fournisseur de cacheFournisseur de cache. Toutes les interactions de données se font via Couche de cache abstraite Terminé . 🎜
Processus de lecture
🎜Comme indiqué ci-dessus, l'application doit uniquement être mise en correspondance avec Interaction du fournisseur de cache, qu'il soit récupéré du cache ou de la base de données. 🎜🎜Lorsque vous effectuez des lectures lourdes, Lecture peut réduire la charge sur la source de données et est également résilient aux pannes du service de cache. Si le service de cache tombe en panne, le fournisseur de cache peut toujours fonctionner en accédant directement à la source de données. 🎜🎜<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05) ;font-family : " operator mono consolas monaco menlo monospace break-all rgb>Read-Through convient à plusieurs demandes pour le même Scénario de données , ceci est très similaire à la stratégie Cache-Aside, mais il existe encore quelques différences entre les deux, qui sont encore soulignées : 🎜
  • Dans Cache-Aside, l'application est chargée d'obtenir les données de la source de données et de les mettre à jour dans le cache.
  • En Read-Through, cette logique est généralement supportée par un fournisseur de cache indépendant (Cache Provider).

Écrivez à travers

Write-Through 策略下,当发生数据更新(Write)时,缓存提供程序 Cache Provider 负责更新底层数据源和缓存。

缓存与数据源保持一致,并且写入时始终通过抽象缓存层到达数据源。

Cache Provider类似一个代理的作用。

Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
Write-Through流程

Write behind

Write behind在一些地方也被成为Write back, 简单理解就是:应用程序更新数据时只更新缓存, Cache Provider每隔一段时间将数据刷新到数据库中。说白了就是延迟写入

Le cache est cohérent avec la source de données et écrit toujours pass -color : rgba(27, 31, 35, 0.05) ;font-family : "Operator Mono", Consolas, Monaco, Menlo, monospace ;word-break : break-all;color: rgb(0, 0, 153); ">La couche de mise en cache abstraite atteint la source de données. 🎜🎜Cache Provider agit comme un proxy. 🎜
Write Behind
est également appelé Réécrire, une compréhension simple est la suivante : lorsque l'application met à jour les données, elle met uniquement à jour le cache, Cache Provider actualise les données dans la base de données à intervalles réguliers. Pour parler franchement, c'estÉcriture différée . 🎜
Dans un scénario à forte concurrence, le cache ou la base de données doivent-ils être mis à jour en premier ?
Processus d'écriture derrière

Comme le montre l'image ci-dessus, lorsque l'application met à jour deux données, le fournisseur de cache les écrira immédiatement dans le cache, mais elles seront écrites dans la base de données par lots après un certain temps.

Cette méthode présente des avantages et des inconvénients :

  • 优点是数据写入速度非常快,适用于频繁写的场景。

  • 缺点

Inconvénient est la mise en cache Il n'est pas fortement cohérent avec la base de données et doit être utilisé avec prudence dans les systèmes ayant des exigences de cohérence élevées.

Pour résumer
  • Après avoir tant appris, je pense que tout le monde a une compréhension claire de la stratégie de mise à jour du cache. Enfin, un petit résumé.
    Il existe trois stratégies principales pour la mise à jour du cache :
  • Cache de côté
  • Lecture/écriture

Écrire derrière

Le cache de côté met généralement à jour d'abord la base de données, puis supprime généralement le cache. définit également une durée de cache pour les données.

La lecture/écriture est généralement fournie par un fournisseur de cache pour les opérations de lecture et d'écriture externes, et l'application n'a pas besoin de savoir si le cache ou la base de données est en cours d'exécution. 🎜🎜Write Behind comprend simplement qu'il s'agit d'une écriture retardée. Le fournisseur de cache entrera la base de données par lots de temps en temps. L'avantage est que l'application écrit très rapidement. 🎜🎜D'accord, c'est tout pour aujourd'hui. Avez-vous retenu la leçon ? 🎜

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