Redis 进阶 01:内存、过期与淘汰
实验基线:Redis 7.4.11,先完成环境准备。除标注为宿主机终端的代码外,Redis 命令在该课指定的 redis-cli 中执行;不复制输出结果作为命令。
学习目标#
区分过期删除、主动删除和内存淘汰,观察实际内存占用,为缓存选择合适的淘汰策略。
原理:TTL 与 maxmemory 是两个问题#
TTL 决定数据何时失效。Redis 通过访问时检查和后台周期采样清理过期键,并不是每个键对应一个精确计时器。maxmemory 决定内存压力下是否需要淘汰键;键可能没到 TTL 就被淘汰,应用应始终能处理未命中。
noeviction 表示不因内存限制淘汰键,达到上限后需要新增内存的写命令可能报 OOM。allkeys-lru 从全部键近似选最近少用的键;volatile-lru 只从有过期时间的键中选择,没有候选键时仍可能无法写入。LRU 与 LFU 都不能提供“最重要数据永远保留”的保证。
实验:不改变主实验实例配置#
宿主机创建独立的容量实验容器,仅从容器内连接,不向外暴露端口:
docker run -d --name redis-memory redis:7.4.11 redis-server --maxmemory 32mb --maxmemory-policy allkeys-lru --save "" --appendonly no
docker exec -it redis-memory redis-cli
后续 Redis 命令在 redis-memory 的 redis-cli 中执行:
SET learn:memory:item demo EX 300
MEMORY USAGE learn:memory:item
INFO memory
INFO stats
CONFIG GET maxmemory
CONFIG GET maxmemory-policy
MEMORY USAGE 是此键的内存估计,包含一定管理开销,不等于字符串字节数。INFO memory 中关注 used_memory、used_memory_rss、maxmemory;INFO stats 中关注 evicted_keys、expired_keys、keyspace_hits 与 keyspace_misses。首次实验通常淘汰数是 0,不应为了追求非零输出而填满共享实例。
容量规划:把峰值和开销一起算进去#
假设 10 万个缓存值平均 1 KiB,值本身约 98 MiB。但 key、对象、哈希表、碎片、复制缓冲和持久化写时复制都需要额外资源。用真实样本测 MEMORY USAGE,并观察进程 RSS,预留空间后再确定实例规格。
命中率按同一观测窗口内的 hits / (hits + misses) 计算。分母为 0 时没有有效样本,不能显示 100%。长期累计值会掩盖近期异常,监控要看增量。
常见错误#
- 将容器内存限制与 maxmemory 设置成完全相同:进程开销可能导致操作系统直接杀进程。
- 重要数据与可淘汰缓存混在一个实例:淘汰策略按实例作用,不理解业务重要程度。
- 只看 used_memory:RSS、碎片和后台任务峰值同样重要。
- 把过期数增加当作故障:首先对比 TTL 策略与流量。
练习与参考答案#
给一个键设置过期,再删除到期时间,观察它是否变成 volatile 策略的候选:
SET learn:memory:persistent value EX 60
PERSIST learn:memory:persistent
TTL learn:memory:persistent
预期 PERSIST 为 1,TTL 为 -1。它不会被 volatile-lru 选中,但仍可能被 allkeys-lru 淘汰。说明为什么缓存未命中不能直接返回业务不存在:数据可能只是被淘汰,需要回源判断事实。
清理#
UNLINK learn:memory:item learn:memory:persistent
QUIT
docker stop redis-memory
docker rm redis-memory
官方参考#
内存淘汰 · MEMORY USAGE · INFO
学习导航#
上一课:Redis 入门 06:排行榜与计数器综合练习 · 学习目录 · 下一课:Redis 进阶 02:RDB、AOF 与备份恢复







