缓存介绍

简单缓存逻辑
image

缓存穿透

如果去请求一条不存在的key,那么缓存和数据库都不存在这条记录,每次请求都会打到数据库上,这叫做缓存穿透(可以用来攻击)。

避免
  1. 缓存空值
    可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候,直接返回null 。
  2. BloomFilter
    在海量数据中,布隆过滤器里头可以选缓存数据库到底有什么key。
    在缓存之前在加一层 BloomFilter ,在查询的时候先去 BloomFilter 去查询 key 是否存在,如果不存在就直接返回,存在再走查缓存 -> 查 DB

缓存击穿

在高并发系统中,大量请求查询一个key,这个key又刚好失效,那么就会有大量的数据打到数据库中。

解决

可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。

其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。(可以利用guava中的机制,第一个请求阻塞等待,其他请求先获取旧的数据,等新的数据获取到后更新)

缓存雪崩

当某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到DB上面。结果就是DB 扛不住,挂掉。

解决
  1. 使用集群缓存,保证缓存服务的高可用
  2. Hystrix限流&降级
  3. 开启Redis持久化机制,尽快恢复缓存集群