在数据库有100万数据但Redis只能存20万的情况下,我们需要确保Redis缓存的是最常被访问的数据(热点数据)。
# Redis配置
maxmemory 2GB # 设置最大内存
maxmemory-policy allkeys-lru # 使用LRU淘汰策略
工作原理:
maxmemory-policy allkeys-lfu # 使用LFU(最不经常使用)策略
优势:
用户请求 → 布隆过滤器 → Redis热点缓存 → 数据库
// 示例:监控并预热热点数据
public void preheatHotData() {
// 1. 从数据库统计最近24小时访问量TOP 20万
List<HotItem> hotItems = database.queryTopItems(200000);
// 2. 批量加载到Redis
hotItems.forEach(item ->
redisTemplate.opsForValue().set(item.key, item.value));
}
// 使用Redis的INCR记录访问次数
public void recordAccess(String key) {
// 记录键的访问次数
redisTemplate.opsForValue().increment("access:" + key);
// 定期(如每小时)整理热点数据
if(System.currentTimeMillis() % 3600000 == 0) {
// 获取访问量TOP 20万的键
Set<String> hotKeys = getTopKeys(200000);
// 更新热点缓存...
}
}
策略 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
LRU | 实现简单,内存友好 | 可能误判突发流量 | 通用场景 |
LFU | 识别长期热点更准 | 内存消耗稍大 | 热点稳定场景 |
主动预热 | 精确控制缓存内容 | 需要额外开发 | 已知热点分布 |
时间窗口 | 实时性高 | 实现复杂 | 访问模式变化快 |
组合使用策略:LRU/LFU + 定时任务预热
监控缓存命中率:
redis-cli info stats | grep keyspace_misses
redis-cli info stats | grep keyspace_hits
设置合理的TTL:即使热点数据也设置过期时间,避免脏数据
考虑分片:如果单Redis实例不够,可以按业务分片存储
小技巧:可以使用
redis-cli --hotkeys
命令(Redis 4.0+)快速找出当前热点键