我选择懒加载+缓存预热+热点key隔离的组合方案。这种方案在实际生产环境中效果最好,能有效避免缓存穿透和雪崩,同时提升整体效率。首先实现懒加载:用户请求时先查缓存,miss则查DB并回写缓存;然后预热热门数据,开机时批量加载到Redis;最后对热点key用独立实例隔离,防止单点故障。代码示例:使用Spring Cache注解简化懒加载,结合定时任务预热。
方案一:懒加载(Cache Aside)
懒加载是最常见的Redis缓存模式,也叫Cache Aside模式。核心思想是读请求时,先从Cache取数据,如果Cache命中,直接返回;Cache未命中时,从数据库查询数据,然后将数据写入Cache,再返回给用户。这种方式简单高效,但要注意缓存穿透问题,可以用布隆过滤器解决。
方案二:读写穿透(Read/Write Through)
读写穿透模式由Cache和数据库两层组成,Cache作为主存储,数据库作为备份存储。应用层只与Cache交互,Cache自己负责与数据库的交互。这种模式的优势是简化了应用层的缓存逻辑,但引入了额外的Cache服务,增加了系统复杂度,不适合所有场景。
方案三:写回缓存(Write Back)& 写穿缓存(Write Through)
写回缓存:应用写数据时,直接写入Cache,异步批量更新数据库。优点:写性能高,缺点:数据一致性差,可能丢失数据。写穿缓存:应用写数据时,同时写入Cache和数据库。优点:数据一致性强,缺点:写性能低。通常结合懒加载使用。
缓存预热
缓存预热就是系统刚启动前,提前将一定的数据加载到缓存中,避免冷启动时大量请求打到数据库上。实现方式:1. 重启后手动触发预热脚本;2. 项目启动时自动执行预热任务;3. 通过定时任务定期预热热点数据。
热点key隔离
热点key会被大量并发请求,导致该key对应的单节点压力过大,乃至成为整体缓存服务的瓶颈。解决方案:1. 本地缓存热点数据;2. 多级缓存(Nginx本地缓存+Redis);3. 热点key使用独立Redis实例;4. 热点数据分片存储。
缓存过期策略
1. 定期清理:Redis每100ms检查一次,删除过期key,适用于小内存Redis。2. 惰性删除:访问key时检查是否过期,过期删除,适用于内存较大的情况。3. 内存淘汰策略:主动清理不活跃数据,如LRU、LFU、随机等。建议组合使用定期清理+惰性删除+内存淘汰。
FAQ
Q: 懒加载和预热哪个更好?
A: 懒加载适合冷数据,预热适合热点数据,二者结合使用效果最佳。
Q: 如何防止缓存雪崩?
A: 设置不同过期时间+热点隔离+限流熔断。
Q: Redis内存满了怎么办?
A: 配置maxmemory和淘汰策略,如allkeys-lru。
Q: 缓存穿透怎么解决?
A: 布隆过滤器+空值缓存+参数校验。