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.
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 lecture
Processus communs
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'écriture
Commun Processus写请求
常见流程
首先更新数据库,然后从缓存中删除该数据。
看了写请求的图之后,有些同学可能要问了:为什么要删除缓存,直接更新不就行了?这里涉及到几个坑,我们一步一步踩下去。
Cache aside策略如果用错就会遇到深坑,下面我们来逐个踩。
踩坑一:先更新数据库,再更新缓存
如果同时有两个写请求
需要更新数据,每个写请求都先更新数据库再更新缓存,在并发场景可能会出现数据不一致的情况。
如上图的执行过程:
(1)写请求1
更新数据库,将 age 字段更新为18;
(2)写请求2
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. 🎜🎜🎜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 2
Mettre à jour la base de données et mettre à jour le champ âge à 20 ;🎜(3)Write request 2
Mise à jour du cache , l'âge du cache est fixé à 20 ; 写请求2
更新缓存,缓存 age 设置为20;
(4)写请求1
更新缓存,缓存 age 设置为18;
执行完预期结果是数据库 age 为20,缓存 age 为20,结果缓存 age为18,这就造成了缓存数据不是最新的,出现了脏数据。
踩坑二:先删缓存,再更新数据库
如果写请求
的处理流程是先删缓存再更新数据库
,在一个读请求
和一个写请求
并发场景下可能会出现数据不一致情况。
如上图的执行过程:
(1)写请求
删除缓存数据;
(2)读请求
查询缓存未击中(Hit Miss),紧接着查询数据库,将返回的数据回写到缓存中;
(3)写请求
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. 🎜Demande d'écriture
Supprimer 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>Cache
L'â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,缓存和数据库数据不一致,缓存出现了脏数据。
踩坑三:先更新数据库,再删除缓存
在实际的系统中针对写请求
还是推荐先更新数据库再删除缓存
,但是在理论上还是存在问题,以下面这个例子说明。
如上图的执行过程:
(1)读请求
先查询缓存,缓存未击中,查询数据库返回数据;
(2)写请求
更新数据库,删除缓存;
(3)读请求
回写缓存;
整个流程操作下来发现数据库age为20
,缓存age为18
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. 🎜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. 缓存数据设置过期时间
。通常在系统中是可以允许少量的数据短时间不一致的场景出现。
在 Cache Aside 更新模式中,应用代码需要维护两个数据源头:一个是缓存,一个是数据库。而在 Read-Through
策略下,应用程序无需管理缓存和数据库,只需要将数据库的同步委托给缓存提供程序 Cache Provider
即可。所有数据交互都是通过抽象缓存层
完成的。
如上图,应用程序只需要与Cache Provider
交互,不用关心是从缓存取还是数据库。
在进行大量读取时,Read-Through
可以减少数据源上的负载,也对缓存服务的故障具备一定的弹性。如果缓存服务挂了,则缓存提供程序仍然可以通过直接转到数据源来进行操作。
Read-Through 适用于多次请求相同数据的场景
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é . 🎜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 : 🎜Write-Through
策略下,当发生数据更新(Write)时,缓存提供程序 Cache Provider
负责更新底层数据源和缓存。
缓存与数据源保持一致,并且写入时始终通过抽象缓存层
到达数据源。
Cache Provider
类似一个代理的作用。
Write behind
在一些地方也被成为Write back
, 简单理解就是:应用程序更新数据时只更新缓存, Cache Provider
每隔一段时间将数据刷新到数据库中。说白了就是延迟写入
Cache Provider
agit comme un proxy. 🎜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
. 🎜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.
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!