缓存穿透

问题特征
  1. 应用服务器压力突然变大了(非双十一的平常).
  2. redis命中率降低(缓存获取查不到数据)
  3. 一直查询数据库.
现象
  1. redis查询不到数据库.
  2. 大量非正常URL访问. 比如黑客乱修dom的值进行访问, 我没有这个数据项, 就一直访问数据库.
解决方案
  1. 对空值缓存: 数据库中查不到的数据null也缓存, 设定较短的过期时间. 临时方法.
  2. 设置可访问的名单(白名单): 使用bitmaps类型定义一个可以访问的名单, 效率不太高.
  3. 采用布隆过滤器: 1970年布隆提出的一个方法, 一个很长的二进制向量和一系列随机映射函数(哈希函数), 是对bitmaps的一种优化.
  4. 进行实时监控(黑名单), 跟运维人员配合, 设置不能访问的对象.

缓存击穿

问题描述
  1. 数据库访问压力突然增大.
  2. redis并没有出现大量的key过期.
  3. redis正常平稳运行, 而数据库挂了.
可能情况
  1. redis某个key过期了, 而此大量访问使用这个key.
解决方案
  1. 预先设置热门数据, 提前添加这些输入到redis中.
  2. 实时调整, 现场监控哪些热门书, 实时调整key的过期时间
  3. 使用锁:
    1. 在缓存失效的时候, 不是立刻去load db.
    2. 先使用缓存工具的某些带成功操作返回值的操作(比如redis的setnx).
    3. 当操作成功时, 在进行load db呃的操作, 并回设缓存, 最后删除mutex key.
    4. 当操作返回失败, 证明有线程在load db, 当前线程睡眠一段时间再重试整个get缓存的方法.

缓存雪崩

问题分析
  1. 数据库压力变大, 服务器崩溃
现象
  1. 在极少时间段, 出现大量key集中过期的情况.
解决方案
  1. 构建多级缓存架构, nginx + redis + 其他缓存.
  2. 使用锁或队列: 最有效, 但是效率也极低, 不适合高并发情况.
  3. 设置过期标志更新缓存: 缓存快过期时触发另外的线程, 让它去更新key的缓存.
  4. 让缓存失效时间分散开.