架构师面试(九):缓存一致性

问题

关于【数据库和缓存】一致性,下面哪几项是在线上生产环境中相对合理的处理方式? 

A. 对于查询操作,先查缓存,如果为空则查 DB,然后将数据带入缓存;

B. 对于插入操作,只写 DB 即可;

C. 对于删除操作,先删除缓存,再删 DB;

D. 对于更新操作,先更新 DB,再更新缓存。

解析

需要先明确两个问题:

1、引入缓存的目的是什么

引入缓存是为了提供高性能的数据读取;也就是缓存是为了抗高吞吐的读操作,而非写操作。

2、数据库和缓存的适用场景是什么

首先,业务如果是追求数据的强一致性,则不用缓存;也就是数据库和缓存之间实现的是最终一致性,只是不同业务对数据不一致的时间窗口大小要求不同而已;然后,对于写多读少的场景,不用缓存;根据引入缓存的目的分析,数据库和缓存配合适合的是读多写少的业务场景。

为了方便实现数据库和缓存之间的最终一致性,从实现成本和降低复杂性考虑,我们从整体上设计完整的实现思路,如下:

1、 插入操作:只写数据库即可

如果写完数据库后,再写缓存,在并发场景下,会产生ABBA问题;

所谓ABBA问题是这样的:客户端A 要对变量X写入5, 同时客户端B要对X写入6;因为是并发,所以写入的时序很可能为【数据库X=5(A 操作)】【数据库X=6(B操作)】【缓存X=6(B操作)】【缓存X=5(A操作)】,结果就是 数据库中的X=6而缓存中的X=5。

2、查询操作:先查询 缓存,如果为空则查询 数据库,然后将查询到的数据写入缓存

在并发场景下,最多会导致对缓存的重复写入,浪费一点算力而已,但不会导致数据库和缓存的不一致性。

3、删除操作:先删除数据库,再删除缓存

釜底抽薪,所以先删除数据库中的数据;如果先删除缓存,会很容易因为查询操作导致数据再次写入缓存;这个地方需要注意的是,删除缓存操作有可能失败,我们后面集中解决这个问题。

4、更新操作:先更新数据库,再删除缓存

为什么是删除缓存,而非更新缓存呢?如果是更新缓存,在并发场景下仍然会很容易出现ABBA的问题;所以删除缓存简单粗暴,让数据为空(在查询操作中让数据补齐即可),非常有效地避免了数据库和缓存的不一致性;这个地方也需要注意的是,删除缓存操作有可能失败,同样我们后面集中解决它。

整体来看,对于CRUD操作有了一个完整的数据库和缓存一致性的解决方案;唯一需要解决的问题就是:删除缓存失败时,该如何处理?

1. 通过缓存的过期策略删除key

2. 基于事务消息对缓存进行删除

3. 基于binlog方式对缓存进行删除

4. 通过离线任务对删除失败的缓存key进行清理

5. 基于分布式锁解决ABBA问题

答案

AB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值