✅P172_缓存-SpringCache-原理与不足

gong_yz大约 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

写模式

  1. 读写加锁
  2. 引入Cannel,感知MySQL的更新去更新数据库
  3. 读多写多,直接查询数据库

原理

CacheManager -> Cache -> Cache负责缓存的读写


SpringCache的不足之处

读模式

  • 缓存穿透:查询一个null数据。解决方案:缓存空数据
  • 缓存击穿:大量并发进来同时查询一个正好过期的数据。解决方案:加锁 ? 默认是无加锁的;使用sync = true来解决击穿问题
  • 缓存雪崩:大量的key同时过期。解决:加随机时间。加上过期时间

写模式:缓存与数据库一致

  • 读写加锁
  • 引入Canal,感知到MySQL的更新去更新Redis
  • 读多写多,直接去数据库查询就行

总结

  • 常规数据(读多写少,即时性,一致性要求不高的数据,完全可以使用Spring-Cache):
  • 写模式,只要缓存的数据有过期时间就足够了
  • 特殊数据:特殊设计