缓存击穿:
产生后的现象
- 数据库压力增大。
- Redis里面没有出现大量key过期。
- Redis正常运行,数据库崩溃。
何时会产生
Redis中的某个key过期了,但是瞬间有大量的请求来访问这个key。
解决方案
- 预先设置热门数据:在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的过期时间。
- 实时调整:现场监控哪些数据热门,实时调整key的过期时长
- 使用锁:
就是在缓存失效的时候(判断拿出来的值为空),不是立即去 load db。
先使用缓存工具的某些带成功操作返回值的操作(比如Redis 的 SETNX )
缓存雪崩:
产生后的现象
- 数据库压力变大,应用服务器返回时间变长。
- 应用访问变慢,Redis中造成大量访问等待。
- 数据库崩溃,服务器崩溃,Redis崩溃。
何时会产生
极少时间段,查询大量已过期key。
每个key(即数据)如果设置了失效时间的话,如果大量key同时过期的时候,或者说因为某种原因redis中的数据突然大批量丢失,这些key又大量地去请求这些key时,因为redis里面没有这些数据,就会大量的请求就会大量涌向数据库,就会导致数据库处理不过来,导致“雪崩”。
解决方案
- 构建多级缓存架构:nginx缓存+redis缓存+其他缓存( ehcache等 ) 。
- 使用锁或队列:
用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。不适用高并发情况· - 设置过期标志更新缓存∶
记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存。 - 将缓存失效时间分散开:
比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
缓存穿透:
产生后的现象
- 应用服务器压力增大。
- Redis命中率降低。在Redis缓存中查询不到数据。请求先到Redis缓存,查到返回,查不到去数据库查,然后再将结果缓存,再返回。
- 所有请求都到数据库,数据库压力增大。
何时会产生
- 1.Redis查询不到数据库,造成命中率降低。
- 2.出现大量非正常url访问。(这些url访问缓存中不存在的数据,一般是遭受恶意攻击。)
解决方案
- 对空值进行缓存
如果一个查询返回的结果是空(不管数据是否存在),将这个空结果进行缓存,设置空值的过期时间会很短,一般不超过5分钟。 - 设置请求可访问的名单(白名单)
使用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和id进行比较,如果id不在bitmaps中,进行拦截,拒绝访问。 - 使用布隆过滤器
布隆过滤器底层就是一个bitmaps,优点是空间效率和查询时间都远超一般算法,缺点是有一定的误识别率。 - 进行实时监控
当发现Redis命中率开始急剧降低时,需要排查访问数据,可以设置黑名单限制服务。