重启机器后Redis进程又跑起来了,感觉像自己在不停地重启循环
- 问答
- 2026-01-06 17:00:12
- 9
(引用来源:某运维工程师的论坛发帖内容)
“我真的快被这个Redis搞疯了,事情是这样的,我们有一台服务器,上面跑着Redis服务,前段时间因为机房电力维护,服务器非正常关机了一次,等电来了,机器重启之后,我登录上去一看,发现Redis进程又好端端地跑起来了,一开始我还挺高兴,觉得省事了,不用手动去启动服务了,但没过多久,监控系统就开始报警,说Redis占用的内存异常的高,而且服务响应非常慢,甚至有时候会完全无响应。”
“我赶紧连上去检查,用ps命令一看,确实有好几个Redis-server的进程在那里,我当时的第一反应是,是不是有哪个不懂事的同事写了个定时任务,在机器启动后自动把Redis拉起来了?于是我就去查crontab,把root用户和部署服务用的那个用户的定时任务列表都翻了个底朝天,结果什么都没发现,干干净净的,根本没有和Redis相关的定时任务,这就奇怪了,那它是怎么自己启动的呢?”
(引用来源:该工程师后续的问题排查记录)
“定时任务的路子走不通,我又想到了是不是系统的服务管理机制在作怪,我们用的是CentOS 7,它用的是systemd来管理服务,我就用systemctl status redis这个命令去查看Redis服务的状态,果然,显示的状态是active (running),并且下面还有一行小字,写着‘Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)’,关键就在那个‘enabled’上!这个单词的意思就是说,这个服务被设置为开机自动启动了。”
“到这里,我好像明白了一点,应该是之前不知道谁,或者是在安装Redis的时候,顺手就执行了systemctl enable redis这个命令,把这个服务设置成了随系统启动,所以每次服务器重启,systemd这个‘大管家’就会按照设定,自动把Redis服务给拉起来,这看起来似乎解释了为什么重启后Redis进程会自己出现。”
(引用来源:工程师与同事的聊天记录片段)
“问题又来了,如果只是开机自启,那应该只启动一次才对啊,为什么我看到的会是好几个Redis进程,而且服务状态还不稳定呢?我把我的发现跟一个老同事说了,他提醒了我一句:‘你光看它是不是enabled了,你看了它的service文件里面具体是怎么写的吗?特别是[Service]区块里的配置?’这句话点醒了我,我赶紧用cat命令打开了那个/usr/lib/systemd/system/redis.service文件。”
“这一看,还真发现了新大陆,在[Service]这个部分,除了指定启动命令和配置文件路径这些常规设置外,我看到了两行关键的配置:一行是‘Restart=always’,另一行是‘RestartSec=10’,我当时对这两个配置项的具体含义不是很清楚,就马上查了一下systemd的文档,查完我就愣住了,也终于明白为什么Redis会‘不停地重启循环’了。”
(引用来源:Systemd官方文档关于服务重启机制的说明)
“原来,‘Restart=always’这个配置是一个非常‘尽职尽责’的设定,它的意思是,无论Redis进程是因为什么原因退出的(不管是正常退出、被杀死还是因为出错崩溃),systemd都会试图去重新启动它,而‘RestartSec=10’则是告诉systemd,在重启之前,先等待10秒钟,换句话说,我面对的情况根本不是简单的‘开机自启’,而是一个‘无限复活’的机制!”
“是什么原因导致Redis进程需要被不断地‘复活’呢?我回过头来仔细检查Redis的日志文件,在日志里,我看到了大量的错误信息,核心内容是‘Can’t save in background: fork: Cannot allocate memory’,这个错误我有点印象,是因为系统的内存不足,导致Redis无法创建子进程来执行持久化操作(比如把数据写到硬盘上的RDB文件),由于我们配置了持久化策略,Redis会定期尝试保存数据,但每次尝试都因为内存问题而失败,这个失败在Redis内部可能被视为一个严重错误,导致Redis进程自己退出了。”
“整个可怕的循环链条就清晰了:服务器启动 -> systemd根据配置自动启动Redis -> Redis开始运行 -> 过一会儿,Redis因内存不足导致后台保存失败 -> Redis进程崩溃或退出 -> systemd检测到Redis进程退出 -> systemd等待10秒后,根据‘Restart=always’的规则,重新启动Redis -> 新启动的Redis再次因同样的问题失败退出 -> systemd再次重启它……就这样,我的Redis就陷入了‘启动-崩溃-重启-再崩溃’的死亡循环之中,表面上看进程一直在,实际上服务根本不可用,而且每一次重启和崩溃的尝试,都在进一步消耗着本已紧张的系统资源。”
(引用来源:工程师最终的解决方案笔记)
“找到根因后,解决起来就有的放矢了,我并没有立即去修改systemd的service文件去掉那个‘Restart=always’,因为那只是治标,万一以后Redis因为别的原因真的崩溃了,我们反而希望它能自动重启,真正的问题在于系统的内存不足,我临时扩大了服务器的交换分区(swap)以缓解燃眉之急,然后着手排查是什么其他进程占用了大量内存,并优化了Redis本身的配置,比如调整了最大内存限制maxmemory和淘汰策略,确保它在内存紧张时能主动清理一些数据,而不是硬扛到崩溃,做完这些之后,再重启Redis服务,它就终于能够稳定运行了,那个诡异的‘自动重启循环’现象也彻底消失了。”
“这次经历给我的教训太深刻了,以后再看到服务‘莫名其妙’地自动重启,我第一个就会去检查systemd的服务配置,特别是那个‘Restart’参数,并且一定要结合服务的日志来综合分析,不能只看表面现象,系统提供的自动化管理工具虽然方便,但如果配置不当或者底层环境有问题,这种‘自动化’反而会变成一场隐藏很深的噩梦。”

本文由钊智敏于2026-01-06发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/75683.html
