获取服务器支持的最大文件描述符数(该 值会限制你的最大文件打开数,对我们而言,关心的是可供打开的socket的数量)

linux机器可以使用 ulimit 命令获取你关心的一些指数

可以看到支持的最大文件描述符数是4000

也可以直接通过 ulimit -n 获取文件描述符数

还可以通过该命令修改最大文件描述符数

在我们线上机器系统配置文件对应位置为:/etc/sysctl.conf,目前我们线上机器配置的最大文件描述符数为655350

 

 

关于redis配置文件一些参数的理解:

daemonize no/yes    Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程(我个人是理解就是设置为yes可以支持后台运行redis)

port 6379    指定Redis监听端口,默认端口为6379

bind 127.0.0.1    绑定的主机地址

timeout 300    当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

databases 16    设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id

maxclients 128     设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息(所以想要让redis支持更多的连接数,需要将文件描述符数和maxclients同时设置的大一些,而最终的最大连接数取决于二者较小的那个值)

 

 

通过以上两种设置,貌似redis已经可以支持大量的客户端连接了,但是采用 redis-benchmark 进行压力测试,会出现如下错误:

-- Could not connect to Redis at IP:PORT,Cannot assign requested address.

这是因为redis-benchmark的压力测试时频繁的连服务器,数据量较大的时候,由于每次连接都在很短的时间内结束,导致很多的TIME_WAIT,以至于用光了可用的端口号,所以新的连接没办法绑定端口,即“Cannot assign requestedaddress”。

 

可以通过 netstat -ant|grep TIME_WAIT 过滤出来大量的未关闭连接,效果大概是下边这个样子

 

这时,你需要让系统知道对于这种TIME_WAIT的TCP连接应该快速回收,以释放端口,供更多的客户端可以请求分配到端口并访问我们的redis

命令如下:

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

 

 

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

 

执行后,利用 redis-benchmark 做压力测试,不会再出现 Cannot assign requested address 这个错误

redis-benchmark 压力测试命令:

redis-benchmark -h 127.0.0.1 -p 6379 -c 20000 -n 20000    (h对应参数为ip,p对应参数为端口,c对应参数为并发连接数,n对应参数为请求数量)

 

这时,你可以看到高并发时 redis 对于不同操作的平均响应时长(只截取部分结果)

在xadtest这台机器上测试20000并发连接数,20000个请求的效果数据如图(可以看到最长响应时长已经达到577ms,目前我们线上服务器的平均响应时长为110ms左右;PS:可能线上的服务器响应效果会好一些,但是有业务在跑,就没做测试):

 

需要额外提一点:上边提到要让服务器快速关闭TIME_WAIT的TCP连接,会对系统设置做两个修改

sysctl -w net.ipv4.tcp_timestamps=1

sysctl -w net.ipv4.tcp_tw_recycle=1

 

但是目前我们线上服务器配置文件里的内容为:

 

#时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉
net.ipv4.tcp_timestamps = 0    (与上述修改是有冲突存在的)

#开启TCP连接复用功能,允许将time_wait sockets重新用于新的TCP连接(主要针对time_wait连接)
net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

贸然更改系统配置,是会影响我们的线上服务的,测试操作请上测试机!!!

本文内容在类linux环境使用,不适用mac/windows 

后续如果涉及到redis集群,会再做补充