一、理解缓存
以空间换时间,所有保存“中间的、额外的”数据的机制,都可以称之为缓存。
二、缓存的作用
通过以下两点,对系统性能有提升
(1)缩短时间,有些数据可能查询起来或是运算起来很花时间, 那么我们就可以在某次获取该数据后放在可以快速取回的地方。
(2)降低压力,在高并发的情况下可能会导致数据库压力过大,借助数据缓存可以很好的规避这种问题。
三、缓存的合理性
(1)访问频率是高还是低?
如果访问频率低,缓存带来的业务复杂度弊端会高于系统性能提高的优势;所以访问频率高,适合缓存,而且效果也好些;
(2) 读写比例是什么样的?
访问频率高,读多写少,适合缓存,效果会好
(3)数据一致性要求高吗?
使用缓存适用那些对数据一致性要求不高的业务。
四、缓存的进化
(1)业务开始时,使用关系型数据库
(2)用户量上来后,将数据库改为读写分离的架构。
(3)还是撑不住,增加数据缓存层(redis)
(4)进一步优化,再次增加缓存层,形成多级缓存
(5)通过增加缓存监控,确保缓存的有效性,以及进一步优化缓存的策略等
五、缓存常见问题
下面所说的三种问题缓存方案都类似于Redis+Mysql,首先先从缓存中获取数据,找不到的时候去数据库获取数据并更新到缓存中。
(1)缓存穿透
请求去查询一条压根儿数据库中根本就不存在的数据,也就是缓存和数据库都查询不到这条数据,但是请求每次都会打到数据库上面去。
解决方案:
1.对于返回为NULL的依然缓存
2.制定一些规则过滤一些不可能存在的数据
(2)缓存击穿
在平常高并发的系统中,大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。这种现象我们称为缓存击穿。
解决方案:
1.加分布式锁,对于获取到这个锁的线程,查询数据库更新缓存,其他线程采取重试策略
2.采取到期自动刷新的策略,而不是到期自动淘汰
(3)缓存雪崩
当某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到DB上面。
解决方案:
1.增加缓存系统可用性,通过监控关注缓存的健康程度,根据业务量适当的扩容缓存。
2.采用多级缓存,不同级别缓存设置的超时时间不同,及时某个级别缓存都过期,也有其他级别缓存兜底。
3.缓存的过期时间可以取个随机值,尽量让不同Key的过期时间不同。
六、缓存更新策略
(1)Cache Aside
应用查询数据的时候先查询缓存层的数据,如果缓存中没有则到数据库中查询数据,并把数据放入缓存层。
更新数据的时候先对数据库进行更新,然后通过指令使缓存层的数据失效。
(2)Read/Write Through
应用要读数据和更新数据都直接访问缓存服务
缓存服务同步的将数据更新到数据库
(3)Write Behind
应用要读数据和更新数据都直接访问缓存服务
缓存服务异步的将数据更新到数据库(通过异步任务)
最后
正确的使用缓存可以让系统性能有提升,要注意需要针对不同场景来设计最佳的缓存方案。实践出真知,要想真正掌握缓存,还是需要在项目设计中多多考虑、