缓存与数据库一致性问题
产生一致性问题的业务背景:
一致性问题一般是出现在修改操作,对数据库中数据进行修改。为什么会有一致性问题的提出那?是因为在大流量下,单访问数据库导致系统的性能较差,所以引入的redis缓存,数据发生变化的时候,数据库和redis中的数据都是需要修改的,但是在并发系统中,对数据库和redis的修改不是原子的,所以会触发不一致问题。但是在短链接创建后,进行修改时,需要同时对两者进行变更,因为种种异常原因,如何保障数据库和缓存种短链接的一致性呢?
项目中的应对策略:
由于修改短链接的并发量并不高,所以就没有 引入Canal 配合 Binlog 的形式解决缓存和数据库最终一致性问题。而是 使用的先修改数据库再删缓存 。该方式实现比较简单,不依赖额外中间件,从实时性以及技术实现复杂度来说都比较不错,在系统并发较小的情况下还是可以使用这种方案。

该策略下的不足:
1、小时间段内不一致问题:
小时间段内数据不一致是在我们先修改了数据库之后和删除的Redis中的缓存之间的这段时间,在我们修改短链接时,对数据库中的信息进行了修改,但是还没有对Redis中的缓存进行删除,这段时间内,有人访问了我们修改的短链接,但是缓存中的短链接还是原始的短链接信息,如果修改了原始链接就会跳转到未修改的原始链接。对于绝大多数的情况来说,是可以容忍的。
2、缓存删除问题:
我们上边提到由于我们的并发量并不高,所以我们选择了先更新数据库再删除缓存。在涉及海量并发的场景中,如果程序删除了缓存,可能会导致缓存击穿问题,而更新频繁时则可能引发缓存雪崩。
我们实际场景下,需要充分考虑业务场景是否属于高并发模型。如果是高并发场景,删除缓存可能并不合适,此时应采用最终一致性策略。那就应该引发出来 Canal 配合 Binlog 的形式解决缓存和数据库最终一致性问题。
拿 MySQL 举例,当一条数据发生修改时,MySQL 就会产生一条变更日志(Binlog),我们可以订阅这个日志,拿到具体操作的数据,然后再根据这条数据,去删除对应的缓存。