如果是oom killer杀掉的话,一般会在/var/log/*留下日志,dmesg也应该能查到,可以使用命令搜索:
dmesg | egrep -i 'killed process'
grep oom /var/log/*
grep total_vm /var/log/*
如果确实是由于内存不足被oom killer杀掉,可以考虑:
maxmemory 512mb
maxmemory-policy volatile-lru
“OOM killer会在可用内存不足时选择性的杀掉用户进程,它的运行规则是怎样的,会选择哪些用户进程“下手”呢?OOM killer进程会为每个用户进程设置一个权值,这个权值越高,被“下手”的概率就越高,反之概率越低。每个进程的权值存放在/proc/{progress_id}/oom_score中,这个值是受/proc/{progress_id}/oom_adj的控制,oom_adj在不同的Linux版本的最小值不同,可以参考Linux源码中oom.h(从-15到-17)。当oom_adj设置为最小值时,该进程将不会被OOM killer杀掉。”
设置方法如下:
echo -17 > /proc/${process_id}/oom_adj
ausearch -sc kill
如果是cli发送的shutdown命令导致redis退出,redis本身的log会有如下记录:
3803:S 11 Oct 18:12:51.251 # User requested shutdown...
3803:S 11 Oct 18:12:51.251 * Removing the pid file.
3803:S 11 Oct 18:12:51.252 # Redis is now ready to exit, bye bye...
如果还没打开redis log,需要在redis.conf中指定路径然后重启:
dir "/opt/redis-4.0.9/redis-cluster/7000"
避免进程被cli远程关闭,可以设置密码,或者在redis.conf中禁用shutdown命令来实现,我们选择采用后者:
rename-command SHUTDOWN ""
ulimit -c unlimited
修改/etc/sysctl.conf文件,加入如下配置指定core dump文件生成的名称和路径:
kernel.core_uses_pid = 1
kernel.core_pattern = /var/core/core_%e_%p
注意不同linux发行版可能设置的方式略有不同。
screen -S redis_trace_7000
strace -T -tt -e trace=all -p `ps -ef|grep redis|grep 7000|grep -v -i screen|grep -v grep|awk '{split($0,a);print a[2]}'`
然后ctrl-a d退出screen
同样建议使用独立的screen执行gdb,另外,gdb需要使用ptrace,如果发现ptrace: Operation not permitted
的报错,需要关闭其他已经使用ptrace命令的进程,例如strace命令。
gdb /usr/local/bin/redis-server 58414
(gdb) continue
使用redis-cli连上server,发送debug segfault指令可以使redis server崩溃,这时候可以:
使用bt查看栈信息
(gdb) bt
#0 debugCommand (c=0x7ffc32005000) at debug.c:220
#1 0x000000010d246d63 in call (c=0x7ffc32005000) at redis.c:1163
#2 0x000000010d247290 in processCommand (c=0x7ffc32005000) at redis.c:1305
#3 0x000000010d251660 in processInputBuffer (c=0x7ffc32005000) at networking.c:959
#4 0x000000010d251872 in readQueryFromClient (el=0x0, fd=5, privdata=0x7fff76f1c0b0, mask=220924512) at networking.c:1021
#5 0x000000010d243523 in aeProcessEvents (eventLoop=0x7fff6ce408d0, flags=220829559) at ae.c:352
#6 0x000000010d24373b in aeMain (eventLoop=0x10d429ef0) at ae.c:397
......
使用info registers查看寄存器信息
(gdb) info registers
rax 0x0 0
rbx 0x7ffc32005000 140721147367424
rcx 0x10d2b0a60 4515891808
rdx 0x7fff76f1c0b0 140735188943024
rsi 0x10d299777 4515796855
rdi 0x0 0
rbp 0x7fff6ce40730 0x7fff6ce40730
rsp 0x7fff6ce40650 0x7fff6ce40650
r8 0x4f26b3f7 1327936503
r9 0x7fff6ce40718 140735020271384
r10 0x81 129
......
最后,使用gcore产生core dump文件
(gdb) gcore
Saved corefile core.58414
设置Redis最大占用内存
Redis的内存优化
Redis禁用命令、危险命令及规避方法
Redis debugging guide
Playing with ptrace, Part I
神器strace, ltrace
How to disable Redis RDB?
Redis研究(十九)—命令属性
Virtual memory settings in Linux - The Problem with Overcommit
What is the logic behind killing processes during an Out of Memory situation?
How to reproduce a condition which invokes the OOM-Killer ?