Redis性能优化之Linux配置调优

通常情况下,生产环境中我们会把Redis部署在Linux系统上,以保障其运行稳定性;只有在测试环境中可能会将Redis部署在Windows系统上进行测试使用。所以,不管是部署在Linux还是Windows系统,为其创造一个良好的运行环境是势在必行的,然而通过实践也恰恰证明一个良好的系统配置能够为Redis服务良好运行保驾护航。

接下来就介绍一下在Linux系统上如何优化Redis服务:

1.内存分配控制

1.1 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 

需要注意的是 vm.overcommit_memory 参数,Linux操作系统对大部分申请内存的请求都回复yes,以便能运行更多的程序。因为申请内存后,并不会马上使用内存,这种技术叫做overcommit。如果Redis在启动时有上面的日志,说明vm.overcommit_memory=0,Redis提示把它设置为1。

vm.overcommit_memory用来设置内存分配策略,有三个可选值,如下表:

含义
0 表示内核将检查是否有足够的可用内存,如果有,内存申请通过,否则内存申请失败,并把错误返回给应用程序
1 表示内核允许应用程序使用超量的内存,直至用完为止
2 表示内存绝不允许使用超量的 内存,即系统整个内存地址允许空间不能超过swap+50%的RAM值,50%是overcommit_ratio默认值,支持修改

当系统可用内存不足时,如果vm.overcommit_memory设置为0,那么Redis在持久化时进行fork操作就会申请内存失败,也就是fork失败,在Redis的日志会出现:

Cannot allocate memory

Redis建议把这个值设置为1,是为了让fork操作能够在低内存下也执行成功。

1.2 查看与配置

#执行以下命令可以 查看当前配置
cat /proc/sys/vm/overcommit_memory

#修改当前配置
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
sysctl vm.overcommit_memory=1

1.3 运维建议

  • Redis设置合理的maxmemory,保证机器有20%~30%的闲置内存。
  • 集中化管理AOF重写和RDB的bgsave。 
  • 设置vm.overcommit_memory=1,防止极端情况下会造成fork失败。

2. swappiness

2.1 swap说明

swap(交换)是指当操作系统的物理内存不足时,可以将一部分内存页进行swap操作,已解燃眉之急。但是swap空间由硬盘提供,对于需要高并发、高吞吐的应用来说,磁盘IO通常会成为系统瓶颈。在Linux中,并不是要等到所有物理内存都使用完才会使用到swap,系统参数swppiness会决定操作系统使用swap的倾向程度。swappiness的取值范围是0~100,swappiness的值越大,说明操作系统可能使用swap的概率越高,swappiness值越低,表示操作系统更加倾向于使用物理内存。swap的默认值是30;具体属性值含义见下表:

策略
0

linux3.5及以上版本,宁愿 OOM killer 也不 swap

linux3.4及更早版本,宁愿 swap 也不 OOM killer

1 linux3.5及以上版本,宁愿 swap 也不 OOM killer
30 默认值,空闲内存少于 30% 时才使用 SWAP 分区
100 操作系统会主动使用 swap

2.2 配置方法

临时设置,机器重启后会失效:

echo 值 > /proc/sys/vm/swappiness

永久设置,机器重启后也会立即生效:

echo vm.swappiness=值 >> /etc/sysctl.conf

2.3 查看swap的使用情况

(1)通过 free -h 命令可以 查看swap 的总体使用情况:

可以看到当前总共2G,使用了0G;

 (2)通过 vmstat 1(每隔1秒更新) 命令可以实时查看swap使用情况:

其中 swap 栏 si、so 分别代表swap in 、swap out,可以看到当前都是 0;

Redis性能优化之Linux配置调优_第1张图片

 (3)通过 /proc/{pid}/smaps |grep Swap 命令可以查看具体某个进程占用的swap情况:

Redis性能优化之Linux配置调优_第2张图片

 2.4 运维建议

如果Linux>3.5,vm.swapniess=1,否则vm.swapniess=0,从而实现如下 两个目标:

  • 物理内存充足时候,使Redis足够快。
  • 物理内存不足时候,避免Redis死掉(如果当前Redis为高可用,死掉比阻塞更好)。

3. Transparent Huge Pages(THP)

