简介:
1、应用服务器压力增大
2、大量访问,但redis命中率降低(先访问缓存,未命中再访问数据库。)
3、数据库压力增大,导致崩溃
redis查询不到数据库,出现很多非正常url访问。
解决方案:
(1)对空值缓存
把空结果进行缓存,并设置空结果的过期时间
(2)设置白名单
用bitmaps类型定义可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里的id进行比较,如果访问id不在bitmaps里面,拦截不允许访问
(3)采用布隆过滤器
布隆过滤器,实际上是二进制向量(位数组)和随机映射函数(哈希函数) 用于快速判断一个一个元素是否可能在一个集合中,尽管可能会将不在集合中的元素误判在集合中,但不会把在集合中的元素误判不在集合中
(4)进行实时监控
Redis命中率下降时,将非正常访问的url和用户拉入黑名单
以上的方法可以综合使用,减少服务器压力。
Redis缓存击穿
特征:
1、数据库访问压力瞬时增加
2、redis里面没有出现大量key过期
3、redis正常运行
出现原因:
在高并发场景下,redis某个热点数据缓存过期的瞬间,收到大量请求同时访问该数据,这些请求会绕过缓存直接查询数据库,导致数据库压力骤增,甚至可能引发数据库宕机。
解决方案:
(1)预先设置热门key
在访问量增加之前,将热门key提前存入到redis中,实时调整key的过期时长
(2)实时调整
监控并实时调整key的过期时长
(3)使用锁
在缓存失效的时候(值为null),不立即去重新从数据库中取值 而是先检查缓存,如果数据存在,则直接返回 如果缓存中没有该数据,则表示该缓存可能已经过期,或数据未被缓存
缓存未命中时,尝试获取一个分布式锁(如SETNX命令),只有获取到锁的请求才可以访问数据库,其他请求则会在等待锁的释放。
获取锁的请求查询数据库后,写入Redis缓存,并根据以上的方法实时调整过期时间, 然后立即释放锁,请求会在锁被释放后,读取缓存返回给客户端。
缓存雪崩
1、在极少时间段内,查询大量key的集中过期情况
2、数据库压力变大,服务崩溃
解决方案
(1)构建多级缓存架构
如:nginx缓存 + redis缓存 + 其他缓存(ehcache等)
(2)使用锁或队列
用加锁或者队列的方式,保证不会有大量线程对数据库进行一次性读写。 不使用于高并发情况。
(3)设置过期标志更新缓存
记录缓存数据是否过期,过期时触发通知,在后台更新实际key的缓存
(4)将缓存失效时间分散
降低缓存过期的重复率,避免引发集体失效的事件。