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
2
小数据 → 紧凑结构 → 节省内存
大数据 → 高效结构 → 提升性能

三、最大内存限制(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
2
allkeys-lfu
volatile-lfu

淘汰访问次数最少的数据。

适合热点数据场景。


4 随机淘汰

1
2
allkeys-random
volatile-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
2
Redis数据:1GB
进程占用:1.4GB

这多出来的:

内存碎片

产生原因:

  • 对象频繁创建删除
  • 内存块大小不匹配

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
2
1.2 ~ 1.5 正常
> 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 机制减少内存碎片,提高内存利用率。