最近公司redis服务出现了异常,记录下教训:
redis异常后:观察redis服务,可以看到redis cpu占用100%
用strace命令查看redis进程,显示如下:
open("/var/log/redis/redis.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EMFILE (Too many open files)
通过google知道这是每个进程可打开的文件句柄数有限,redis压力大了,文件句柄不够用,linux系统默认一个进程可打开文件句柄数为1024
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4}}}, 10240, 88) = 1
accept(4, 0x7fff9864c840, [883955190649061392]) = -1 EMFILE (Too many open files)
open("/var/log/redis/redis.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EMFILE (Too many open files)
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4}}}, 10240, 88) = 1
accept(4, 0x7fff9864c840, [883955190649061392]) = -1 EMFILE (Too many open files)
open("/var/log/redis/redis.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EMFILE (Too many open files)
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4}}}, 10240, 88) = 1
netstat -ano | grep port | wc -l统计下,发现redis确实已经达到1000多个连接了.
修改linux文件句柄,为了使重新启动后仍然生效,步骤如下:
1、打开/etc/profile,在最后加一行ulimit -n 65535(这里我修改为65535)
2、source /etc/profile 设置当前终端生效
3、通过命令ulimit -n查看是否生效。 这样设置好后,需要重新启动redis服务,以使redis进程生效。 由于公司的redis增加了个shell脚本程序,用来监控redis是否异常挂掉,若挂掉,则重新拉起,这样,我将redis杀掉后,redis进程被重新拉起了,
问题出现了,监控用shell脚本未重启,直接拉起了redis,这个貌似就是子Shell,这样设置redis没有生效,必须重启监控脚本。然后重启redis。 顺便记下:redis2.6应该已经解决了2.4的这个问题。
参考:https://github.com/antirez/redis/issues/246