缓存降级方案:当缓存扛不住时的求生策略

缓存降级方案:当缓存扛不住时的求生策略

什么是缓存降级

缓存降级(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%+ → 限流 + 返回兜底数据

降级注意事项

  1. 可还原性:降级后要能平滑恢复,避免恢复瞬间打挂系统
  2. 流量控制:降级恢复时要逐步放量,配合限流
  3. 监控告警:降级触发和恢复都需要记录日志并告警
  4. 用户体验:降级时给用户的反馈要友好,比如"正在精简模式运行"
  5. 不需要持久化降级数据:降级数据往往使用短 TTL

面试要点

  • 讲清缓存降级的本质是有损服务,核心是"保核心、弃非核心"
  • 能说出至少三种降级策略(读降级、写降级、功能降级)
  • 提到配置中心和熔断组件配合实现自动/手动降级
  • 最好能举例:双十一大促期间,关闭商品评论模块,释放 Redis 资源给订单核心链路
© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容