Redis 通过监听一个 TCP 端口(6379)或者 Unix socket 的方式来接收来自客户端的连接。当一个连接建立后,Redis 内部会进行以下一些操作:
(1)客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。
(2)为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法。
(3)创建一个可读的文件事件用于监听这个客户端 socket 的数据发送。
在 Redis 2.4 中,最大连接数是被直接硬编码在代码里面的,而在 Redis 2.6 版本中这个值变成可配置的。
注意,Redis 中默认最大连接数为 10000,配置最大连接数有两种方式:
我们可以通过 config set maxclients 命令设置 Redis 最大连接数,如下:
# 获取当前最大连接数 127.0.0.1:6379> config get maxclients 1) "maxclients" 2) "10000" # 将最大连接数设置为 100 127.0.0.1:6379> config set maxclients 100 OK # 获取最新的最大连接数 127.0.0.1:6379> config get maxclients 1) "maxclients" 2) "100"
注意:通过 config set maxclients 命令设置的最大连接数是临时的,如果重启 Redis 服务,该命令的配置将丢失。
除了命令行方式外,还可以通过配置文件(redis.conf)的方式修改 Redis 最大连接数。
在 redis.conf 文件的 CLIENTS 模块,设置同时连接的最大客户端数量。默认情况下,此限制设置为 10000 个客户端。但是,如果 Redis 服务器无法将进程文件限制配置为允许指定的限制,则允许的最大客户端数量将设置为当前文件限制减去 32(因为 Redis 保留了一些文件描述符供内部使用)。
实例:将 Redis 的最大客户端数永久的设置为 100,如下:
################################### CLIENTS #################################### # Set the max number of connected clients at the same time. By default # this limit is set to 10000 clients, however if the Redis server is not # able to configure the process file limit to allow for the specified limit # the max number of allowed clients is set to the current file limit # minus 32 (as Redis reserves a few file descriptors for internal uses). # # Once the limit is reached Redis will close all the new connections sending # an error 'max number of clients reached'. # # maxclients 10000 # 将最大客户端数设置为100,默认为 10000 maxclients 100
配置完成后,重启 Redis 服务,再使用 config get maxclients 命令获取,如下:
127.0.0.1:6379> config get maxclients 1) "maxclients" 2) "100"
注意:客户端连接一旦达到最大客户端限制,Redis 将关闭所有新连接,并发送错误 “max number of clients reached(已达到最大客户端数)”。
服务端根据频率定时检测所有 client 的空闲时间是否超过配置的 timeout 值。如果超过 timeout 参数就会关闭这个连接,空闲时长可以根据 client list 查看服务端的连接信息,其中的 idle 值就表示空闲时长。
与客户端最大连接数类似,也支持通过命令行和配置文件进行配置,如下:
(1)通过命令行配置 timeout,如下:
127.0.0.1:6379> config get timeout 1) "timeout" 2) "0" # 临时设置 timeout 值 127.0.0.1:6379> config set timeout 100 OK # 查看最新 timeout 值 127.0.0.1:6379> config get timeout 1) "timeout" 2) "100" # 查看客户端列表 127.0.0.1:6379> client list id=904 addr=127.0.0.1:4339 fd=42 name= age=1247 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client
(2)通过配置文件方式配置 timeout,如下:
# Close the connection after a client is idle for N seconds (0 to disable) # 在客户端空闲N秒后关闭连接(0表示禁用) timeout 0
注意:通过命令行修改的 timeout 是临时的,重启 Redis 服务后修改将丢失;通过配置文件修改是永久的,重启 Redis 服务也不会丢失;
服务端会根据这个参数定时给客户端发送 TCP 心跳包,检测网络连通性,当网络异常时,可以尽快清理 TCP 僵尸连接。
当客户端与服务端网络发生问题时,服务端并不会立即释放这个 client。如果 Redis 没有开启 tcp-keepalive 的话,服务端直到配置 timeout 时间后,才会清理释放这个 client。
在没有清理之前,如果还有大量新连接进来,就有可能导致 Redis 服务端内部持有的 client 超过了 maxclients,这时新连接就会被拒,所以建议开启此配置。
与客户端最大连接数类似,也支持通过命令行和配置文件进行配置,如下:
(1)命令行方式设置 tcp-keepalive,如下:
# 获取旧值 127.0.0.1:6379> config get tcp-keepalive 1) "tcp-keepalive" 2) "300" # 设置新的 tcp-keepalive 值 127.0.0.1:6379> config set tcp-keepalive 400 OK # 获取新的 tcp-keepalive 值 127.0.0.1:6379> config get tcp-keepalive 1) "tcp-keepalive" 2) "400"
(2)配置文件方式设置 tcp-keepalive,如下:
# TCP keepalive. # # If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence # of communication. This is useful for two reasons: # # 1) Detect dead peers. # 2) Take the connection alive from the point of view of network # equipment in the middle. # # On Linux, the specified value (in seconds) is the period used to send ACKs. # Note that to close the connection the double of the time is needed. # On other kernels the period depends on the kernel configuration. # # A reasonable value for this option is 300 seconds, which is the new # Redis default starting with Redis 3.2.1. #tcp-keepalive 300 # 将 tcp-keepalive 修改为 400 tcp-keepalive 400
注意:修改配置文件后,需要重启 Redis 服务。
TCP 三次握手后,会将接受的连接放入队列中,tcp-backlog 就是队列的大小,它在 Redis 中的默认值是 511。通常来讲这个参数不需要调整,但是这个参数会受到操作系统的影响,例如在 Linux 操作系统中,如果 /proc/sys/net/core/somaxconn 小于 tcp-backlog,那么在 Redis 启动时会看到如下日志,并建议将 /proc/sys/net/core/somaxconn设置更大。
与上面的配置不同,tcp-backlog 仅仅支持配置文件进行配置,如下:
(1)命令行方式设置 tcp-backlog(不支持),如下:
127.0.0.1:6379> config get tcp-backlog 1) "tcp-backlog" 2) "511" 127.0.0.1:6379> config set tcp-backlog 1000 (error) ERR Unsupported CONFIG parameter: tcp-backlog
注意:通过命令行方式修改 tcp-backlog 报错了,不支持。
(2)配置文件方式设置 tcp-backlog,如下:
# TCP listen() backlog. # # In high requests-per-second environments you need an high backlog in order # to avoid slow clients connections issues. Note that the Linux kernel # will silently truncate it to the value of /proc/sys/net/core/somaxconn so # make sure to raise both the value of somaxconn and tcp_max_syn_backlog # in order to get the desired effect. #tcp-backlog 511 # 将 tcp-backlog 修改为 1000 tcp-backlog 1000
注意:修改配置文件后,需要重启 Redis 服务。