缓存是软件开发中一个很是有用的概念,数据库缓存更是在项目中必然会遇到的场景。而缓存一致性的保证,更是在面试中被反复问到,这里进行一下总结,针对不一样的要求,选择恰到好处的一致性方案。mysql
存储的速度是有区别的。缓存就是把低速存储的结果,临时保存在高速存储的技术。面试
咱们本次的讨论,主要针对数据库缓存场景,将以redis做为mysql的缓存为案例来进行。redis
存储如mysql一般支持完整的ACID特性,由于可靠性,持久性等因素,性能广泛不高,高并发的查询会给mysql带来压力,形成数据库系统的不稳定。同时也容易产生延迟。根据局部性原理,80%请求会落到20%的热点数据上,在读多写少场景,增长一层缓存很是有助提高系统吞吐量和健壮性。sql
存储的数据随着时间可能会发生变化,而缓存中的数据就会不一致。具体能容忍的不一致时间,须要具体业务具体分析,可是一般的业务,都须要作到最终一致。数据库
一般的开发模式中,都会使用mysql做为存储,而redis做为缓存,加速和保护mysql。可是,当mysql数据更新以后,redis怎么保持同步呢。缓存
强一致性同步成本过高,若是追求强一致,那么不必用缓存了,直接用mysql便可。一般考虑的,都是最终一致性。服务器
经过key的过时时间,mysql更新时,redis不更新。 这种方式实现简单,但不一致的时间会很长。若是读请求很是频繁,且过时时间比较长,则会产生不少长期的脏数据。并发
优势:异步
不足高并发
在方案一的基础上扩展,经过key的过时时间兜底,而且,在更新mysql时,同时更新redis。
优势
不足
针对方案二的同步写redis进行优化,增长消息队列,将redis更新操做交给kafka,由消息队列保证可靠性,再搭建一个消费服务,来异步更新redis。
优势
不足
经过订阅binlog来更新redis,把咱们搭建的消费服务,做为mysql的一个slave,订阅binlog,解析出更新内容,再更新到redis。
优势
缺点
通常状况,方案1够用。若延时要求高,直接选择方案4。若是是面试场景,从简单讲到复杂,面试官会一步一步追问,我们就一点点推导,宾主尽欢。