6. 内存管理
6.1 键的过期策略
Redis 有两种过期策略协同工作:
- 🕐惰性删除:访问一个键时才检查是否过期,过期则删除
- 🔄定期删除:每 100ms 随机抽查一批键,删除已过期的键
📝 备注: 为什么不直接扫描所有过期键?因为键可能有几十万个,全扫描会阻塞主线程。惰性 + 定期的组合是性能与准确性的折中。
6.2 内存淘汰策略(8 种)
当 maxmemory 达到上限时,Redis 需要腾出空间来存放新数据,这时淘汰策略就登场了。
| 策略 | 说明 | 适用场景 |
|---|---|---|
| noeviction | 不淘汰,内存满了直接报错 | 不允许丢数据的场景 |
| allkeys-lru | 所有键中淘汰最近最少使用的 | 最常用!通用缓存 |
| allkeys-lfu | 所有键中淘汰最不经常使用的 | 热点数据明显的场景 |
| allkeys-random | 所有键中随机淘汰 | 各键访问频率均匀 |
| volatile-lru | 有过期时间的键中淘汰 LRU | 混合存储(缓存 + 持久) |
| volatile-lfu | 有过期时间的键中淘汰 LFU | 混合存储,考虑访问频率 |
| volatile-random | 有过期时间的键中随机淘汰 | 混合存储 |
| volatile-ttl | 有过期时间的键中淘汰 TTL 最小的 | 希望快过期的键先被移除 |
bash
# 查看当前淘汰策略
CONFIG GET maxmemory-policy
# 设置淘汰策略
CONFIG SET maxmemory-policy allkeys-lru
# 设置最大内存
CONFIG SET maxmemory 4gbbash
1) "maxmemory-policy"
2) "noeviction"
OK
OK6.3 内存优化技巧
bash
# 1. 使用 Hash 替代多个 String(小 Hash 使用 ziplist 编码,更省内存)
# 差: SET user:1001:name "张三" / SET user:1001:age "28"
# 好: HSET user:1001 name "张三" age 28
# 2. 键名设计要短(键名存储也需要内存!)
# 差: user_profile_information_for_user_1001
# 好: u:1001:p
# 3. 使用整数集合代替 Set(元素全为整数且数量少时自动启用)
SADD status_set 0 1 2 3
# 4. 使用整数枚举代替字符串值
# 差: SET user:1001:gender "male"
# 好: SET user:1001:gender 1 (1=男, 2=女)
# 5. 设置合理的过期时间,避免无用数据占用内存
EXPIRE temp:data 3600
# 6. 查看内存使用情况
INFO memory
MEMORY USAGE user:1001bash
(integer) 4
(integer) 1
# Memory
used_memory:1520840
used_memory_human:1.45M
used_memory_rss:5234688
used_memory_rss_human:4.99M
mem_fragmentation_ratio:3.44
(integer) 80