亿级流量下的缓存架构设计:Redis+Caffeine多级缓存实战
一、为什么需要多级缓存?
在亿级流量场景下,单纯依赖Redis会遇到三大瓶颈:
-
网络延迟:Redis远程访问通常需要1-5ms,QPS超过10万时成为瓶颈
-
资源成本:高频读取导致Redis CPU飙升至80%+
-
可用性风险:Redis集群故障时数据库直接被击穿
多级缓存架构正是破局关键:
二、Caffeine+Redis核心架构设计
2.1 组件定位
组件 | 特性 | 适用场景 |
---|---|---|
Caffeine | 进程内缓存,访问速度纳秒级 | 高频热key(如秒杀商品) |
Redis | 分布式缓存,数据一致性高 | 全量数据缓存层 |
2.2 数据流转流程
public Product getProduct(Long id) {// 1. 查询CaffeineProduct product = caffeineCache.getIfPresent(id);if (product != null) {return product; }// 2. 查询Redis(加分布式锁防击穿)product = redisUtil.getWithLock("product:" + id, lockKey -> loadFromDB(id), // 缓存未命中时查DB3, TimeUnit.SECONDS);// 3. 回填Caffeine(设置短过期时间)caffeineCache.put(id, product, 30, TimeUnit.SECONDS);return product;
}
三、关键技术实现
3.1 Caffeine高效配置
Caffeine<Object, Object> caffeine = Caffeine.newBuilder().maximumSize(10_000) // 基于容量淘汰.expireAfterWrite(30, TimeUnit.SECONDS) // 写后过期.refreshAfterWrite(5, TimeUnit.SECONDS) // 异步刷新.recordStats(); // 开启监控统计LoadingCache<Long, Product> cache = caffeine.build(id -> {// 异步加载函数(避免阻塞请求线程)return loadFromRedis(id);
});
3.2 Redis热点Key处理
// 使用Redis集群分片+本地缓存分摊压力
public Product getProduct(Long id) {int slot = id % 100; // 分片逻辑String key = "product:" + slot + ":" + id;// 先读本地缓存再读Redis...
}
3.3 缓存一致性保障
双删策略+版本号控制:
// 更新数据时
public void updateProduct(Product product) {// 1. 更新数据库db.update(product);// 2. 删除Redis(失败重试3次)redis.deleteWithRetry("product:"+product.getId());// 3. 延迟500ms二次删除(防旧数据回填)scheduleTask(() -> {redis.delete("product:"+product.getId());caffeine.invalidate(product.getId());}, 500);// 4. 设置版本号(解决并发更新)redis.incr("version:"+product.getId());
}
四、性能压测对比
使用JMeter模拟100万QPS:
方案 | 平均响应时间 | Redis CPU | 数据库QPS |
---|---|---|---|
纯Redis | 12ms | 92% | 1800 |
多级缓存 | 1.8ms | 35% | <10 |
性能提升点:
-
99%的热点请求被Caffeine拦截
-
Redis负载下降60%
五、避坑指南
缓存污染问题
解决方案:Caffeine配置weakKeys+softValues
.weakKeys().softValues() // 启用弱引用+软引用
冷启动雪崩
预热方案:使用Guava的CacheLoader预加载热数据
CacheLoader.asyncReloading((id) -> loadFromDB(id), executor)
监控告警体系
// 通过Micrometer暴露指标
CaffeineMetrics.monitor(monitorRegistry, cache, "productCache");
监控看板需包含:
Caffeine命中率(Hit Ratio)
Redis连接池等待时间
六、扩展优化方向
热点探测:基于Redis的hotkeys命令动态识别热数据
分级存储:
-
L1:Caffeine(最新数据)
-
L2:Redis(全量数据)
-
L3:磁盘缓存(历史数据)
流量调度:根据用户IP路由到就近缓存节点