有三类基本问题

  1. 缓存穿透;
  2. 缓存击穿;
  3. 缓存雪崩

缓存穿透(Cache Penetration)

定义

缓存穿透是指请求的数据在缓存和底层数据库中都不存在,导致每次请求都会绕过缓存直接访问数据库,使数据库承受过大压力

发生原因

  • 查询不存在的数据
  • 恶意攻击(如发送大量ID为-1的请求)
  • 缓存设计不当,未缓存空结果2

解决方法

  1. 布隆过滤器:快速判断请求的数据是否存在

  2. 缓存空结果:为不存在的数据设置空缓存值,并给予较短的TTL

缓存击穿(Cache Breakdown/Stampede)

定义

缓存击穿指的是某个热点数据缓存过期的同时,大量请求并发访问该数据,导致这些请求绕过缓存直接访问数据库,对数据库造成瞬时压力13

发生原因

  • 热点数据的缓存恰好过期
  • 同时有大量请求访问这个热点数据

解决方法

  1. 互斥锁:第一个请求获取锁并更新缓存,其他请求等待
  2. 热点数据预热:定期刷新热点数据缓存
  3. 热点数据不设置过期时间,或者设置一个比较长的时间。

缓存雪崩(Cache Avalanche)

定义

缓存雪崩是指大量缓存同时失效或缓存服务器宕机,导致大量请求直接访问数据库,使数据库被巨大压力压垮,引发系统级联故障

发生原因

  • Redis服务器宕机
  • 大量缓存在同一时间过期
  • 重启后面对堆积的请求,可能再次导致系统崩溃

解决方法

  1. 随机过期时间:设置不同的缓存 TTL,避免同时过期
  2. Redis 高可用架构:使用 Redis 集群或哨兵模式
  3. 熔断机制:当检测到缓存服务异常时,暂时阻断对数据库的请求,返回降级结果
  4. 服务降级:当检测到系统出现缓存雪崩的迹象时,对一些非核心业务进行服务降级,暂时关闭或限制部分不重要的业务功能,减少对数据库的请求压力,保证核心业务的正常运行。

布隆过滤器详解

什么是布隆过滤器?

布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,由Burton Howard Bloom在1970年提出。它用于快速判断一个元素是否可能存在于集合中,具有极低的内存占用和常量级的查询时间复杂度12

关键特点是:布隆过滤器可能会告诉你一个不在集合中的元素误判为存在(称为”假阳性”),但绝不会将一个存在于集合中的元素误判为不存在(不会有”假阴性”)。用专业术语说就是:可能有假阳性,但绝不会有假阴性

工作原理

布隆过滤器的核心结构非常简单:一个很长的位数组(bit array)和多个哈希函数

布隆过滤器的数学原理

布隆过滤器的假阳性率与以下因素相关1:

  • m: 位数组大小
  • k: 使用的哈希函数数量
  • n: 预计插入的元素数量

假阳性率计算公式:(1 - e^(-kn/m))

理想情况下,当 k = (m/n)ln(2) 时,假阳性率最小。

布隆过滤器的优点

  1. 空间效率极高:每个元素只需要几个比特位,而不是存储元素本身5
  2. 查询时间复杂度O(k):k是哈希函数数量,通常是个小常数
  3. 插入时间复杂度O(k):同样是哈希函数数量
  4. 可以处理大规模数据集:即使有数十亿元素,内存占用也很小
  5. 支持并行操作:不同元素的插入和查询可以并行化1

布隆过滤器的局限性

  1. 不支持删除操作:标准布隆过滤器无法安全删除元素(但有变种如计数布隆过滤器可以支持)
  2. 存在假阳性:可能误报元素存在,误报率取决于位数组大小、元素数量和哈希函数数量
  3. 无法获取具体元素:只能判断成员资格,不能列举成员

布隆过滤器变种

  1. 计数布隆过滤器(Counting Bloom Filter):将位扩展为计数器,支持删除操作23
  2. 可扩展布隆过滤器(Scalable Bloom Filter):自动调整大小以保持误判率23
  3. 布谷鸟过滤器(Cuckoo Filter):更高效且支持删除操作的替代方案
  4. 空间布隆过滤器(Spatial Bloom Filter):专为地理空间数据设计的变种