当前位置: 首页 > backend >正文

Redis内存使用耗尽情况分析

目录

1、内存上限介绍

1.1、产生原因

1.2、Redis的maxmemory限额

1.3、影响的命令与场景

2. 内存用完后的策略

2.1、淘汰策略分类

2.2、淘汰策略介绍

2.3、不同策略对比

3、常见业务示例

3.1、影响

3.2、监控与自动告警


前言

        在日常项目中,不知道你思考过没有redis的内存耗尽的情况?

如下所示:

具体行为:

当内存满时:

  • 读操作(如GET):可以正常进行
  • 写操作(如SET、LPUSH、SADD等):
    • 如果能通过淘汰策略释放一点空间,则写入继续
    • 如果根据策略无法再释放空间(比如noeviction),则直接返回错误:“OOM command not allowed when used memory > 'maxmemory'.”

风险:

  • 如果是noeviction(默认),Redis直接拒绝写入!
  • 如果淘汰策略被触发,你的“旧数据”就会被自动删除(可能有业务风险)。
  • 内存页碎片、fork快照等也会加速内存耗尽。
  • 极端情况下,如果宿主机内存被撑爆,系统可能直接kill掉Redis进程(OOM Killer)。

关于更多redis的介绍,可参考:对Redis组件的深入探讨_redis 磁盘 内存-CSDN博客文章浏览阅读1.3k次,点赞20次,收藏8次。前言在介绍redis的时候,先介绍下存储介质,磁盘和内存。通过对以下两种认识,对了解redis有着更深的理解。如下图所示:以上就是r。_redis 磁盘 内存 https://blog.csdn.net/weixin_50055999/article/details/147757520?spm=1011.2415.3001.5331


1、内存上限介绍

        Redis是内存数据库所有数据(Key/Value)都存放在内存(RAM)中,不像MySQL等主要用磁盘。

Redis的数据结构不仅要存储你的 key/value 数据,还要存储:

1、Key/value 相关的元数据(如过期信息)

2、Append Only File (AOF)

3、缓冲区复制缓冲区、客户端连接缓冲区等

所以实际内存消耗 = 数据+各种维护数据+内存碎片。

1.1、产生原因

1、数据总量超过maxmemory配置:

这是最常见情况:写入、缓存、业务量上涨、没有删除机制,累计到了上限。

2、未设置maxmemory,Redis自动用光了系统全部内存:

系统会自动kill Redis进程(Linux OOM Killer)。

3、AOF或RDB备份引起内存瞬时暴涨:

快照/流复制/fork过程占用大量额外内存

4、客户端缓冲区、复制缓冲区太大:

有些命令或者慢客户端导致缓冲区堆积

5、内存碎片率很高:

内存并不是100%利用,碎片率过高也会导致出现“看似还有容量,实际已用尽”的问题。

1.2、Redis的maxmemory限额

Redis 是基于内存的数据库,其总内存上限可通过maxmemory参数配置。

比如在redis.conf中:

maxmemory 1gb

如果你没有设置,理论上 Redis 可以用光宿主机所有可用内存,直到被Linux OOM杀死进程。

1.3、影响的命令与场景

1、影响所有产生新内存分配的命令

包括:set/hash/set/zset/list的增量写入命令,bitmap、hyperloglog…

2、以下命令不会报错

读命令(GET/EXISTS/SCAN等)

删除命令(DEL/EXPIRE/UNLINK)

清空命令(FLUSHDB、FLUSHALL)


2. 内存用完后的策略

        当 Redis 达到 maxmemory 限制(即内存“用完”),会按照配置的淘汰策略(maxmemory-policy参数)来处理新写入命令

如下图所示:

写请求 -> 检查used_memory|是否超maxmemory?/        \否         是|           |正常写   执行淘汰策略|能释放内存吗?/     \能       不能|           |正常写     返回OOM错误,写失败

2.1、淘汰策略分类

  • noeviction默认):不淘汰,拒绝写入,只允许读;
  • allkeys-lru:将所有key中最久未使用的key淘汰;
  • volatile-lru:只对设置了过期时间的key做lru淘汰;
  • allkeys-random:所有key随机淘汰;
  • volatile-random只对设置了过期的key随机淘汰;
  • volatile-ttl优先淘汰过期时间到期最早的key;
  • volatile-lfu、allkeys-lfu:最不常用的(Least Frequently Used)key被淘汰。

2.2、淘汰策略介绍

1、noeviction(默认)

只读不写: 所有新增key、修改key、增加元素的命令(如SET、LPUSH、HSET等) 统统返回错误(error),只允许读(GET等)。

(error) OOM command not allowed when used memory > 'maxmemory'.
  • 危险:
    • 业务写入完全中断
    • 可能造成数据库/队列/秒杀等核心数据业务丢失
    • 生产极其危险,尤其是做缓存穿透时容易击穿下游数据库

2、allkeys-lru

自动淘汰: 

        优先淘汰“最久未使用”的key(Least Recently Used),腾出空间让新数据写成功。

风险:

        部分“冷数据”被自动删掉,新数据继续写入,服务不中断,但有可能丢掉了有用的老数据。

3、volatile-lru

  • 只判断有过期时间(expire)的key
  • 只淘汰带过期时间的key,不带过期属性的key永远不会被删
  • 如果全是永久key,效果跟noeviction一样,容易写不进去

