Supervisord守护Redis进程后无法调整maxclients问题的解决
前言
在服务器上运行Redis时,默认的最大连接数通常设置为10000。然而,在生产环境中,频频出现资源池打满现象,和开发沟通后认为不可能打满10000,所以开始排查吧。
问题现象
在高并发访问Redis的场景下,Redis的最大连接数达到上限时,新的连接请求将会被拒绝。我们可以通过以下命令查看Redis当前的最大连接数及相关的系统资源限制:
-
连接Redis服务器,查看
maxclients
的当前设置:redis-cli CONFIG GET maxclients
竟然惊奇的发现最大连接数为
4064
,说明Redis的默认最大连接数配置异常,不是10000。 -
查看系统进程的文件描述符限制:
首先找到Redis的PID:ps aux | grep redis
然后通过Redis的PID查看打开文件数限制:
cat /proc/<redis-pid>/limits
找到
Max open files
,通常情况下,默认值是4096
,这将严重限制Redis的最大连接数。
尝试的解决方案
1. 修改系统文件描述符限制
为了增加允许的最大打开文件数,我们首先尝试修改系统级别的文件描述符限制。以下是步骤:
-
临时修改当前会话的打开文件数限制:
ulimit -n 65536
这个命令将当前shell会话中的最大文件描述符数调整为
65536
。 -
永久修改:
编辑/etc/security/limits.conf
文件,在末尾添加以下内容:* soft nofile 65536 * hard nofile 65536
然后,修改
/etc/sysctl.conf
文件,添加或修改以下内容:fs.file-max = 65536
运行以下命令使配置生效:
sysctl -p
2. 检查
重启redis后,通过redis-cli连接查看后仍然为4064
。
定位问题
开始怀疑使用supervisord
守护Redis进程时,尽管我们已经按照上述步骤修改了系统级别的限制和Redis配置文件,但是这些配置可能仍然无法生效。原因在于supervisord
自身并没有继承系统的文件描述符限制。
我们需要在supervisord
的服务配置中明确设置文件描述符限制。
最终解决方案
-
编辑
supervisord
的services配置文件vim /usr/lib/systemd/system/supervisord.services # 增加此配置,解除限制 LimitNOFILE=65535
-
如果使用
systemd
管理supervisord
服务,还需重新加载systemd
的配置:systemctl daemon-reload systemctl restart supervisord
验证效果
重新启动Redis后,可以再次通过以下命令确认Redis的maxclients
和文件描述符限制已经生效:
-
连接Redis,查看当前的
maxclients
:redis-cli CONFIG GET maxclients
-
查看Redis进程的文件描述符限制:
cat /proc/<redis-pid>/limits
确认Max open files
已经大于10000
了。
总结
在高并发场景下,调整Redis的maxclients
和系统的文件描述符限制至关重要。通过修改系统设置、Redis配置文件以及supervisord
守护进程的相关配置,可以确保Redis能够处理更多的连接,避免因连接池打满导致的服务中断问题。