1 现象:
1.1 Redis连接数1千多个(redis在美国AWS、客户端在中国AWS),状态一直是ESTABLISHED,没有释放。在中国AWS上没有发现到美国Redis上的连接.
1.2 Redis占用单核CPU 100%
2 分析方式
2.1 在Redis server上采用netstat 命令查看连接。在客户端上采用netstat 命令查看连接. 确定Redis server上的连接是僵尸连接。
2.2 查看Redis 的配置,发现没有配置timeout参数,使用的默认是为0(表示redis server不进行超时处理)。
采用redis-cli登录上redis,采用config get timeout 参数可以查看该参数设置值确实是0。
当跨区网络不稳定,客户端断连的包发出去后,redis server没有接受到,则会出现redis server以为连接正常的情况。因为需要在redis server 需要启动超时设置,如果在一定的时间内,客户端没有消息过来,则redis server主动断开连接。
2.2 采用ltrace -p PID(redis server的进程号),发现进程当前状态在accept后,会一直循环打印“too many open files”。
因此,当外部新连接过来时,由于循环执行,cpu会100%。
查看该redis server 进程的文件数限制。 cat /proc/PID/limits 查看打开的文件数限制,发现为
Max open files 1024 1024 files
在前面的分析中,发现redis 僵尸连接已经为1千多个,说明确实是文件数限制导致的。
3 解决措施
由于是生产环境,需要做到redis不停止恢复。
2.1 关闭僵尸连接
采用redi-cli登录,采用client kill ip:port(redis远程连接的ip和端口)。
需要采用脚本批量删除多个连接
2.2 修改redis timeout参数
采用redis-cli登录,采用config set timeout xx 设置redis的keepalive时间
2.3 修改redis进程的文件数限制
echo -n "Max open files 3000:3000" > /proc/PID/limits
2.4 修改系统参数的最大文件数限制
/etc/security/limits.conf