缓存与数据库双写一致性问题

前言

首先我们需要知道现在的访问90%甚至更多为读请求,剩余部分才是写请求,并且随着目前网络的发展,使得数据库逐渐无法承受住用户的请求,所以现在的企业都会在数据库访问前引入一层或者多层缓存用来处理读请求(通常使用Redis)。

虽然缓存即为有效的提高了读多写少的场景的效率,但是遇到写请求的时候,就需要考虑一个问题,缓存和数据库的数据两个问题的双写一致性问题。

双写一致性问题

首先针对于数据库只存在写操作,但是针对于缓存的话我们有两种选择(删除缓存,更新缓存),如何选择写缓存的操作也十分关键。

因为缓存和数据库操作总有一个先后顺序,那么如何选择就成为了关键。

根据上面的两个关键点我们可以分为四种情况进行讨论。

修改缓存(无cache miss)
1.先修改缓存,再更新数据库。
2.先更新数据库,再修改缓存。
== 删除缓存(出现一次cache miss)==
3.先删除缓存,在更新数据库。
4.先更新数据库,再删除缓存。

一般都是后一步操作出现问题,所以我们只需要选择如果后一步出现问题对整个系统影响较小的部分即可。

修改缓存

如果缓存的值十分的简单(例如库存)那么其实修改缓存和删除缓存的效率差不多,但是如果缓存的值十分的复杂,例如商品需要进行各种的折扣计算,那么更新缓存就需要对数据库多次访问(例如多次查找数据库折扣)再重新进行计算更新缓存,这样不如删除缓存,让下一次读操作进来时发现cache miss对数据库进行访问在更新缓存的效率高。

所以我们直接淘汰了修改缓存的部分,使用删除缓存的方法,即保留了3,4两种情况。

谁先执行?

如果是数据库先执行更新操作后,系统出现问题或者延迟增大导致无法删除缓存或者需要过一段时间才能删除缓存,那么此时数据库中是新数据,而缓存中是旧数据,此时如果有请求过来打在了缓存上,那么读到的就是旧数据。----------很显然这种情况我们无法选择。

那么只剩下了先删除缓存再更新数据库了。针对这种情况我们分析一下。

如果删除缓存后,更新数据库操作不能执行或者延迟执行的话,那么此时数据库还没更新,下一个请求过来时发现cache miss从而去访问数据库(这个时候数据库还是旧数据),那么我们可以选择把这个数据读取后返回(但不更新缓存,此处类似缓存击穿),当我们前面的数据库操作执行完毕以后再更新缓存。------这样就解决了问题。

我能不能读取旧数据后就更新缓存
也可以,但是那么在第一步更新缓存的部分的时候,则需要加一步缓存是否存在,如果存在则删除了再更新(防止在执行数据库操作的时候就有读操作更新了缓存(此时缓存为旧数据)),如果不存在的话则直接更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值