4、allkeys-random/volatile-random

  • allkeys-random:任意key随机淘汰
  • volatile-random:也只淘汰带过期的key,随机选择。

5、volatile-ttl

淘汰带过期时间里“快要到期”的key。

6、allkeys-lfu/volatile-lfu

淘汰最少被访问的key(Least Frequently Used),更智能。

2.3、不同策略对比

如下所示:

注意

  • 持久化(RDB/AOF)也有可能被影响,如果没法持久化新数据,有可能异常或数据丢失!
  • 主从同步、集群等同步数据也受maxmemory影响。

3、常见业务示例

3.1、影响

1、缓存:

        如果用作普通缓存,可以用allkeys-lru/allkeys-lfu让Redis自动“以空间换时间”。热点数据永远在,冷数据慢慢淘汰,更健康

2、持久化队列/核心计数/实时业务:

        如果Redis用作数据库功能(存放业务数据、消费队列),noeviction策略推荐。避免关键数据被误删。一旦写入超限应报警、扩容、限流,绝不随便丢“老数据”

3、大key、热key、慢客户端

某个大key占住大量内存,会加速爆表,需依据业务定期分析优化。

更多bigkey文章介绍,参考:

Redis中的bigkey的介绍及影响_redis 大key-CSDN博客文章浏览阅读1.2k次,点赞31次,收藏12次。什么是BigKey?为什么它成为Redis的性能杀手?BigKey指在Redis中key对应的value占用内存或元素数量超出业务合理阈值的键值对。_redis 大key https://blog.csdn.net/weixin_50055999/article/details/148856033?spm=1011.2415.3001.5331

4、内存暴涨瞬间写崩溃

       新增了超大key(如bitmap、大string、大list),远超单条key的预期,会导致写入命令的突然异常或长时间阻塞(尤其fork的时候)。

3.2、监控与自动告警

建议配合运维/监控工具(如Prometheus、Grafana、redis_exporter、阿里云/腾讯云云监控等)。

重点关注:

1、used_memory (info memory)。

2、maxmemory。

3、内存碎片率。

4、淘汰计数器evicted_keys。

5、命令拒绝计数rejected_connections


总结

        Redis的内存满了,不同的淘汰策略决定要不要丢弃已有数据腾空间,否则直接拒绝写入并报错,只能读不能写,业务必须配合好监控、限流和数据结构优化。


参考文章:

1、内存耗尽后,Redis会发生什么?_redis中key没有达到过期时间,但是内存满了会怎么样?-CSDN博客文章浏览阅读84次。作为一台服务器来说,内存并不是无限的,所以总会存在内存耗尽的情况,那么当 Redis 服务器的内存耗尽后,如果继续执行请求命令,Redis 会如何处理呢?_redis中key没有达到过期时间,但是内存满了会怎么样? https://blog.csdn.net/qq_30987095/article/details/143257130?ops_request_misc=%257B%2522request%255Fid%2522%253A%252295fab89f19b3cb10a23ea7030593bb32%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=95fab89f19b3cb10a23ea7030593bb32&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-143257130-null-null.142^v102^control&utm_term=redis%E5%86%85%E5%AD%98%E8%80%97%E5%B0%BD&spm=1018.2226.3001.4187

http://www.xdnf.cn/news/16556.html

相关文章:

  • 编辑距离:理论基础、算法演进与跨领域应用
  • Windows使用Powershell自动安装SqlServer2025服务器与SSMS管理工具
  • css3之三维变换详说
  • Qt 多线程界面更新策略
  • 如何在Windows操作系统上通过conda 安装 MDAnalysis
  • 激光雷达/相机一体机 时间同步和空间标定(1)
  • 自然语言处理NLP(3)
  • leetcode 74. 搜索二维矩阵
  • 柔性生产前端动态适配:小批量换型场景下的参数配置智能切换技术
  • 汇总10个高质量免费AI生成论文网站,支持GPT4.0和DeepSeek-R1
  • cpolar 内网穿透 ubuntu 使用石
  • 2025年06月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • go install报错: should be v0 or v1, not v2问题解决
  • 【自制组件库】从零到一实现属于自己的 Vue3 组件库!!!
  • P2910 [USACO08OPEN] Clear And Present Danger S
  • 四、Linux核心工具:Vim, 文件链接与SSH
  • 永磁同步电机无速度算法--静态补偿电压模型Harnefors观测器
  • 人工智能技术革命:AI工具与大模型如何重塑开发者工作模式与行业格局
  • Linux 完整删除 Systemd 服务的步骤
  • redis得到shell的几种方法
  • 如何使用Spring AI框架开发mcp接口并发布成微服务
  • 31.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--财务服务--收支分类
  • 解决IDEA拉取GitLab项目报错:必须为访问令牌授予作用域[api, read user]
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(11):文法+单词
  • tcp通讯学习数据传输
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博文章数据可视化分析-文章评论量分析实现
  • Web3 网络安全漏洞的预防措施
  • 面向对象系统的单元测试层次
  • 算法思维进阶 力扣 375.猜数字大小 II 暴力递归 记忆化搜索 DFS C++详细算法解析 每日一题
  • K8s集群两者不同的对外暴露服务的方式