最近几天生产系统上线,对redis的一些参数做了一些调优,同时处理了一些问题,记录一下,这只是初级版本,如果有大佬有其他更好的优化方案,欢迎指教。

一、前置环境

操作系统

redis最好部署在linux,windows 没有官方版本,微软版本只支持到3年前的3.2.100,由于我们目前只有windows server,所以使用一个非官方维护的windows4.0.2版本

硬盘

硬盘首选SSD,当然如果没有持久化要求可以用普通机械硬盘

网络

redis和应用一定要再同一个内网环境,这个对TPS影响特别大,如果redis和应用部署在同一个服务器,那么尽量找一个内存使用不超过2/5的服务器。

高可用

建议通过哨兵实现高可用,至少3哨兵+一主一备

内存分配限制

Redis在主从复制时,需要fork子进程来进行操作,如果你的应用堆积了很大数据在内存中,那么就需要针对这个子进程申请相应的内存空间,此时会受到操作系统的限制。通过更改系统配置文件/etc/sysctl.conf的vm.overcommit_memory=1以永久生效。该参数有0、1、2三个值。1表示允许分配所有的物理内存,而不管当前的内存状态如何。

客户端获取连接限制

频繁地连服务器,但每次连接都在短时间内结束,导致很多的TIME_WAIT,以至于用光端口号,所以新连接没办法绑定端口。修改如下2个内核参数:

sysctl -w net.ipv4.tcp_timestamps=1,开启对于TCP时间戳的支持,若该项设置为0,则下面一项设置不起作用;

sysctl -w net.ipv4.tcp_tw_recycle=1,表示开启TCP连接中TIME-WAIT sockets的快速回收。

redis rdb目录配置

主从的dir需要配置为不一样的地址,否则可能报错

主从复制配置

slave需要配置该参数,slaveof <masterip> <masterport>,注意,masterip需要与master节点bind参数第一个IP一致。

二、redis参数

日志配置

日志级别和输出(loglevel、logfile),生产可调至warning级别,并写入文件中,有助于排查问题。

客户端输出缓冲区(client-output-buffer-limit)

该参数有三种场景,主要是第二种slave场景在写入比较频繁时容易出问题。

当使用主从复制时,性能压测下,数据量会急剧增长,导致从节点需要复制的数据很大,消耗时长增加。slave没挂但被阻塞住了,比如正在loading Master发过来的RDB, Master的指令不能立刻发送给slave,就会放在output buffer中(见oll是命令数量,omem是大小),在配置文件中有如下配置:client-output-buffer-limit slave 256mb 64mb 60, 这是说负责发数据给slave的client,如果buffer超过256m或者连续60秒超过64m,就会被立刻强行关闭。所以此时应该相应调大数值,否则就会出现很悲剧的循环:Master传输一个很大的RDB给Slave,Slave努力地装载,但还没装载完,Master对client的缓存满了,再来一次。

平时可以在master执行 redis-cli client list 找那个cmd=sync,flag=S的client,注意OMem的变化。

建议配置 client-output-buffer-limit slave 0 0 0

异常信息:Uncaught RedisException: Redis is LOADING the dataset 

端口绑定配置

如果redis使用了哨兵+主从,则在bind参数的第一个ip需要配置内网ip,如master 配置为bind 192.168.30.2,则redis slave的slaveof也需要配置为192.168.30.2

异常信息:Sending command to master in replication handshake: -Writing to master: Unknown error;

stop-writes-on-bgsave-error配置

redis被配置为保存数据库快照,如果快照不能持久化,则写入会报错。将stop-writes-on-bgsave-error设置为no解决。当然根本问题还是持久化出了问题,需要检查为什么不能持久化。

异常信息:MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error

端口

建议使用10000以上端口

port 29764

后台运行

linux系统配置redis后台运行

daemonize yes

三、漏洞

redis存在未授权访问漏洞,在使用之前一定要进行加固,否则系统分分钟被黑。

漏洞介绍及攻击方法。

加固方案

1、redis.conf文件添加如下配置,禁用远程修改DB文件,如config set 命令也无法使用

rename-command FLUSHALL "" 
rename-command CONFIG "" 
rename-command EVAL ""

2、为redis单独创建用户和目录,以下命令适用于linux

 


groupadd -r redis && useradd -r -g redis redis


3、为redis添加密码验证

 


requirepass mypassword


4、禁止外网访问redis

 


bind 127.0.0.1


5、linux下保证authorized_keys文件的安全,只对拥有者只读,对其他用户没有权限

 


chmod 400 ~/.ssh/authorized_keys


6、为保证authorized_keys的权限不会被改掉,您还需要设置该文件的immutable位权限

 


chattr +i ~/.ssh/authorized_keys


7、然而,用户还可以重命名~/.ssh,然后新建新的~/.ssh目录和authorized_keys文件。要避免这种情况,需要设置~./ssh的immutable位权限

 


chattr +i ~/.ssh


如果需要添加新的公钥,需要移除authorized_keys的 immutable 位权限。然后,添加好新的公钥之后,按照上述步骤重新加上immutable位权限