多级缓存设计:从 CPU 到分布式缓存的层层加速

多级缓存设计:从 CPU 到分布式缓存的层层加速

什么是多级缓存

多级缓存(Multi-Level Cache)是一种分层缓存架构,将不同速度、不同容量、不同成本的存储介质组织成缓存层级。请求从最快的层级开始查询,逐级向下,直到找到数据或最终回源数据库。

典型的互联网系统采用三级缓存架构:

浏览器缓存 → CDN 缓存 → Nginx 本地缓存 → 应用本地缓存 → Redis 分布式缓存 → 数据库

为什么需要多级缓存

单一种类的缓存总有短板:

缓存类型 速度 容量 成本 分布式
本地内存 纳秒级 GB 级
Redis 毫秒级 百 GB 级
数据库 毫秒~秒级 无限

多级缓存用空间换时间,用成本换性能

经典三级缓存架构

第一级:本地缓存(L1)

使用 Caffeine/Guava Cache/Ehcache,存储在应用进程内,速度极快(微秒级):

@Bean
public Cache<String, Product> localCache() {
    return Caffeine.newBuilder()
        .maximumSize(10_000)
        .expireAfterWrite(5, TimeUnit.SECONDS)   // 短 TTL 保证新鲜度
        .recordStats()
        .build();
}

优点:无网络开销,速度最快
缺点:容量有限、重启丢失、多副本不一致

第二级:分布式缓存(L2)

Redis/Memcached,统一集群,所有应用节点共享:

public Product getProduct(Long id) {
    // 先查本地缓存
    Product product = localCache.getIfPresent(id);
    if (product != null) return product;

    // 本地未命中,查 Redis
    String json = redis.opsForValue().get("product:" + id);
    if (json != null) {
        product = JSON.parseObject(json, Product.class);
        localCache.put(id, product);  // 回填本地缓存
        return product;
    }

    // 都未命中,查数据库
    product = productDao.findById(id);
    redis.opsForValue().set("product:" + id, JSON.toJSONString(product), 30, TimeUnit.MINUTES);
    localCache.put(id, product);
    return product;
}

第三级:数据库(L3)

最终数据源,做好保护:读库、限流、连接池管理。

多级缓存的一致性问题

更新难题

数据发生变更时,需要同时更新/失效多个缓存层级:

public void updateProduct(Product product) {
    productDao.update(product);                   // 更新数据库
    redis.delete("product:" + product.getId());   // 删除 Redis 缓存
    localCache.invalidate(product.getId());       // 失效本地缓存
}

本地缓存一致性方案

  1. 短 TTL:本地缓存 TTL 设为 5-10 秒,容忍短暂不一致
  2. 消息通知失效:更新时发送 MQ 消息,所有节点消费后失效本地缓存
  3. Redis 订阅 + 本地监听:使用 Redis Key 失效事件的订阅机制

缓存的过期联动

建议不同层级的 TTL 呈递进关系:

L1 本地缓存:3~5 秒(最快感知变化)
L2 Redis:  15~30 分钟(兜底,保护数据库)
L3 数据库: 持久化(最终数据源)

多级缓存的挑战

缓存穿透放大

如果数据不存在,每一级都要查一遍。解决方案:布隆过滤器在 L1 前拦截。

内存压力

每个应用节点都存一份本地缓存,需要精确估算内存占用。

热点数据感知

不是所有数据都适合进入本地缓存。需要识别真正的热点:

// 记录访问频率,热点自动升级到本地缓存
public Product getSmart(Long id) {
    // 访问频率低,直接从 Redis 查
    if (!isHotKey(id)) {
        return getFromRedis(id);
    }
    // 热点数据走多级缓存
    return getFromMultiLevel(id);
}

几种常见架构对比

架构 适用场景 延迟 复杂度
单 Redis 中小系统 ~10ms
本地+Redis 高并发读 ~1μs+1ms
CDN+Nginx+Redis+DB 大规模互联网 动态
数据库查询缓存 低并发 ~100μs 极低

面试要点

  • 多级缓存的核心思想是用距离换速度,越靠近 CPU 越快但也越贵
  • 能说清三级缓存的典型架构:本地缓存 → Redis → 数据库
  • 一致性是最难的考点:短 TTL + 消息失效 + 驱逐监听
  • 本地缓存不是所有数据都适合,只有热点数据 + 读多写少才值得
  • 能提到”布隆过滤器防穿透”是高级思维
© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容