【小记】如何保证缓存和数据库的一致性

8 篇文章 0 订阅

2021-03-07

今天看到一个有意思的问题,如何保证缓存和数据库的一致性,思考后查资料总结如下。

要对数据库更新,如何处置缓存,更新or删除?

选择删除缓存

因为要更新的数据可能是简单的也可能是复杂的,复杂的数据更新缓存的话,成本较大,所以选择删除缓存。

如果选择更新缓存的话,频繁的写操作意味着数据库和缓存都频繁更新,但重点是,该数据的读频率多大。根据28法则,20%的数据占了80%的访问量,对于某些缓存的频繁更新有点得不偿失。

先淘汰缓存还是先更新数据库?

先淘汰缓存

如果先更新数据库,再淘汰缓存,数据库更新完了之后,若缓存淘汰失败,那么后面读到的都是脏数据了,直到缓存失效。

如果先淘汰缓存,再更新数据库,如果数据库更新失败,只会造成一次缓存miss。相较而言,后者对业务的影响较小。

高并发下数据不一致问题的分析与解决

如下场景:同时有一个请求A进行更新操作,另一个请求B进行查询操作
(1)请求A进行写操作,删除缓存
(2)请求B发现缓存不存在
(3)请求B去数据库查询得到旧值
(4)请求B将查到的旧值写入缓存
(5)请求A将新值写入数据库

这样就出现了数据不一致的错误,导致脏读。

只有在对数据进行并发读写时,才会出现这样的问题。

其实并发量很低,特别是读很低,每天就1w的访问量,那么很少会出现上面的状况。

但问题是,如果每天的是上亿的流量,每秒并发读是几万,每秒只要有数据更新的请求,就可能会出现上述的数据库+缓存不一致的情况。

高并发了以后,问题是很多的。

解决方法

  • 延时双删策略
    在对数据写操作之前,删除缓存,延时1s后再将缓存删除。这样做可以将1s内的缓存脏数据清除。时间间隔可以根据具体业务设定。
  • 读请求和写请求串行化
    将读请求和写请求串行化,串到一个内存队列中去,这样就可以保证一定不会出现不一致的情况。

串行化之后,会导致系统的吞吐量大幅度降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

一般来说,如果系统不是严格要求缓存+数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要做这个方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值