缓存降级方案:当缓存扛不住时的求生策略
什么是缓存降级
缓存降级(Cache Degradation)是指当缓存系统或后端服务出现异常、负载过高、资源不足时,主动牺牲一部分非核心功能或数据质量,以保障核心功能可用的策略。简单说就是:”保核心,弃非核心”。
降级的触发场景
| 触发条件 | 具体表现 | 风险等级 |
|---|---|---|
| Redis 高负载 | 延迟飙升、CPU 打满 | 高 |
| 缓存大面积失效 | 雪崩,请求穿透 | 高 |
| 数据库压力过大 | DB 连接池耗尽 | 高 |
| 网络异常 | 缓存不可达 | 中 |
| 内存不足 | OOM 或淘汰 eviction | 中 |
| 请求超量 | QPS 超过预估 | 中 |
常见的降级策略
1. 读降级
缓存不可用或慢加载时,直接读取数据库的降级副本或静态数据:
public User getUser(String userId) {
try {
String cached = redis.opsForValue().get("user:" + userId);
if (cached != null) return JSON.parseObject(cached, User.class);
} catch (Exception e) {
log.warn("Redis异常,触发读降级", e);
}
// 降级到数据库
return userDao.findById(userId);
}
更进一步:数据库也扛不住时,降级到本地缓存甚至返回”数据暂时不可用”的兜底数据。
2. 写降级
缓存写入异常时,暂时绕过缓存直接写数据库,或使用异步队列暂存:
public void updateUser(User user) {
try {
userDao.update(user);
redis.opsForValue().set("user:" + user.getId(), JSON.toJSONString(user));
} catch (CacheException e) {
log.warn("缓存写入失败,降级为仅写数据库");
// 即使缓存写入失败,数据库写入已完成,不影响核心流程
}
}
3. 功能降级
关闭非核心功能以释放资源给核心链路:
- 一级降级:关闭首页推荐、个性化展示,使用通用数据
- 二级降级:关闭社区、评论等非核心模块
- 三级降级:关闭搜索、筛选功能,只保留基础浏览
4. 数据降级
用低质量数据替代高质量数据:
// 正常逻辑:从缓存获取完整商品详情
// 降级逻辑:只返回基础信息
public Product getProduct(Long id) {
try {
return getFullProduct(id);
} catch (Exception e) {
// 降级:只返回必要的字段
return getBasicProduct(id);
}
}
降级实现方式
手动降级开关
通过配置中心(Apollo/Nacos)动态控制降级策略:
@Value("${degrade.redis.enabled:false}")
private boolean redisDegradeEnabled;
public String get(String key) {
if (redisDegradeEnabled) {
return loadFromDB(key); // 跳过缓存
}
return getFromCache(key);
}
自动熔断降级
结合 Hystrix/Resilience4j/Sentinel 实现自动降级:
@SentinelResource(value = "getUser", fallback = "getUserFallback")
public User getUser(String id) {
// 正常缓存查询
}
public User getUserFallback(String id, Throwable t) {
// 降级逻辑:返回本地缓存的旧数据
return localCache.get("user:" + id);
}
渐进式降级
根据负载程度逐级降低服务质量:
负载<60% → 全功能
负载60-80% → 关闭非核心功能 + 缩短缓存过期时间
负载80-90% → 关闭写缓存 + 只读取本地缓存
负载90%+ → 限流 + 返回兜底数据
降级注意事项
- 可还原性:降级后要能平滑恢复,避免恢复瞬间打挂系统
- 流量控制:降级恢复时要逐步放量,配合限流
- 监控告警:降级触发和恢复都需要记录日志并告警
- 用户体验:降级时给用户的反馈要友好,比如"正在精简模式运行"
- 不需要持久化降级数据:降级数据往往使用短 TTL
面试要点
- 讲清缓存降级的本质是有损服务,核心是"保核心、弃非核心"
- 能说出至少三种降级策略(读降级、写降级、功能降级)
- 提到配置中心和熔断组件配合实现自动/手动降级
- 最好能举例:双十一大促期间,关闭商品评论模块,释放 Redis 资源给订单核心链路
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容