Redis的角色由maxmemory与maxmemory-policy共同定义:设maxmemory并启用lru/lfu/ttl等淘汰策略即为缓存;配noeviction+强持久化才是数据库模式;evicted_keys增长即表明已进入缓存模式。

Redis 作为缓存时,maxmemory-policy 决定数据是否可丢
Redis 本身没有“数据库模式”和“缓存模式”的开关,区分本质在于你是否允许数据丢失。关键配置是 maxmemory-policy:它只在设置了 maxmemory 后生效,而这个设置本身就是在明确告诉 Redis:“我当你是缓存,内存有限,你要自己管淘汰”。
常见错误是以为只要没配 maxmemory 就是“数据库模式”——其实只是没设上限,一旦内存耗尽,OS 可能 OOM kill 进程,比主动淘汰更危险。
-
noeviction(默认):内存满后拒绝写入,适合要求强一致、不允许丢数据的场景,但需自行保障内存充足 -
allkeys-lru/volatile-lru等带lru、lfu、ttl的策略:明确启用淘汰,即接受部分数据丢失,是典型缓存用法 -
volatile-ttl仅对设了EXPIRE的 key 生效,若全都没过期时间,它等同于不淘汰——这点常被忽略
持久化配置(save、aof)不改变缓存/数据库定位
开启 RDB 或 AOF 只影响宕机后能否恢复,不影响运行时数据是否可被主动淘汰。一个启用了 allkeys-lru 且开着 AOF 的 Redis,仍是缓存角色:AOF 日志里记录的是“写操作”,不是“最终快照”,重启后加载 AOF 恢复的是淘汰前的数据状态,但一运行起来,淘汰立刻继续发生。
反例:有人把 appendonly yes + save "" 当作“数据库替代”,结果业务流量上涨后触发 allkeys-lru,大量热 key 被清掉,缓存命中率骤降,却误以为是 AOF 没起作用。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 真正想当数据库用,必须配
noeviction,再叠加appendonly yes+save 3600 1等合理持久化策略 -
RDB是快照,AOF是日志重放,两者都不阻止运行时淘汰行为 - 混合持久化(
aof-use-rdb-preamble yes)只优化加载速度,不改变数据生命周期逻辑
应用层如何配合判断 Redis 角色
服务代码里不能只看 Redis 是否连得上,得看它实际承担什么职责。最直接的信号是:你的应用是否接受“读不到就查库再回填”。如果回填逻辑存在且稳定,说明 Redis 是缓存;如果读不到就报错或降级,那它实际已是数据库。
容易踩的坑是混用:比如用户 session 存 Redis(应设 TTL + volatile-lru),但同时把订单状态也塞进去(不该设 TTL),结果高峰期 session 淘汰压力大,把订单 key 也顺带清了——因为用了 allkeys-lru。
- 缓存场景:所有写入都带
EXPIRE或SETEX,淘汰策略选volatile-*系列更安全 - 数据库场景:禁用淘汰(
noeviction),写入不设 TTL,应用负责兜底容错 - 混合场景(如部分热数据+部分元数据):拆成两个 Redis 实例,比在一个实例里靠 key 命名区分更可靠
INFO memory 和 MEMORY USAGE 是验证真实角色的关键命令
别只信配置文件,运行时用命令看真实行为。执行 INFO memory,重点看 used_memory_human、maxmemory_human、mem_policy 和 evicted_keys。如果 evicted_keys 持续增长,说明淘汰已生效,哪怕你本意是当数据库用,Redis 早就按缓存跑了。
MEMORY USAGE 可查单个 key 占用,结合 OBJECT IDLETIME 能验证 LRU 是否真在起作用——但注意 IDLETIME 在集群模式下不可用,且只对未被逻辑删除的 key 有效。
-
evicted_keys非零且递增 → 缓存模式已激活 -
maxmemory为 0 但used_memory_human接近系统内存 → OOM 风险高,不是安全的数据库用法 - 用
redis-cli --bigkeys发现大量小 key 占内存 → 很可能误把缓存当数据库,没清理过期逻辑
maxmemory-policy 不是 noeviction,它就在主动丢数据——而丢哪些、何时丢,取决于你选的策略和 key 的访问模式,不是你想当然的“只丢冷数据”。

















