前言:作为Java后端开发者,Redis是项目中不可或缺的高性能缓存组件,核心作用是提升接口响应速度、降低数据库压力。但很多开发者只懂"用Redis存数据",却不清楚其底层缓存机制,也不会根据业务场景选择合适的缓存淘汰策略,导致生产环境中频繁出现内存溢出、缓存雪崩、服务卡顿等问题。
在前面有两篇Redis的相关文章有提到Redis的应用场景和核心特性"内存存储+高效管理",今天做一些补充:缓存淘汰策略是内存满时的"应急方案"------仅当Redis配置了maxmemory(最大内存限制)时,淘汰策略才会触发。生产环境必须配置该参数,否则Redis会无限制占用内存,最终导致服务器OOM。
一、Redis缓存机制核心原理
Redis缓存机制本质是"内存键值存储+持久化兜底+高效管理",核心围绕3个核心模块展开,兼顾高性能和数据安全性。
1. 内存键值存储
Redis以「键值对(key-value)」形式将数据存储在内存 中,这是其毫秒级响应的核心原因------避免了传统数据库的磁盘I/O耗时。我们有提过:Redis支持丰富的数据结构:核心支持 String、Hash、List、Set、ZSet(有序集合),还扩展了 Bitmap、HyperLogLog、Geo 等。
适配不同Java后端业务场景:
-
String:存储用户会话、验证码、接口临时结果(最常用);
-
Hash:存储商品详情、用户信息(字段可单独更新,节省内存);
-
List:存储消息队列、最新通知(如订单消息、系统公告);
-
Sorted Set:存储排行榜、热点数据排序(如商品销量排行)。
2. 数据持久化机制
由于Redis是内存存储的,为防止断电或重启后的数据丢失,Redis提供了两种数据持久化方式:RDB快照和AOF日志持久化。生产环境通常是组合起来采用RDB+AOF混合持久化模式,兼顾数据和性能安全。
-
RDB(快照持久化):每隔一段时间,将内存中的全量数据快照保存到磁盘(.rdb文件)。优点:体积小、恢复速度快,适合备份和批量恢复;缺点:可能丢失两次快照之间的数据(如1小时快照一次,宕机可能丢失1小时数据)。
-
AOF(日志持久化):记录每一次写操作(set、del等),重启时通过重放日志恢复数据。优点:数据丢失少(可配置每秒同步一次);缺点:日志文件体积大、恢复速度慢。
3. 缓存管理机制(核心:过期删除+内存淘汰)
由于内存是有限的,Redis不会一直只往内存塞东西,当内存达到maxmemory阈值时,会通过"过期删除策略+内存淘汰策略"清理无效数据,平衡内存占用、CPU开销和缓存命中率------这也是本文重点讲解的"缓存淘汰策略"的核心背景。
二、Redis缓存淘汰策略详解
以下淘汰策略基于Redis官网文档:
https://redis.io/docs/latest/operate/rs/databases/memory-performance/eviction-policy/
1. 按过期时间分类:
定期删除:Redis后台每隔100ms(默认),随机抽取一批过期key检查并删除,同时控制删除时间(避免阻塞主线程)。优点:弥补惰性删除不足,主动释放部分内存;缺点:无法删除所有过期key,仍有残留。
惰性删除:不主动删除过期key,只有客户端主动查询该key时,才检查是否过期:过期则删除并返回null,未过期则正常返回。优点:CPU友好,不占用额外CPU资源;缺点:内存不友好,大量过期key长期不被查询会导致"内存泄漏"。
2. 按内存淘汰策略分类:
当Redis内存达到maxmemory阈值时,触发内存淘汰策略,主动清理key释放内存。8种策略可分为3类,按生产使用率排序,重点掌握前5种常用策略:
---名词介绍---
-
volatile-*:仅淘汰「设置了过期时间(expire=true)」的key;
-
allkeys-*:淘汰「所有key」(无论是否设置过期时间);
-
noeviction:不淘汰任何key,内存满时直接拒绝写操作(慎用)。
-
LRU(Least Recently Used):淘汰最久未使用的键。
-
LFU(Least Frequently Used):淘汰访问频率最低的键(Redis 4.0+)。
-
TTL:淘汰剩余过期时间最短的键。
-
Random:随机淘汰。
|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------|
| 策略名称 | 规则 | 适用场景 |
| volatile-lru | Removes least recently used keys with expire field set to true。 从设置了过期时间的key中,淘汰「最近最少使用(LRU)」的key | 用户登录会话(2小时过期)、 商品列表(30分钟过期),均采用该策略。 |
| allkeys-lru | Keeps most recently used keys; removes least recently used (LRU) keys 从所有key中,淘汰最近最少使用的key(无论是否过期) | 纯临时缓存(日志、临时计算结果) |
| volatile-ttl | Removes keys with expire field set to true and the shortest remaining time-to-live (TTL) value 从设置了 TTL 的键中淘汰剩余存活时间最短的键。 | 实时性要求高的场景 (订单缓存、验证码),优先淘汰即将过期的数据 |
| volatile-random | Randomly removes keys with expire field set to true。 从设置了过期时间的key中,随机淘汰key。 | 无明显热点、对命中率要求低的场景(非核心日志、临时通知) |
| noeviction | New values aren't saved when memory limit is reached 不淘汰任何key,内存满时拒绝所有写操作(返回OOM command not allowed错误) When a database uses replication, this applies to the primary database | 核心不可丢失数据(系统配置、字典)。 (该策略需严格控制内存足够大) |
| allkeys-random | Randomly removes keys 随机淘汰所有key | (极少用) |
| allkeys-lfu | Keeps frequently used keys; removes least frequently used (LFU) keys 从所有key中,淘汰最不频繁使用的key(无论是否过期) | 热点数据缓存,区分冷热数据。 |
| volatile-lfu | Removes least frequently used keys with expire field set to true 淘汰设置过期时间中,最近最不频繁使用(LFU)的key | 需结合ttl使用 |
三、选型:Java项目如何选择淘汰策略?
1. 看数据类型和过期设置(最基础)
-
有过期时间、核心业务数据(用户、商品、订单)→ 选 volatile-lru;
-
无过期时间、纯临时缓存(日志、临时计算)→ 选 allkeys-lru;
-
有过期时间、实时性要求高(验证码、短期订单)→ 选 volatile-ttl;
-
核心不可丢失数据(配置、字典)→ 不设置maxmemory 或 选 noeviction。
2. 看数据热点程度
-
有明显热点数据(爆款商品、高频接口)→ 优先选 LRU类策略(volatile-lru/allkeys-lru),保留热点数据;
-
无明显热点、数据均匀分布 → 可选 volatile-random(极少用)。
3. 看数据一致性要求
-
高一致性(支付、订单状态)→ 选 volatile-lru + 主动更新(避免缓存与DB不一致);
-
弱一致性(商品详情、用户简介)→ 选 volatile-lru 即可,允许短期不一致。
4. 结合Redis集群场景(生产必看)
若使用Redis集群(主从、哨兵、Cluster),淘汰策略需在所有节点统一配置,避免数据混乱:
-
主从架构:仅主节点触发淘汰,从节点同步主节点淘汰结果;
-
Cluster集群:每个分片独立淘汰,需保证所有分片的maxmemory和淘汰策略一致,避免内存占用不均。
5. 合理设置maxmemory
生产环境建议:将maxmemory设置为Redis所在服务器内存的50%~70%(与MySQL、Tomcat共存时设50%,单独部署设70%~80%),避免Redis占用过多内存导致服务器OOM。
配置示例(redis.conf)
# 服务器16GB内存,设置Redis最大内存为8GB
maxmemory 8gb
# 显式配置默认淘汰策略
maxmemory-policy volatile-lru
总结
对于Java后端开发者来说,Redis缓存机制和淘汰策略,是项目性能优化的核心。无需死记所有策略,重点掌握3个核心:
-
缓存机制:内存存储(高性能)+ 持久化(保数据)+ 缓存管理(控内存);
-
淘汰策略:重点掌握volatile-lru的原理和适用场景,理解"过期删除+内存淘汰"的协同逻辑;
-
实战选型:贴合业务场景,平衡命中率、内存和CPU,配合避坑技巧,避免缓存异常。
生产环境中,没有"最优"的策略,只有"最贴合业务"的策略。