Redis运行久了性能掉了?聊聊后期优化和持久化那些事儿
- 问答
- 2026-01-12 11:49:52
- 3
前段时间,我们项目用的Redis服务器出了一点小状况,这个Redis实例已经稳定运行了快一年了,一直充当着我们系统的缓存扛把子,速度飞快,但不知道从什么时候开始,运维同事偶尔会收到告警,说接口响应变慢了,一开始大家没太在意,以为是网络波动或者业务高峰期的正常现象,但后来,这种慢查询报警越来越频繁,甚至影响到了一些核心业务的用户体验。
我们赶紧登录服务器排查,首先用Redis自带的INFO命令看了一下整体状态,发现used_memory(已用内存)和used_memory_rss(从操作系统角度看进程占用的内存)这两个值相差特别大,后者比前者高出了将近一倍,这其实就是一个很典型的信号,说明内存碎片化已经比较严重了。(来源:Redis官方文档对INFO命令输出字段的解释)

Redis在运行过程中,会不断地分配和释放内存,我们经常会对缓存数据进行更新或删除,当一个键值对被删除后,它所占用的内存就会被释放,形成一块空闲空间,如果新存入的数据需要的内存大小和这些空闲空间对不上,比如新数据需要64字节,但空闲空间是128字节,那么Redis就只能把这块128字节的空间切分开,用掉64字节,剩下的64字节就变成了新的、更小的空闲空间,长此以往,内存里就会布满各种大小不一的“碎片”,这些碎片本身是空闲的,但因为它们不连续、大小不合适,当需要分配一块较大的连续内存时,即使总空闲内存还够,Redis也可能因为找不到一块足够大的连续空间而失败,或者被迫进行更耗时的碎片整理,这就会拖慢操作速度。(来源:Redis官方文档中关于内存优化的章节)
除了内存碎片,另一个潜在的“性能杀手”是持久化操作,我们当时为了数据安全,同时开启了RDB和AOF两种持久化方式,RDB是定时拍一个完整的数据快照,AOF则是记录每一次写操作命令,AOF文件会越来越大,所以Redis需要定期重写AOF,也就是根据当前数据库的状态,生成一个全新的、最简洁的AOF文件来替换旧的。

问题就出在这里,当Redis在后台进行BGREWRITEAOF(后台重写AOF)或者BGSAVE(后台生成RDB快照)时,会fork出一个子进程来完成任务,这个fork操作本身,在数据量很大的情况下,可能会造成主进程短暂的停顿,更重要的是,在子进程持久化数据的过程中,如果主进程接收了大量的写请求,那么操作系统会采用“写时复制”机制,这会导致父子进程共享的内存页被分离,从而可能使得父进程的内存占用短时间内显著增加,如果此时服务器物理内存已经比较紧张,就很可能触发操作系统的Swap机制。(来源:Redis持久化官方文档中关于fork和写时复制的说明)
什么是Swap?就是操作系统发现物理内存不够用了,会把内存中一些暂时不用的数据写到硬盘上的一个交换分区里,等需要的时候再读回来,但硬盘的读写速度和内存根本不在一个数量级上,一旦Redis的数据被Swap到了硬盘上,下次读取这些数据时就会发生硬盘I/O,性能就会呈现断崖式下跌,慢查询也就随之而来了。
找到原因后,我们的优化就有的放矢了,针对内存碎片,我们采取了几个措施:
- 重启大法:这是最简单粗暴但也最有效的方法,我们选择了一个业务低峰期,搭建了新的Redis从节点,然后进行主从切换,平滑地重启了原来的主节点,重启后,内存碎片被彻底清理,内存使用率恢复了正常,但这毕竟不是长久之计。
- 调整配置:我们检查了系统中那些设置了过期时间的键,发现很多键的实际存活时间远小于设置的过期时间,于是我们适当调整了
active-expire-effort参数,让Redis更积极地去淘汰过期键,这有助于释放出更大的连续内存块,我们也启用了activedefrag配置(自动碎片整理功能),并设置了触发整理的阈值,让Redis在后台自动进行小幅度的碎片整理。
针对持久化可能带来的影响,我们做了如下优化:
- 分离持久化任务:我们将AOF重写和RDB快照的定时任务错开,避免它们同时发生,减少对系统资源的集中消耗。
- 优化AOF策略:我们将AOF的刷盘策略从默认的
everysec(每秒同步)改成了no(由操作系统决定何时同步),这样做牺牲了极端情况下最多一秒的数据丢失风险(因为服务器是虚拟机,本身有备份),但减少了同步操作的等待时间,换来了更好的写入性能,这个选择需要根据业务对数据安全性的要求来权衡。 - 预留足够内存:这是最关键的一点,我们根据数据量和增长趋势,为服务器配置了更充足的内存,并确保
vm.overcommit_memory=1,从根本上避免了因为内存不足而导致Swap的发生。
经过这一系列的调整,Redis的性能终于恢复了往日的活力,这次经历让我们深刻体会到,对于Redis这种核心组件,不能只是“部署完就撒手不管了”,长期的监控(比如关注内存碎片率、是否发生Swap等指标)、定期的健康检查以及根据业务变化适时调整配置,都是保证其持续稳定高性能运行的必要手段。

本文由称怜于2026-01-12发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/79293.html
