redis 默认安装启动之后,如果查看 redis 日志,经常会报几条警告,这些警告与 linux 操作系统的配置有关系。如果忽略它们,有可能会造成 redis 在运行过程中异常。
具体的报警信息如下:
27967:M 23 Jul 03:48:38.410 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
27967:M 23 Jul 03:48:38.410 # Server started, Redis version 3.0.6
27967:M 23 Jul 03:48:38.410 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
27967:M 23 Jul 03:48:38.410 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
解决办法如下:
一、修改 /etc/sysctl.conf
在配置文件末尾增加如下两行:
net.core.somaxconn=65535
vm.overcommit_memory=1
二、重新载入 sysctl 配置,使配置生效
sysctl --system
三、处理 transparent_hugepage
echo never > /sys/kernel/mm/transparent_hugepage/enabled
四、处理 maximum open files
启动 redis 的时候,还可能遇到这个问题,使用 ulimit -n 明明设置的都是比较大大值,比如 10240,但是似乎 redis 无法识别这个设置,始终会报如下警告:
Redis can't set maximum open files to 10032 because of OS error: Operation not permitted.
此时,你需要修改 /etc/pam.d/ 目录下的 sudo 文件, 添加如下行:
session required pam_limits.so
这将会帮助使得 /etc/security/limits.conf 中的设置生效。
五、vm.overcommit_memory 原理
Redis在启动时可能会出现这样的日志:
# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the
command 'sysctl vm.overcommit_memory=1' for this to take effect.
在分析这个问题之前,首先要弄清楚什么是overcommit?Linux操作系统对大部分申请内存的请求都回复yes,以便能运行更多的程序。因为申请内存后,并不会马上使用内存,这种技术叫做overcommit。如果Redis在启动时有上面的日志,说明vm.overcommit_memory=0,Redis提示把它设置为1。
vm.overcommit_memory用来设置内存分配策略,它有三个可选值,如下表所示。
vm.overcommit_memory 含义
0 表示内核将检查是否有足够的可用内存。如果有足够的可用内存,内存申请通过,否则内存申请失败,并把错误返回给应用进程
1 表示内核允许超量使用内存直到用完为止
2 表示内核决不过量的(“never overcommit”)使用内存,即系统整个内存地址空间不能超过swap+50%的RAM值,50%是overcommit_ratio默认值,此参数同样支持修改
注意:本文的可用内存代表物理内存与swap之和。
日志中的Background save代表的是bgsave和bgrewriteaof,如果当前可用内存不足,操作系统应该如何处理fork。如果vm.overcommit_memory=0,代表如果没有可用内存,就申请内存失败,对应到Redis就是fork执行失败,在Redis的日志会出现:
Cannot allocate memory
Redis建议把这个值设置为1,是为了让fork能够在低内存下也执行成功。
5.2. 获取和设置
获取:
cat /proc/sys/vm/overcommit_memory
设置:
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1
5.3. 最佳实践
Redis设置合理的maxmemory,保证机器有20%~30%的闲置内存。
集中化管理 aof 重写和 rdb 的 bgsave。
设置vm.overcommit_memory=1,防止极端情况下,会造成fork失败。
六. Transparent Huge Pages 原理
Redis在启动时可能会看到如下日志:
WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
从提示看Redis建议修改Transparent Huge Pages (THP)的相关配置,Linux kernel在2.6.38内核增加了Transparent Huge Pages (THP)特性 ,支持大内存页(2MB)分配,默认开启。当开启时可以降低fork子进程的速度,但fork之后,每个内存页从原来4KB变为2MB,会大幅增加重写期间父进程内存消耗。同时每次写命令引起的复制内存页单位放大了512倍,会拖慢写操作的执行时间,导致大量写操作慢查询。例如简单的incr命令也会出现在慢查询中。因此Redis日志中建议将此特性进行禁用,禁用方法如下:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
而且为了使机器重启后THP配置依然生效,可以在/etc/rc.local中追加
echo never > /sys/kernel/mm/transparent_hugepage/enabled。
在设置THP配置时需要注意:有些Linux的发行版本没有将THP放到/sys/kernel/mm/transparent_hugepage/enabled中,例如Red Hat 6以上的THP配置放到/sys/kernel/mm/redhat_transparent_hugepage/enabled中。而Redis源码中检查THP时,把THP位置写死。
FILE *fp = fopen("/sys/kernel/mm/transparent_hugepage/enabled","r");
if (!fp) return 0;
所以在发行版中,虽然没有THP的日志提示,但是依然存在THP所带来的问题。
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
七、TCP backlog 原理
Redis默认的tcp-backlog为511,可以通过修改配置 tcp-backlog 进行调整,如果 Linux 的 tcp-backlog 小于Redis设置的 tcp-backlog,那么在Redis启动时会看到如下日志:
# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
查看方法:
cat /proc/sys/net/core/somaxconn
修改方法:
echo 511 > /proc/sys/net/core/somaxconn