高并发场景下的缓存雪崩探析与应对策略

目录

一、问题描述

二、解决策略分析

(一)解决策略一:分散过期时间

(二)解决策略二:提前演练压测

[(三)解决策略三:cache高可用 + 后端数据库限流](#(三)解决策略三:cache高可用 + 后端数据库限流)

三、总结


干货分享,感谢您的阅读!

在高并发场景下,缓存作为前置查询机制,显著减轻了数据库的压力,提高了系统性能。然而,这也带来了缓存失效、增加回溯率等风险。常见的问题包括缓存穿透、缓存雪崩、热Key和大Key等。这些问题如果不加以处理,会影响系统的稳定性和性能。因此,采用有效的缓存策略,如缓存空结果、布隆过滤器、缓存过期时间随机化、多级缓存等,对于保障系统在高并发情况下的可靠性至关重要。本次我们将详细探讨缓存雪崩及其应对策略。

一、问题描述

缓存层挡在db层前面,抗住了非常多的流量,在分布式系统中,"everything will fails",缓存作为一种资源,当cache crash后,流量集中涌入下层数据库,称之为缓存雪崩。

造成这种问题通常有2种原因:

  1. 业务层面:大量的缓存key同时失效,失效请求全部回源到数据库,造成数据库压力过大崩溃。
  2. 系统层面:缓存服务宕机。

二、解决策略分析

(一)解决策略一:分散过期时间

业务层面的原因,主要是缓存key过期时间一致,造成同一时间,大量缓存key同时失效。针对这种问题的解决方案,主要是防止缓存在同一时间一起过期,如在设置的过期时间的基础上增加1-5分钟的随机值,使缓存失效时间比较均匀。通过这种方式,可以避免缓存key在同一时间失效,进而防止大量请求同时回溯到数据库。

java 复制代码
import java.util.Random;

public class CacheManager {
    private static final Random RANDOM = new Random();

    // 设置缓存值并增加随机过期时间
    public void setCache(String key, Object value, int baseExpirationTimeInSeconds) {
        int randomOffset = RANDOM.nextInt(300); // 1-5分钟的随机值,单位是秒
        int finalExpirationTime = baseExpirationTimeInSeconds + randomOffset;
        // 这里假设使用的是某个缓存框架的set方法
        cache.set(key, value, finalExpirationTime);
    }
}

(二)解决策略二:提前演练压测

系统在实际运行中可能会遇到各种性能瓶颈,提前演练和压测可以帮助发现这些瓶颈并进行优化。

在系统上线前,进行充分的压力测试和演练,找出系统的性能瓶颈,预估合适的系统存储和计算容量。根据压测结果,调整系统架构和配置,确保在高并发情况下系统能够稳定运行。

(三)解决策略三:cache高可用 + 后端数据库限流

  • 采用双缓存热备份方案来进可能提升缓存资源的可用性
  • 后端数据库限流(Hystrix),缓存层宕机,流量集中打到数据库,会再次让db崩溃。为保护这种情况下的db,在db层加入限流(Hystrix)

具体实现如下:

java 复制代码
public class CacheSupplier {

    @Qualifier(value = "tairCache")
    @Autowired
    private HACache tair;

    @Qualifier(value = "squirrelCache")
    @Autowired
    private HACache squirrel;

    @Autowired
    private CacheConfig cacheConfig;

    // 当前主备缓存引用,默认 master(squirrel) slave(celler)
    private CachePair cachePair;

    public CachePair getCachePair() {
        if (!cacheConfig.isCacheOn()) {
            return null;
        }
        if (cachePair != null && !cacheConfig.changed()) {
            return cachePair;
        }
        return updateCachePair();
    }

    private synchronized CachePair updateCachePair() {
        if (cachePair == null || cacheConfig.changed()) {
            cacheConfig.getConfigLock().lock();
            try {
                cachePair = createCachePair();
                cacheConfig.unchanged();
            } finally {
                cacheConfig.getConfigLock().unlock();
            }
        }
        return cachePair;
    }

    private CachePair createCachePair() {
        CachePair cp = new CachePair();
        cp.setMaster(selectCache(cacheConfig.getMasterCache(), tair, squirrel));
        if (cacheConfig.isSlaveOn()) {
            cp.setSlave(selectCache(cacheConfig.getSlaveCache(), squirrel, tair));
        }
        return cp;
    }

    private HACache selectCache(String cacheName, HACache defaultCache1, HACache defaultCache2) {
        if (CacheConfig.TAIR.equals(cacheName)) {
            return tair;
        } else if (CacheConfig.SQUIRREL.equals(cacheName)) {
            return squirrel;
        } else {
            return defaultCache1 != null ? defaultCache1 : defaultCache2;
        }
    }
}

三、总结

缓存雪崩作为高并发场景下的一个典型问题,严重威胁着系统的稳定性和性能。当缓存层失效或服务宕机时,大量请求会直接涌入数据库,造成数据库负载过重甚至崩溃。因此,采取有效的应对策略至关重要。

本文首先明确了缓存雪崩的定义及其两种主要成因,即业务层面的大量缓存key同时失效和系统层面的缓存服务宕机。针对这些成因,提出了三种解决策略:

  1. 分散过期时间:通过在设置的过期时间基础上增加随机值,使缓存失效时间均匀分布,避免大量请求同时回溯到数据库。
  2. 提前演练压测:通过充分的压力测试和演练,找出系统的性能瓶颈,并在系统上线前进行优化,确保系统在高并发情况下的稳定运行。
  3. cache高可用和后端数据库限流:采用双缓存热备份方案提升缓存资源的可用性,并在数据库层加入限流机制,防止缓存层宕机时流量集中打到数据库,进而保护数据库的稳定性。

这些策略各有优劣,结合具体业务场景和系统特点,灵活运用这些策略可以有效防止缓存雪崩。

相关推荐
佛祖让我来巡山1 天前
Redis 为什么这么快?——「极速快递站」的故事
redis·redis为什么快?
惊讶的猫1 天前
AMQP 与 RabbitMQ 四大模型
分布式·rabbitmq
灰子学技术1 天前
istio从0到1:如何解决分布式配置同步问题
分布式·云原生·istio
小马爱打代码1 天前
ZooKeeper:入门实战
分布式·zookeeper·云原生
啦啦啦_99991 天前
Redis-0-业务逻辑
数据库·redis·缓存
自不量力的A同学1 天前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
永远都不秃头的程序员(互关)1 天前
CANN赋能AIGC分布式训练:硬核通信,加速大模型智能生成新纪元
分布式·aigc
fengxin_rou1 天前
[Redis从零到精通|第四篇]:缓存穿透、雪崩、击穿
java·redis·缓存·mybatis·idea·多线程
fengxin_rou1 天前
黑马点评实战篇|第二篇:商户查询缓存
缓存
是阿楷啊1 天前
Java大厂面试场景:音视频场景中的Spring Boot与微服务实战
spring boot·redis·spring cloud·微服务·grafana·prometheus·java面试