我tcp-backlog在redis.conf中感到困惑:
# 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
Run Code Online (Sandbox Code Playgroud)
是tcp-backlog"完整连接队列"的大小(三次握手完成,这里描述的是什么)还是"不完整的连接队列"?
如果它意味着"完整的连接队列"那么我为什么要提出tcp_max_syn_backlog哪个限制了一个不完整的连接队列的大小?
tcp-backlog 是“完整连接队列”(三路握手完成,这里描述什么)或“不完整连接队列”的大小?
tcp-backlog是完整连接队列的大小。实际上,Redis 将这个配置作为listen(int s, int backlog)调用的第二个参数传递。
@GuangshengZuo 已经对这个问题有了很好的回答。所以我会专注于另一个。
如果它意味着“完整的连接队列”,那么我为什么要提高 tcp_max_syn_backlog 来限制不完整的连接队列的大小?
引用您提到的文档:
该实现使用两个队列,一个 SYN 队列(或不完整连接队列)和一个接受队列(或完整连接队列)。状态为 SYN RECEIVED 的连接被添加到 SYN 队列,然后当它们的状态更改为 ESTABLISHED 时,即当收到 3 次握手中的 ACK 数据包时,将移动到接受队列。顾名思义,accept 调用的实现只是为了消费来自accept 队列的连接。在这种情况下,listen 系统调用的 backlog 参数决定了接受队列的大小。
我们可以看到中的项目complete connection queue从incomplete connection queue.
如果您有一个大的somaxconn和一个小的tcp_max_syn_backlog,那么您可能没有足够的项目可以移动到complete connection queue,并且complete connection queue可能永远不会装满。许多请求可能已经从第一个队列中删除,然后才有机会移动到第二个队列。
所以只提高价值somaxconn可能不起作用。你必须提高他们两个。
tcp-backlog 是接受队列或完整连接队列的大小。
正如您提到的文档所说:
在 Linux 上,情况有所不同,如监听系统调用的手册页中所述:
Linux 2.2 中 TCP 套接字上的 backlog 参数的行为发生了变化。现在它指定等待接受的完全建立的套接字的队列长度,而不是不完整的连接请求的数量。不完整套接字的队列最大长度可以使用 /proc/sys/net/ipv4/tcp_max_syn_backlog 设置。
这意味着当前的 Linux 版本使用带有两个不同队列的第二个选项:一个由系统范围设置指定大小的 SYN 队列和一个由应用程序指定大小的接受队列。
Redis服务器使用tcp-backlog的配置来通过listen()指定接受队列的大小。SYN队列的大小是由linux的管理员决定的。
如果它意味着“完整连接队列”,那么为什么我应该提高 tcp_max_syn_backlog 来限制不完整连接队列的大小?
提高 tcp_max_syn_backlog 的目的是避免客户端连接速度慢的问题。如果有一些慢速客户端正在与redis服务器进行3次握手,并且这些客户端读取响应和发送请求的速度很慢,那么它们将因为速度慢而占用redis服务器的SYN队列很长时间。
在某些情况下,由于这些低效的客户端,SYN 队列将被填满。如果SYN队列已满,redis服务器将无法接受新客户端。所以你应该提高 tcp_max_syn_backlog 来处理这个问题。