Redis(13)| 缓存与数据库数据一致性问题

本文讨论的前提:

  1. 不是一个事务,永远无法满足数据库和缓存的强一直性的;
  2. 文中会列举不一致的逻辑场景;
  3. 一定是依解决业务问题,和业务达成的共同目标为前提;

前言

只要用到多数据源存储同一份相同的数据,在更新时,都会考虑数据一致性问题。这是常见问题,但是对于分布式系统的CAP 理论,相信很多人都听过,它是指:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

为什么要理解 CAP 理论?
我能说出很多理由来。如果是在职场上,也许最合适的理由是,当领导给出的任务不靠谱时,我们可以依据 CAP 去否决它。比如,有这么一个任务,给你定了个大目标:

1. 这个系统满足编辑后数据要有实时性可见;
2. 还要系统的可用性,即响应效率高、响应结果合理,不能有bug;
3. 分区容错能力要高故障率99.9999%;

这个目标能完成吗?
本次讨论的数据库和缓存的数据一致性,就是Consistency。

为什么出现数据不一致

我们引入缓存机制,目的是:提高查询效率,这是初衷和前提,在并发场景下,也引入了一个问题,**何时去更新缓存?**在数据更新时,不仅要更新数据库,而且要更新缓存等,有如下集中情况

1.先更新数据库,再更新缓存

举个例子,比如「请求 A 」和「请求 B 」两个请求,同时更新「同一条」数据,则可能出现这样的顺序:
在这里插入图片描述

A 请求先将数据库的数据更新为 1,然后在更新缓存前,请求 B 将数据库的数据更新为 2,紧接着也把缓存更新为 2,然后 A 请求更新缓存为 1。
此时,数据库中的数据是 2,而缓存中的数据却是 1,出现了缓存和数据库中的数据不一致的现象。

2. 先更新缓存,再更新数据库

那换成「先更新缓存,再更新数据库」这个方案,还会有问题吗?
依然还是存在并发的问题,分析思路也是一样。
假设「请求 A 」和「请求 B 」两个请求,同时更新「同一条」数据,则可能出现这样的顺序:
在这里插入图片描述
A 请求先将缓存的数据更新为 1,然后在更新数据库前,B 请求来了, 将缓存的数据更新为 2,紧接着把数据库更新为 2,然后 A 请求将数据库的数据更新为 1。
此时,数据库中的数据是 1,而缓存中的数据却是 2,出现了缓存和数据库中的数据不一致的现象。
所以,无论是「先更新数据库,再更新缓存」,还是「先更新缓存,再更新数据库」,这两个方案都存在并发问题,当两个请求并发更新同一条数据的时候,可能会出现缓存和数据库中的数据不一致的现象。

3. 先删除缓存,再更新数据库

假设某个用户的年龄是 20,请求 A 要更新用户年龄为 21,所以它会删除缓存中的内容。这时,另一个请求 B 要读取这个用户的年龄,它查询缓存发现未命中后,会从数据库中读取到年龄为 20,并且写入到缓存中,然后请求 A 继续更改数据库,将用户的年龄更新为 21。
在这里插入图片描述
最终,该用户年龄在缓存中是 20(旧值),在数据库中是 21(新值),缓存和数据库的数据不一致。
可以看到,先删除缓存,再更新数据库,在「读 + 写」并发的时候,还是会出现缓存和数据库的数据不一致的问题。

4. 先更新数据库,再删除缓存

继续用「读 + 写」请求的并发的场景来分析。
假如某个用户数据在缓存中不存在,请求 A 读取数据时从数据库中查询到年龄为 20,在未写入缓存中时另一个请求 B 更新数据。它更新数据库中的年龄为 21,并且清空缓存。这时请求 A 把从数据库中读到的年龄为 20 的数据写入到缓存中。
在这里插入图片描述
最终,该用户年龄在缓存中是 20(旧值),在数据库中是 21(新值),缓存和数据库数据不一致。从上面的理论上分析,先更新数据库,再删除缓存也是会出现数据不一致性的问题,

解决方案

一切的技术方案都要根据业务合理的需求来。引入缓存是为了提高查询效率。

  1. 实时性不高的。比如:商详页、评价列表、点赞数等可以使用缓存过期时间+MQ/canal异步删除
  2. 实时性高的。比如商品库存、优惠券数量、保存在redis。并采用redisson提供的读写锁保证数据同步。
    在这里插入图片描述
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值