怎么保证缓存和数据库一致性?
存储的数据随着时间可能会发生变化,而缓存中的数据就会不一致。
具体能容忍的不一致时间,需要具体业务具体分析,但是通常的业务,都需要做到最终一致。
redis作为mysql缓存:
通常的开发模式中,都会使用mysql作为存储,redis作为缓存,
当mysql数据更新之后,redis怎么保持同步呢?
强一致性同步成本太高,如果追求强一致,那么没必要用缓存了,
直接用mysql即可。通常考虑的,都是最终一致性。
解决方案
方案一
通过key的过期时间,mysql更新时,redis不更新。
这种方式实现简单,但不一致的时间会很长。如果读请求非常频繁,且过期时间比较长,则会产生很多长期的脏数据。
优点:开发成本低,易于实现;
不足:完全依赖过期时间,时间太短容易缓存频繁失效,太长容易有长时间更新延迟(不一致)
方案二
在更新mysql时,同时更新redis。
方案三
针对方案二的同步写redis进行优化,增加消息队列,将redis更新操作交给消息队列,
由消息队列保证可靠性,再搭建一个消费服务,来异步更新redis。
方案四
通过订阅binlog来更新redis,把我们搭建的消费服务,
作为mysql的一个slave,订阅binlog,解析出更新内容,再更新到redis。
总结
通常来说,方案1就够了,笔者咨询过4,5个团队,基本都是用方案1,因为能用缓存方案,通常是读多写少场景,同时业务上对延迟具有一定的包容性。方案1没有开发成本,其实比较实用。
结论
一般情况,方案1够用。若延时要求高,直接选择方案4。如果是面试场景,从简单讲到复杂,面试官会一步一步追问,咱们就一点点推导,宾主尽欢。
参考:https://mp.weixin.qq.com/s/6VXi9UsMl1rbZZ-aVOPtQA