Redis内存管理
Redis内存管理
Redis 的内存管理,本质上是在回答一个问题:数据全部放在内存里,那内存怎么分配、怎么控制、满了怎么办?
这背后其实有三层机制在协同工作:内存分配器、内存淘汰策略、内存碎片管理。
一、内存分配机制(Redis 怎么申请内存)
Redis 本身并不直接管理系统内存,而是依赖专业的内存分配器。默认使用的是:
- jemalloc
这是一个高性能内存分配库,比系统的 malloc 更适合高并发服务。
Redis 启动时通常会选择:
1 | jemalloc |
为什么不用系统 malloc?
普通 malloc 在频繁的小对象分配场景下容易出现:
- 内存碎片严重
- 锁竞争
- 性能下降
而 jemalloc 的特点是:
| 特性 | 说明 |
|---|---|
| 多线程友好 | 减少锁竞争 |
| 内存分级管理 | 小对象用不同大小的内存块 |
| 减少碎片 | 提高内存利用率 |
简单理解:
1 | Redis对象 → jemalloc → 操作系统内存 |
二、Redis 内存数据结构优化(节省内存)
Redis 在设计数据结构时有一个原则:
在小数据量时使用紧凑结构,在数据变大时自动转换。
例如:
1 String
如果字符串很小:
1 | embstr |
否则:
1 | raw |
2 Hash
小数据量:
1 | ziplist / listpack |
大数据量:
1 | hashtable |
3 ZSet
小数据量:
1 | ziplist |
大数据量:
1 | skiplist + hashtable |
核心思想:
1 | 小数据 → 紧凑结构 → 节省内存 |
三、最大内存限制(maxmemory)
Redis 可以设置最大内存:
1 | maxmemory 2gb |
意思是:
Redis 最多使用 2GB 内存
当达到这个限制时,就必须做一件事:
淘汰数据(eviction)
否则 Redis 会直接返回错误:
1 | OOM command not allowed |
四、内存淘汰策略(最重要)
Redis 提供 8 种淘汰策略。
可以通过配置:
1 | maxmemory-policy |
设置。
1 不淘汰
1 | noeviction |
内存满了直接报错。
2 LRU(最近最少使用)
Redis实现的是近似LRU算法。
1 | allkeys-lru |
淘汰所有 key 中最久没访问的。
或者:
1 | volatile-lru |
只在设置过过期时间的 key里淘汰。
3 LFU(最少使用频率)
1 | allkeys-lfu |
淘汰访问次数最少的数据。
适合热点数据场景。
4 随机淘汰
1 | allkeys-random |
随机删除。
5 TTL 淘汰
1 | volatile-ttl |
删除即将过期的 key。
总结
| 策略 | 含义 |
|---|---|
| noeviction | 不淘汰 |
| allkeys-lru | 所有key中LRU |
| volatile-lru | 只淘汰有TTL的key |
| allkeys-lfu | 所有key中LFU |
| volatile-lfu | TTL key中LFU |
| allkeys-random | 随机 |
| volatile-random | TTL key随机 |
| volatile-ttl | 优先删除快过期 |
实际生产最常用:
1 | allkeys-lru |
五、内存碎片问题
长期运行后 Redis 会出现一种现象:
1 | 操作系统内存 > Redis实际数据 |
比如:
1 | Redis数据:1GB |
这多出来的:
内存碎片
产生原因:
- 对象频繁创建删除
- 内存块大小不匹配
Redis 用两个方法解决:
1 active defrag(主动碎片整理)
开启配置:
1 | activedefrag yes |
Redis 会后台整理碎片。
2 jemalloc 内存管理
jemalloc 本身就减少碎片。
六、Redis 内存统计指标
常见监控命令:
1 | INFO memory |
关键指标:
| 指标 | 含义 |
|---|---|
| used_memory | Redis实际使用 |
| used_memory_rss | 操作系统分配 |
| mem_fragmentation_ratio | 碎片率 |
碎片率:
1 | fragmentation = rss / used_memory |
例如:
1 | 1.2 ~ 1.5 正常 |
七、Redis 过期键删除机制(内存回收)
Redis 删除过期 key 有两种方式:
1 惰性删除
访问 key 时检查:
1 | 过期 → 删除 |
优点:
- 不浪费CPU
缺点:
- 可能占内存
2 定期删除
Redis 每秒执行:
1 | 随机检查部分key |
如果发现过期:
1 | 删除 |
这是CPU和内存的折中策略。
八、面试版总结(推荐背这一段)
如果面试官问:
Redis 的内存管理是怎样的?
可以这样回答:
Redis 的内存管理主要包括三部分:
第一,Redis 使用 jemalloc 作为默认内存分配器,提高并发性能并减少内存碎片。
第二,可以通过 maxmemory 设置最大内存,当达到限制时 Redis 会根据配置的淘汰策略删除数据,常见策略有 LRU、LFU、随机和 TTL 等,其中生产环境最常用的是 allkeys-lru。
第三,Redis 通过惰性删除和定期删除机制清理过期 key,同时还可以通过 active defrag 机制减少内存碎片,提高内存利用率。
