缓存穿透
缓存穿透:当查询的内容在缓存中没有命中时,会向数据层发送查询命令,当存在大量的查询命令穿过缓存到达数据库时,会导致数据库崩溃,引发服务器的死机。
应对方案:
- 使用布隆过滤器(bloomfilter):布隆过滤器是一种数据结构,将所有可能会查询的参数以hash形式存储,在控制层中进行参数校验,不符合就会丢弃此查询命令,不会向下传递。
- 创建缓存空对象:当用户查询内容在redis中没有命中,则在redis中创建这个空对象,以防止用户无限次的穿过缓存去查询数据库。对于这些会占用大量内存空间的空对象,可以设置过期时间。存在的问题是当数据库中存入了这个新对象后,会导致缓存与数据库的数据不一致。
关于缓存与数据库数据不一致问题可参考:
如何保持mysql和redis中数据的一致性?
Redis与数据库的数据一致性解决方案
缓存击穿
缓存击穿:当用户查询量过大,而此时缓存中的对象过期且还未重新生成的这段时间里,会有大量的查询命令到达数据层来访问数据库,而导致数据库崩溃。
应对方案:
- 设置热点数据永不过期
- 加互斥锁(分布式锁):设置对对象的查询,数据层同时只能一个线程来查,其他的线程都要等待。(对分布式锁是巨大考验)
缓存雪崩(当发生雪崩时,每一片雪花都在勇闯天涯!)
缓存雪崩:在某个时间段内,缓存中的对象大量过期失效,或者redis宕机了(那个扫地阿姨又把我服务器电源线踢掉了!)导致大量查询命令到达数据库造成崩溃。
应对方案:
- 搭建redis集群(异地多活)
- 限流降级:缓存数据大量失效时,通过加锁或者队列来控制查询线程数量
- 数据预热:先将可能会发生高并发查询的数据预先访问一遍,加载到缓存中(在发生高并发访问前手动触发加载缓存),设置不同的过期时间,使失效时间尽量分布均匀。
关于redis的基础知识学习笔记已总结完毕,关于如何使用springBoot整合redis(Jedis和lettuce)的内容将在以后进行总结。