Redis缓存更新

文章讨论了在项目中处理数据库和Redis缓存数据一致性的问题,提出了更新缓存和删除缓存两种策略。更新策略可能导致大量无效操作,而删除策略能减少无效操作。在保证操作成功方面,单体系统可使用事务,分布式系统则需借助TCC等方案。先操作数据库再操作缓存的方法被推荐,以降低线程间数据不一致的风险。
摘要由CSDN通过智能技术生成

在项目中对于数据库和redis中的数据一致性问题,要考虑这些问题

  • 删除缓存还是更新缓存

  • 如何保证缓存与数据库同时操作成功

  • 先操作缓存还是先操作数据库

删除缓存和更新缓存

更新缓存:

那么每次更新数据库都会触发更新缓存的动作,操作一次就得改一次缓存,这其中无效的操作很多

orderService.update(order);   // 数据库更新
// 随之带来的就是缓存也得更新
redis: 更新对应键值对
// 这俩是一对一的关系

删除缓存:

只要操作数据库信息,那就把缓存删除。只有查的时候才重新把数据写到缓存中

orderService.update(order);   // 数据库更新
orderService.update(order);   // 数据库更新
orderService.update(order);   // 数据库更新
// ......
// 以上操作触发一次删除缓存操作,然后对于redis就没有操作了
orderService.select();  // 查询数据库
// 把数据写到缓存并返回

如果选择删除缓存,那多个更新操作只对应一个删除缓存操作,在下一次查的时候再写入缓存。这其中就少了很多无效的操作

如何保证缓存与数据库同时操作成功

  • 单体系统:将缓存与数据库操作放在一个事务内,保证两个操作的原子性

  • 分布式系统:利用 TCC 等分布式事务方案

先操作缓存还是先操作数据库

缓存---数据库

正常情况下拿到的数据是没有问题的,但如果在线程1更新数据库之前,线程二来查询,就会出现问题

线程1只删除了缓存,线程2来查询没有命中缓存,然后就去查数据库,写入缓存。然后切换到线程1,再把线程1的新数据写到数据库里,而现在的缓存是由线程2写入的旧数据,和数据库里的数据不一致,出现脏数据的情况

数据库---缓存

线程2更新数据库,然后把缓存删了,然后线程1来查,发现并没有命中缓存,然后就去查数据库,再把数据写到缓存。但还是会出现异常情况

线程1查询数据,此时是没有缓存的,然后去查数据库,再查数据库的时间里,线程2更新的数据库字段,并且把缓存删了,此时删除的是空对象。最后线程1把查出来的旧数据写到缓存中里,现在缓存中的数据是旧的,而数据库中的数据是新的

对比两种情况

先操作缓存再操作数据库的过程中,由于线程1查询时缓存刚好失效,从而到数据库中查到旧数据,然后线程2先更新了数据库,再删除缓存,这两个操作其实是比较耗时的。线程1查完数据库之后直接就写入缓存,这期间的时间间隔是比较短的,可能造成的情况是线程1刚写完缓存,线程2就又给删了,下次再来线程查询拿到的是新的数据库中数据,然后再写到缓存中。

所以 先操作数据库,后操作缓存的方案更加可靠

总结

删除缓存而不是更新缓存,更新缓存会有很多无效操作

先操作数据库后操作缓存的方式更加可靠

用户不查则不重建缓存

先删除,后重建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值