短视频全套源码,解决缓存击穿的常用方案

云豹科技-苏凌霄 / 2024-09-21 / 原文

短视频全套源码,解决缓存击穿的常用方案

一、设置合理的过期时间

固定过期时间:为短视频全套源码中的热点数据设置一个合理的固定过期时间,可以有效地减少数据库的访问频率,但不能完全避免缓存击穿问题。
随机过期时间:通过为短视频全套源码中的缓存设置不同的随机过期时间,可以使缓存失效的时间点分散,减少同时大量请求数据库的概率。

@Autowired
private StringRedisTemplate redisTemplate;

public String getDataWithRandomExpiration(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        value = fetchDataFromDatabase(key);
        // 设置一个5到10分钟的随机过期时间
        long timeout = 5L + new Random().nextInt(5);
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.MINUTES);
    }
    return value;
}

private String fetchDataFromDatabase(String key) {
    return "database-value";
}

 

二、使用互斥锁

单体应用中的互斥锁:在访问数据库前,使用 Java 的 synchronized 关键字或 ReentrantLock 类实现互斥锁。
分布式环境的互斥锁:使用 Redis 的 SETNX 命令实现分布式锁,确保同一时间只有一个请求去短视频全套源码数据库中查询数据并更新缓存。

@Autowired
private StringRedisTemplate redisTemplate;

public String getDataWithLock(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        String lockKey = "lock:" + key;
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
        if (Boolean.TRUE.equals(acquired)) {
            try {
                value = redisTemplate.opsForValue().get(key);
                if (value == null) {
                    value = fetchDataFromDatabase(key);
                    redisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES);
                }
            } finally {
                redisTemplate.delete(lockKey);
            }
        }
    }
    return value;
}

 

三、布隆过滤器

使用布隆过滤器预先判断请求的数据是否可能存在于短视频全套源码的数据库中,这样可以避免对不存在的数据进行大量的数据库查询,减少数据库的无效访问。

@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private BloomFilter<String> bloomFilter;

public String getDataWithBloomFilter(String key) {
    if (!bloomFilter.mightContain(key)) {
        return null;  // 假设数据不在数据库中
    }
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        value = fetchDataFromDatabase(key);
        redisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES);
    }
    return value;
}

 

四、永不过期策略

对于短视频全套源码中某些极为重要的热点数据,可以考虑将它们设置为永不过期,同时通过后台线程定期更新这些数据。这种策略虽然保持数据的实时性不如上述方法,但可以最大限度防止数据库的突发访问压力。

@Autowired
private StringRedisTemplate redisTemplate;

public String getAlwaysValidData(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        value = fetchDataFromDatabase(key);
        redisTemplate.opsForValue().set(key, value);  // 没有设置过期时间
    }
    return value;
}

 

以上就是短视频全套源码,解决缓存击穿的常用方案, 更多内容欢迎关注之后的文章