✅P172_缓存-SpringCache-原理与不足
大约 2 分钟
读模式
缓存穿透
解决:保存空值
spring
cache:
redis:
cache-null-values: true
缓存击穿
解决:加锁,默认不加锁
@Cacheable(sync = true)
缓存雪崩
其实只要不是超大型并发,比如十几W的key同时过期,正好碰上十几W的请求过来查询,不用考虑这个问题
原来的解决方案是加随机时间,但是很容易弄巧成拙,假设数据不是同一时间放进去的,比如第1个数据是3秒过期,然后加了个随机数1秒,4秒过期,第2个数据是2秒过期,然后加了个随机数2秒,还是4秒过期,本来什么都不加的时候,它们过期时间不会冲撞在一起,结果有可能一加,倒还让他们撞在一起了,当时每一个数据存储的时间节点其实是不一样的,所以,只要指定过期时间就行
解决:加上过期时间
spring
cache:
redis:
time-to-live: 3600000 # 单位ms
写模式
- 读写加锁
- 引入Cannel,感知MySQL的更新去更新数据库
- 读多写多,直接查询数据库
原理
CacheManager -> Cache -> Cache负责缓存的读写
SpringCache的不足之处
读模式
- 缓存穿透:查询一个null数据。解决方案:缓存空数据
- 缓存击穿:大量并发进来同时查询一个正好过期的数据。解决方案:加锁 ? 默认是无加锁的;使用sync = true来解决击穿问题
- 缓存雪崩:大量的key同时过期。解决:加随机时间。加上过期时间
写模式:缓存与数据库一致
- 读写加锁
- 引入Canal,感知到MySQL的更新去更新Redis
- 读多写多,直接去数据库查询就行
总结
- 常规数据(读多写少,即时性,一致性要求不高的数据,完全可以使用Spring-Cache):
- 写模式,只要缓存的数据有过期时间就足够了
- 特殊数据:特殊设计