在 生成 rdb 文件和 aof 重写的时候,主进程 会 fork 子进程,而 fork 的时候,子进程需要拷贝父进程的空间内存页表,会耗费一定的时间。
一般来说,如果父进程内存有 1 个 G 的数据,那 fork 可能会耗费在 20ms 左右,如果是 10G~30G,那么就会耗费 20 * 10,甚至20 * 30,也就是几百毫秒的时间(info stats 中的 latest_fork_usec,可以看到最近一次 fork 的时长)。
redis 单机 qps 一般在几万,fork 可能一下子就会拖慢几万条操作的请求时长,从几毫秒变成 1 秒。
fork 耗时跟 redis 主进程的内存有关系,一般控制 redis 的内存在 10GB 以内。
redis 将数据写入 AOF 缓冲区,单独开一个线程做 fsync 操作,每秒一次。另外,redis 主线程会检查两次 fsync 的时间,如果距离上次 fsync 时间超过了 2 秒,那么写请求就会阻塞,整个 redis 就被拖慢,最多会丢失 2 秒的数据。
优化硬盘写入速度,建议采用 SSD,不要用普通的机械硬盘。
主从复制可能会超时严重,这个时候需要良好的监控和报警机制。在 info replication 中,可以看到 master 和 slave 复制的 offset,写一个脚本监控对应的延迟量,如果延迟过多,那么就进行报警。
如果同时让多个 slave 从 master 去执行全量复制,一份大的 rdb 文件同时发送到多个 slave,会导致网络带宽被严重占用。
如果一个 master 真的要挂载多个 slave,那尽量用树状结构,不要用星型结构。
0:检查有没有足够内存,没有的话申请内存失败
1:允许使用内存直到用完为止
2:内存地址空间不能超过 swap + 50%
如果是 0 的话,可能导致类似 fork 等操作执行失败,申请不到足够的内存空间。
cat /proc/sys/vm/overcommit_memory
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1
redis 实例启动日志中能看到有关 vm.overcommit_memory 的提示内容
使用命令 cat /proc/version 查看 linux 内核版本
如果 linux 内核版本 <3.5,那么 swapiness 设置为 0,表明系统宁愿 swap 也不会 oom killer(杀掉进程);
如果 linux 内核版本 >=3.5,那么 swapiness 设置为 1,表明系统宁愿 swap 也不会 oom killer。
保证 redis 不会被杀掉
echo 0 > /proc/sys/vm/swappiness
echo vm.swapiness=0 >> /etc/sysctl.conf
redis 实例启动日志中能看到有关最大打开文件句柄的提示内容
通过命令 ulimit -n 10032 10032 可按提示要求设置最大打开文件句柄。
redis 实例启动日志中能看到有关 tcp backlog 的提示内容
通过命令 echo 511 > /proc/sys/net/core/somaxconn 可按提示要求设置 tcp backlog。