Redis动态热点数据缓存策略设计

Redis动态热点数据缓存策略设计

1. 热点数据识别机制

1.1 计数器方式

java 复制代码
@Service
public class HotDataCounter {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 访问计数
    public void incrementCounter(String key) {
        String countKey = "counter:" + key;
        redisTemplate.opsForValue().increment(countKey, 1);
        // 设置计数器过期时间,比如1小时
        redisTemplate.expire(countKey, 1, TimeUnit.HOURS);
    }

    // 获取访问次数
    public Long getCounter(String key) {
        String countKey = "counter:" + key;
        return (Long) redisTemplate.opsForValue().get(countKey);
    }
}

1.2 LRU算法实现

java 复制代码
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int capacity;

    public LRUCache(int capacity) {
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity;
    }
}

2. 动态缓存策略实现

2.1 基础缓存服务

java 复制代码
@Service
public class DynamicCacheService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private HotDataCounter hotDataCounter;
    // 热点阈值
    private static final long HOT_THRESHOLD = 100;

    // 获取数据
    public Object getData(String key) {
        // 增加访问计数
        hotDataCounter.incrementCounter(key);
        // 从缓存获取数据
        Object value = redisTemplate.opsForValue().get(key);
        if (value != null) {
            return value;
        }
        // 从数据库获取数据
        value = getFromDB(key);
        // 判断是否为热点数据
        if (isHotData(key)) {
            // 热点数据设置较长的过期时间
            redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
        } else {
            // 非热点数据设置较短的过期时间
            redisTemplate.opsForValue().set(key, value, 5, TimeUnit.MINUTES);
        }
        return value;
    }

    // 判断是否为热点数据
    private boolean isHotData(String key) {
        Long count = hotDataCounter.getCounter(key);
        return count != null && count > HOT_THRESHOLD;
    }
}

2.2 定时任务更新策略

java 复制代码
@Component
public class HotDataScheduler {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void updateHotData() {
        // 获取所有计数器
        Set<String> counterKeys = redisTemplate.keys("counter:");
        if (counterKeys == null) return;
        // 更新热点数据过期时间
        for (String counterKey : counterKeys) {
            String dataKey = counterKey.substring("counter:".length());
            Long count = (Long) redisTemplate.opsForValue().get(counterKey);
            if (count != null && count > HOT_THRESHOLD) {
                // 延长热点数据过期时间
                redisTemplate.expire(dataKey, 1, TimeUnit.HOURS);
            }
        }
    }
}

3. 多级缓存策略

3.1 本地缓存配合Redis

java 复制代码
@Service
public class MultiLevelCache {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    // 本地缓存
    private final LoadingCache<String, Object> localCache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build(new CacheLoader<String, Object>() {
                @Override
                public Object load(String key) {
                    return getFromRedis(key);
                }
            });

    public Object get(String key) {
        try {
            return localCache.get(key);
        } catch (ExecutionException e) {
            return getFromRedis(key);
        }
    }

    private Object getFromRedis(String key) {
        Object value = redisTemplate.opsForValue().get(key);
        if (value == null) {
            value = getFromDB(key);
            if (value != null) {
                redisTemplate.opsForValue().set(key, value);
            }
        }
        return value;
    }
}

4. 热点数据预加载

4.1 预热服务

java 复制代码
@Service
public class HotDataPreloader {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @PostConstruct
    public void preloadHotData() {
        // 从统计数据中获取历史热点数据
        List<String> historicalHotKeys = getHistoricalHotKeys();
        // 预加载数据到Redis
        for (String key : historicalHotKeys) {
            Object value = getFromDB(key);
            if (value != null) {
                redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
            }
        }
    }
}

5. 缓存更新策略

5.1 更新服务

java 复制代码
@Service
public class CacheUpdateService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 更新缓存数据
    @Transactional
    public void updateData(String key, Object value) {
        // 更新数据库
        updateDB(key, value);
        // 判断是否为热点数据
        if (isHotData(key)) {
            // 直接更新缓存
            redisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
        } else {
            // 删除缓存
            redisTemplate.delete(key);
        }
    }
}

6. 监控和告警

6.1 监控服务

java 复制代码
@Service
public class CacheMonitorService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 监控缓存命中率
    public double getHitRate() {
        Long hits = (Long) redisTemplate.opsForValue().get("cache:hits");
        Long misses = (Long) redisTemplate.opsForValue().get("cache:misses");
        if (hits == null || misses == null) {
            return 0.0;
        }
        return (double) hits / (hits + misses);
    }

    // 记录缓存访问
    public void recordAccess(boolean isHit) {
        String key = isHit ? "cache:hits" : "cache:misses";
        redisTemplate.opsForValue().increment(key, 1);
    }
}

7. 配置管理

7.1 动态配置

java 复制代码
@Configuration
@RefreshScope
public class CacheConfig {
    @Value("${cache.hot.threshold:100}")
    private long hotThreshold;
    @Value("${cache.hot.expire:3600}")
    private long hotExpireSeconds;
    @Value("${cache.normal.expire:300}")
    private long normalExpireSeconds;

}

8. 总结

  1. 热点识别

    • 使用计数器记录访问频率
    • 实现LRU算法管理缓存
  2. 动态缓存

    • 根据访问频率动态调整过期时间
    • 定时任务更新热点数据
  3. 多级缓存

    • 本地缓存配合Redis
    • 减少网络开销
  4. 预加载机制

    • 系统启动时预加载历史热点数据
    • 提高系统启动后的访问性能
  5. 更新策略

    • 热点数据直接更新缓存
    • 非热点数据采用删除策略
  6. 监控告警

    • 监控缓存命中率
    • 记录访问统计
  7. 配置管理

    • 支持动态调整配置
    • 灵活控制缓存策略
相关推荐
海梨花2 小时前
【从零开始学习Redis】项目实战-黑马点评D2
java·数据库·redis·后端·缓存
小兔兔吃萝卜4 小时前
Spring 创建 Bean 的 8 种主要方式
java·后端·spring
AAA修煤气灶刘哥5 小时前
面试官: SpringBoot自动配置的原理是什么?从启动到生效,一文讲透
后端·spring·面试
qq_三哥啊7 小时前
【IDEA】设置Debug调试时调试器不进入特定类(Spring框架、Mybatis框架)
spring·intellij-idea·mybatis
别惹CC8 小时前
Spring AI 进阶之路01:三步将 AI 整合进 Spring Boot
人工智能·spring boot·spring
寒士obj8 小时前
Spring事物
java·spring
IT毕设实战小研16 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
甄超锋17 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
鼠鼠我捏,要死了捏18 小时前
生产环境Redis缓存穿透与雪崩防护性能优化实战指南
redis·cache
Java小白程序员21 小时前
Spring Framework:Java 开发的基石与 Spring 生态的起点
java·数据库·spring