缓存一致性的问题一直是比较困扰人的一个问题,接下来就和大家讨论下缓存一致性的各种问题。
1.1 为什么使用缓存
在互联网电商公司,对于数据的读取是非常频繁的。磁盘IO的瓶颈会限制在高并发请求的有效响应,因此此刻使用离内存更近的存储方式是减少数据传输时间,提高效率的有效和最常用的方式,这种方式就是缓存。
使用缓存不仅减少了请求的响应时间,而且降低了后端服务器的压力,提升了用户的体验。
1.2 缓存带来的问题
凡事皆有利就有弊,在高并发的场景下会带来以下几个问题:
缓存一致性:缓存数据和DB数据不一致,依赖于缓存的过期时间和更新缓存的策略。
缓存并发:高并发情况下,读取缓存不存在,去读取数据库,此刻未写入缓存是另一线程并发读取回直接打到数据库上。造成缓存并发,可以通过互斥锁解决。
缓存穿透:查询了一个不存在的数据,缓存不存在则读取DB,造成每次必定访问DB。可以通过短时间缓存空数据返回解决。
缓存雪崩:缓存部分热点的数据key,由于在同一时间失效导致大量请求访问DB。比较简单的一种方式是在固定时间的基础上加上随机数时间解决。
1.3 缓存一致性解决方案:
缓存一致性的问题很重要的一点就是:在得知DB数据发生的变化后写入缓存
方式一:
1.通过业务同时更新DB和缓存
2.更新DB成功,开始更新缓存。更新DB失败,直接失败。
3.更新缓存成功,成功返回。
4.更新缓存失败,数据发送到MQ
5.监听MQ消息,继续更新缓存。
方式二: 依赖binlog
1.业务更新数据库,更新MySql binlog日志。
2.获取mySql日志,转换为数据发送至MQ。
3.业务方监听MQ消息,根据标识更新缓存。
没有最好的解决方案,只有各自适合业务的解决方案。
参考文档:关于缓存穿透以及简单的处理方式 https://www.jianshu.com/p/400dd82389b4?from=groupmessage
参考文档:缓存在高并发场景下该如何处理问题 https://www.jianshu.com/p/99216e67612c
参考文档:分布式缓存一致性https://blog.csdn.net/koli6678/article/details/88202245