Linux透明大页简称THP ,Linux kernel在2.6.38内核增加了THP特性,支持大内存页(2MB)分配,默认开启。

3.1 开启的好处

开启内存透明大页最根本的作用就是降低内存页的分配数量,当进程需要访问某个内存空间时,让CPU可以更快的根据页表找到物理内存,以提高CPU的命中率,提升CPU性能。

3.2 开启的劣处

当开启时可以加快fork子进程的速度,但fork操作之后,每个内存页从原来4KB变为2MB,会大幅增加重写期间父进程内存消耗。同时每次写命令引起的复制内存页单位放大了512倍,会拖慢写操作的执行时间,导致大量写操作慢查询,例如简单的incr命令也会出现在慢查询中。因此Redis日 志中建议将此特性进行禁用。

开启状态下启动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 madvise > /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 (set to 'madvise' or 'never').

3.3 关闭方法

(1)执行以下命令可以临时关闭THP,机器重启后会失效

echo never > /sys/kernel/mm/transparent_hugepage/enabled

(2)防止机器重启失效,添加开机自动执行命令

#将此命令放到 /etc/rc.local 中
bash -c 'cat >>  /etc/rc.local << EOF
echo never > /sys/kernel/mm/transparent_hugepage/enabled
EOF'

#添加可执行权限
chmod  +x  /etc/rc.local

4. Linux OOM killer

4.1 OOM killer说明

Linux内核有一种被称为OOM killer(内存耗尽杀手)的机制,它将监视那些占用过多内存的进程,特别是那些在瞬间占用过快的进程,然后防止内存耗尽会主动杀了这个进程。

OOM killer机制会根据每个进程存放在/proc/{progress_id}/oom_score中的权值,这个值受 /proc/{progress_id}/oom_adj 的控制,从而决定是否优先杀掉该进程,这个权值越高,被优先杀掉的机率就大。

4.2 修改Redis的 oom_score 

#将redis的oom_adj设置为最低值或者稍小的值,降低被OOM killer杀掉的概率
echo -17 > /proc/${redis_pid}/oom_adj

4.3 运维建议

  • oom_adj参数只能起到辅助作用,合理地规划内存更为重要。
  • 通常在高可用情况下,被杀掉比僵死更好,因此不要过多依赖oom_adj。

5. 使用NTP

NTP(Network Time Protocol,网络时间协议)是一种保证不同机器时钟一致性的服务。保证Redis集群服务器时间的一致性。

同步阿里云NTP服务器:

/usr/sbin/ntpdate ntp.aliyun.com

6. Open files

(1)通过 ulimit 命令查看和设置系统当前用户进程的资源数:

Redis性能优化之Linux配置调优_第3张图片

 (2)当Redis配置的maxclients 大于 当前系统 open files时,启动Redis会提示以下日志:

You requested maxclients of 10000 requiring at least 10032 max file descriptors.
Redis can’t set maximum open files to 10032 because of OS error: Operation not permitt# Current maximum open files is 1024. Maxclients has been reduced to 1024 to compensate
for low ulimit. If you need higher maxclients increase ‘ulimit –n’.

(3)Open files的设置方法如下:

ulimit -Sn 65535

当Redis以systemd进程服务运行时,可以进行systemd配置限制:

echo "[Service]" > /etc/systemd/system/redis.service.d/limits.conf
echo "LimitNOFILE=65535" >> /etc/systemd/system/redis.service.d/limits.conf

7. TCP backlog

TCP backlog在linux系统中控制tcp三次握手已完成连接队列的长度。在高并发系统中,你需要设置一个较高的tcp-backlog来避免客户端连接速度慢的问题(三次握手的速度)。

(1)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.

(2)查看方法:

[root@active_sentinel ~] cat /proc/sys/net/core/somaxconn 
4096

(3)修改方法:

  直接修改:

[root@active_sentinel ~] echo 511 > /proc/sys/net/core/somaxconn

  通过配置net.core.somaxconn进行修改:

[root@active_sentinel ~] echo net.core.somaxconn=4096 >> /etc/sysctl.conf
[root@active_sentinel ~] sysctl -p 

你可能感兴趣的:(Redis攻略,redis,linux,性能优化,运维)