redis与mysql的数据一致性

解决redis与mysql的数据一致性

为什么会出现数据不一致性?

首先要明白只要我们使用了Redis缓存,就必然存在缓存和DB数据一致性的问题!就是我们修改了数据,没能即使同步到缓存中去!而我们业务读到缓存中不是最新的数据,这可能会导致严重的错误!如将商品库存缓存在Redis,若库存数量不对,则下单时就可能出错,这是难以接受的。

那么什么是数据一致性?

  • 缓存中有数据且缓存数据值与DB相同
  • 缓存无数据DB是最新最新值

不符合我们这两种的情况,都是属于数据不一致了!

好处就是减少数据库的IO操作;提升数据的IO性能!如图去数据的缓存架构图:

在这里插入图片描述

解决方法

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

这里会有一个问题:如果更新缓存失败,就会导致会数据和redis中数据不一致。

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

这里也有一个问题:在理想情况下应用下次访问redis的时候,发现redis里面的数据是空的,就从数据库中加载保存到redis里面,那么数据看起来就是一致的!但是在极端的情况下,由于删除redis和更新数据库,这两个操作不是原子的,所以在这个过程有其他的线程来访问的,还是会存在数据不一致的问题!

所以在极端的情况下,仍然保证redis与mysql的数据一致性,可以采用最终的一次性方案:

  • 基于RocketMQ的可高性消息通信来实现最终一次性
    *在这里插入图片描述

  • 通过Canal组件监控MySQL中Binlog日志实现一致性,把更新的数据同步到Redis里面去

在这里插入图片描述

这两个方法都是最终一致性来实现的!如果我们的业务场景不能接受数据短期不一致性的哇!那么我们可以通过读写锁的方法来保证强一致性!在数据更新的时候其他任何请求都无法访问缓存中的数据,直到数据更新完毕,从而保证数据的强一致性!但是这种方式,由于增加锁的操作,所以在性能上会有一定的影响

如图是读写锁实现一致性图:

在这里插入图片描述