概述
接下来将详细了解 /usr/local/redis/conf/redis.conf 文件里的各个参数,请注意!以下的参数仅针对 Redis 7.2.3 版本。
这个配置文件一共划分了几个部分,它们分别是:
- INCLUDES
- MODULES
- NETWORK
- TLS/SSL
- GENERAL
- SNAPSHOTTING
- REPLICATION
- KEYS TRACKING
- SECURITY
- CLIENTS
- MEMORY MANAGEMENT
- LAZY FREEING
- THREADED I/O
- KERNEL OOM CONTROL
- KERNEL transparent hugepage CONTROL
- APPEND ONLY MODE
- SHUTDOWN
- NON-DETERMINISTIC LONG BLOCKING COMMANDS
- REDIS CLUSTER
- CLUSTER DOCKER/NAT support
- SLOW LOG
- LATENCY MONITOR
- LATENCY TRACKING
- EVENT NOTIFICATION
- ADVANCED CONFIG
- ACTIVE DEFRAGMENTATION
当涉及到内存配置的参数值时,其单位需要注意(不区分大小写,1GB、1Gb、1gb都是一样的),比如:
- 1k => 1000 bytes
- 1kb => 1024 bytes
- 1m => 1000000 bytes
- 1mb => 1024*1024 bytes
- 1g => 1000000000 bytes
- 1gb => 1024*1024*1024 bytes
由于涉及到的内容较多,配置文件里的内容共划分为三份文件。
INCLUDES 部分
该部分的参数用来包含额外的配置文件(支持通配符 * ),比如 include /usr/local/redis/conf/*.conf
。灵活的配置推荐——将上面的每个部分划分为一个单独的 .conf 文件放入到 /usr/local/redis/conf/ 目录中,方便后期的维护。如果要用包含的配置文件参数覆盖默认 redis.conf 里的参数,请将 include 参数写入到 redis.conf 的最后一行,这通常用于测试。
MODULES 部分
启动 Redis 实例后用来加载 .so 模块,可使用多个 loadmodule 参数(官方称为指令,不习惯),比如:
loadmodule /usr/local/redis/modules/my_module.so
loadmodule /usr/local/redis/modules/other_module.so
模块可以对 Redis 的功能进行扩展与增强。同 nginx 模块一样,这里的模块属于 动态模块 。
NETWORK 部分
相关的重要参数有:
- bind 192.168.1.30 // 绑定接口的 IP 地址
- protected-mode no // 安全模式为 no
- port 6379 //占用的端口号
- tcp-backlog 511 // 一个影响性能的关键参数,稍后将介绍
- timeout 0 // 当客户端连接后的空闲时间超过该阈值时,表示超时,连接会被断开。0值表示关闭超时功能。
- tcp-keepalive 300 // tcp-keepalive 是 TCP/IP 协议当中的一个保持活跃的机制(有些资料称为 TCP 长连接)。作用之一是保持 TCP 的连接,在一次 TCP 连接中多次传输数据(报文)而不用反复的三次握手;作用之二是周期性探测,Redis 当中由 server 端发出,以秒为单位,在两次探测客户端后,客户端并无 ACK 回复 ,则会关闭连接。当 timeout 设置为0 时, TCP 长连接才生效;当 tcp-keepalive 设置为 0 时,表示关闭长连接。是否开启 Redis 的长连接,看具体的使用场景。
关于 tcp-backlog 的知识
tcp-backlog 是一个处理关于 tcp 连接队列的这样一个参数(与三次握手相关),在高并发场景下,参数值的多少与性能直接挂钩。
众所周知,在 TCP/IP 协议族当中,在传输层这里有两个协议:
- TCP(传输控制协议):面向连接的协议,即收发数据前,必须与对方建立可靠的连接。拥有三次握手、四次挥手的特征。相比 UDP,TCP能够保证数据的准确性,同时还更加安全。
- UDP(用户数据报协议):一种无连接的传输协议,提供面向事务的不可靠信息传输服务,其传输的速度相比 TCP 更快,但数据有可能丢失。
首先回顾下 TCP 的报头结构:
标志:数据标志,6个标志只能选择其中的一个。
- URG – 紧急指针字段,当URG=1时,此字段告诉系统此报文段中有紧急数据,应尽快传送。
- ACK – 确认字段,当ACK=1时,表示确认,且确认号有效;当ACK=0时,确认号字段无效。
- PSH – 推送字段,当PSH=1时,提示接收端应用程序应该立即从TCP接受缓冲区中读走数据,为接受后续数据腾出空间。如果不将接收到的数据读走,它们就会一直停留在TCP报文段。
- RST – 复位字段,当RST为1时,表明TCP连接中出现了严重的差错,必须释放连接,然后再重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。
- SYN – 同步字段,当SYN=1时,表示发起一个连接请求。我们称携带SYN标志位的TCP报文段为同步报文段。
- FIN – 中止字段,用来释放连接。当FIN=1时,表明此报文段的发送端的数据已发送完成,并要求释放连接。我们称携带FIN标志的TCP报文段为结束报文段。
所谓 TCP 的三次握手,其实就是指三次交互过程:
状态说明:
- CLOSED – 没有任何连接状态
- LISTEN – 监听来自客户端的连接请求
- SYN_SENT – 同步发送状态
- SYN_RCVD – 同步接收状态
- ESTAB_LISHED – 打开的连接,数据可以传输。
三次握手的过程就好像打电话:
- A:「服务器B,你在吗?」
- B:「我在。」
- A:「我要给你传输数据。」
当服务端调用 listen() 等函数时,状态由 CLOSED 变更为 LISTEN,此时的 Linux 内核会 创建/维护 两个队列:
- 半连接队列(Incomplete Connection queue,又称 SYN 队列) – 当服务端接收到了客户端的 SYN 且返回了 SYN 和 ACK,此时服务端状态变更为 SYN_RCVD ,会将用户的请求放入到半连接队列中。
- 全连接队列(Completed Connection queue,又称 ACCEPT 队列) – 等到客户端返回 ACK,此时三次握手完成,半连接队列会被释放且移动到全连接队列。
当半连接队列或全连接队列发生了问题(比如队列满了),TCP 三次握手的机制就不成功,因此,在一些高并发的场景下进行优化时,需要调整队列的配置。
# 在 Linux 内核当中,半连接队列的大小取决于这个文件的内容——/proc/sys/net/ipv4/tcp_max_syn_backlog
## 在 Rocky Linux 8.x 中,这个值为 128
Shell > cat /proc/sys/net/ipv4/tcp_max_syn_backlog
128
# 全连接队列的大小由两部分决定——listen 函数里的 backlog 以及 Linux 内核参数 /proc/sys/net/core/somaxconn,最终的队列大小由数字最小的那个来决定
Shell > cat /proc/sys/net/core/somaxconn
2048
如何知道某个服务的全连接队列大小?
使用 ss
命令查阅 Send-Q 这一列。
Shell > /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
Shell > ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=764,fd=5))
udp UNCONN 0 0 [::1]:323 [::]:* users:(("chronyd",pid=764,fd=6))
tcp LISTEN 0 511 192.168.100.3:6379 0.0.0.0:* users:(("redis-server",pid=1654,fd=6))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=777,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=777,fd=4))
如您所见,Linux 内核全连接队列的大小为2048,但是 Redis 配置文件的 backlog 则是511,取最小的值,所以 511 就是 redis 最终的全连接队列大小。
如果全连接队列满了,Linux 内核会如何处理?
与这个内核参数有关——/proc/sys/net/ipv4/tcp_abort_on_overflow ,有效值为 0 或 1
- 0 值:重试。在客户端等待超时后,重新发送 ACK,让服务端重新进入到 ESTAB_LISHED 状态
- 1 值:断开连接。服务端会发送 RST 包给客户端,客户端会收到诸如 "104 Connection reset by peer" 的错误
Shell > cat /proc/sys/net/ipv4/tcp_abort_on_overflow
0
sysctl -p
命令重新加载,使修改生效。