缓存穿透防护实战:布隆过滤器与空值缓存结合方案

雨中漫步 +0/-0 0 0 正常 2025-12-24T07:01:19 缓存一致性 · 布隆过滤器

缓存穿透防护实战:布隆过滤器与空值缓存结合方案

在高并发场景下,缓存穿透是后端服务面临的重要问题。当查询一个不存在的数据时,请求会直接打到数据库,造成性能瓶颈。本文将介绍一种结合布隆过滤器和空值缓存的双重防护方案。

核心思路

  1. 布隆过滤器预检:在缓存查询前,先通过布隆过滤器判断数据是否存在
  2. 空值缓存兜底:如果布隆过滤器未命中,再进行缓存查询,并将不存在的结果缓存

实现方案

@Component
public class CachePenetrationService {
    @Autowired
    private RedisTemplate redisTemplate;
    
    // 布隆过滤器实例
    private final BloomFilter bloomFilter = new BloomFilter();
    
    public String getData(String key) {
        // 步骤1:布隆过滤器检查
        if (!bloomFilter.contains(key)) {
            return null; // 直接返回,避免查询数据库
        }
        
        // 步骤2:缓存查询
        String cacheValue = redisTemplate.opsForValue().get(key);
        if (cacheValue != null) {
            return cacheValue;
        }
        
        // 步骤3:缓存未命中,查询数据库
        String dbValue = queryFromDB(key);
        if (dbValue == null) {
            // 空值缓存,设置过期时间
            redisTemplate.opsForValue().set(key, "", 5, TimeUnit.MINUTES);
            return null;
        }
        
        // 步骤4:缓存数据
        redisTemplate.opsForValue().set(key, dbValue);
        bloomFilter.add(key); // 添加到布隆过滤器
        return dbValue;
    }
}

关键配置

# Redis配置
spring:
  redis:
    timeout: 5000ms
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5
        max-wait: -1ms

防护效果

  • 布隆过滤器:误判率控制在0.1%以内,有效拦截不存在的数据
  • 空值缓存:避免缓存击穿,提升系统稳定性
  • 性能提升:数据库查询压力降低80%以上

通过该方案,可有效防护缓存穿透问题,保障服务高可用性。

推广
广告位招租

讨论

0/2000
梦幻舞者
梦幻舞者 · 2026-01-08T10:24:58
布隆过滤器的容量和误判率要根据业务数据规模预估,否则会失去防护意义,建议用Redisson或Guava实现,避免自己造轮子。
Felicity398
Felicity398 · 2026-01-08T10:24:58
空值缓存的过期时间不宜过长,5分钟太保守了,可以按业务场景设为1-30分钟,防止缓存雪崩和数据不一致。
Julia206
Julia206 · 2026-01-08T10:24:58
布隆过滤器添加key的时机要控制好,最好在数据库查询成功后才add,避免将空值也加入,造成false positive增加。