当Redis内存耗尽时,其行为取决于配置的淘汰策略(maxmemory-policy
),以下是具体影响及处理逻辑:
⚠️ 一、默认策略:写入拒绝 (noeviction
)
-
核心表现
- 写入操作(如
SET
、HSET
):直接返回错误OOM command not allowed
,拒绝执行 ; - 读取操作(如
GET
):仍可正常响应 。
> SET new_key "value" (error) OOM command not allowed when used memory > 'maxmemory'
- 写入操作(如
-
业务影响
依赖写入的功能(如用户注册、实时计数)立即中断,需人工介入扩容或清理数据 。
♻️ 二、启用淘汰策略:自动删除旧数据
若配置了淘汰策略,Redis 会根据规则自动删除部分数据释放空间:
策略分类 | 淘汰范围 | 淘汰逻辑 | 典型场景 |
---|---|---|---|
volatile-* | 仅设置过期时间的键 | LRU (最近最少使用)或 TTL (即将过期) | 缓存场景 |
allkeys-* | 所有键 | LFU (最不频繁使用)或随机删除 | 持久化数据与缓存混合 |
volatile-ttl | 设置过期时间的键 | 优先删除剩余生存时间最短的键 | 短期缓存清理 |
风险与缺陷:
- 数据丢失:自动删除可能导致有效数据被清除,引发业务异常 ;
- LRU/LFU 近似算法:非精确淘汰(采样部分键),可能误删热点数据 ;
- 碎片加剧:频繁删除可能增加内存碎片,降低利用率 。
💥 三、极端情况:系统级OOM Killer
当满足以下条件时,可能触发系统内核强制终止进程:
- Redis 未配置淘汰策略或淘汰速度跟不上写入需求;
- Linux 系统内存溢出,内核根据
oom_score
杀死得分最高的进程(常包括 Redis)。
后果:服务崩溃,需重启恢复,可能丢失持久化间隙数据 。
⚙️ 四、内存耗尽的其他诱因
-
内存碎片
频繁更新或删除导致碎片化,可用内存不足(即使总量未超限)。
解决方案:启用activedefrag yes
自动碎片整理 。 -
持久化fork阻塞
RDB
或AOF
重写时 fork 子进程,若内存过大可能阻塞主线程,加速耗尽 。
🔧 五、预防与优化建议
-
配置合理的淘汰策略
- 纯缓存场景 →
allkeys-lru
或volatile-lru
; - 混合数据场景 →
allkeys-lfu
(优先保留高频访问数据)。
- 纯缓存场景 →
-
监控与扩容
- 实时监控内存使用率(
info memory
); - 设置
maxmemory
为物理内存的 80%,预留缓冲 。
- 实时监控内存使用率(
-
降低内存占用
- 使用
ziplist
等紧凑数据结构; - 缩短过期时间,避免数据堆积 。
- 使用
📌 结论:内存耗尽时 Redis 的行为由
maxmemory-policy
决定,默认策略拒绝写入,启用淘汰策略则自动删除数据(伴随丢失风险)。生产环境必须提前配置策略并监控内存,避免服务中断 。