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