redis.conf中的"tcp-backlog"是什么?

14

我对redis.conf中的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”是“完成连接队列”的大小(即三次握手已经完成,如这里所描述的),而不是“未完成连接队列”。

如果它表示“完成连接队列”,那么为什么我要提高“tcp_max_syn_backlog”呢?它限制了一个未完成的连接队列的大小。


好问题。它是已完成连接队列。SYN积压是独立的。我看不出他们需要跟踪的原因。 - user207421
3个回答

10

tcp-backlog 是指“完成连接队列”(即三次握手完成的队列),而不是“未完成连接队列”。

实际上,Redis 将此配置作为 listen(int s, int backlog) 调用的第二个参数传递。

@GuangshengZuo 已经给出了一个好答案,所以我将重点放在另一个方面。

如果它指的是“完成连接队列”,那么为什么我要提高限制未完成连接队列大小的 tcp_max_syn_backlog 呢?

引用您提到的文档:

该实现使用两个队列:SYN 队列(或未完成连接队列)和 accept 队列(或已完成连接队列)。 状态为 SYN RECEIVED 的连接将添加到 SYN 队列中,并在其状态更改为 ESTABLISHED 时(即在 3 次握手中收到 ACK 包时)移动到 accept 队列中。 正如名称所示,然后只是为了从 accept 队列中消耗连接来实现 accept 调用。 在这种情况下,listen 系统调用的 backlog 参数确定 accept 队列的大小。

我们可以看到,完成连接队列 中的项目是从 未完成连接队列 移动而来的

如果您有一个大的 somaxconn,但只设置了较小的 tcp_max_syn_backlog,那么您可能没有足够的项目可以移动到 完成连接队列 中,并且 完成连接队列 可能永远不会被填满。在它们有机会移动到第二个队列之前,许多请求可能已经从第一个队列中丢失了。

因此,仅提高 somaxconn 的值可能不起作用。您必须同时提高两者的值。


5
tcp-backlog是accept队列或者完全连接队列的大小。
正如您提到的文档所说:
在Linux上,情况有所不同,正如listen系统调用的man页面中所述:
backlog参数在TCP套接字上的行为随着Linux 2.2发生了变化。现在它指定等待被接受的完全建立的套接字的队列长度,而不是不完整的连接请求数量。不完整套接字队列的最大长度可以使用/proc/sys/net/ipv4/tcp_max_syn_backlog设置。
这意味着当前的Linux版本使用第二个选项,具有两个不同的队列:一个SYN队列,其大小由系统范围的设置指定,以及一个由应用程序指定大小的accept队列。 Redis服务器使用tcp-backlog的配置来指定通过listen()的accept队列的大小。而SYN队列大小是由Linux管理员确定的。
如果它的意思是“完全连接队列”,那么为什么我要提高tcp_max_syn_backlog,这会限制不完整的连接队列的大小?
提高tcp_max_syn_backlog的目的是为了避免慢客户端连接问题。如果有一些慢速客户端正在与redis服务器进行三次握手,而这些客户端读取响应并发送请求很慢,它们将长时间占用redis服务器的SYN队列,因为它们很慢。
在某些情况下,SYN队列将因这些效率低下的客户端而填满。如果SYN队列已满,则redis服务器无法接受新客户端。因此,您应该提高tcp_max_syn_backlog来处理这个问题。

0
昨天,我读了《Redis In Action》的第6章,Joshua Carlton写道:“Redis发布和订阅模型的缺点之一是客户端必须始终保持连接以接收消息,断开连接可能会导致客户端丢失消息,而旧版本的Redis如果有慢订阅者,则可能变得无法使用、崩溃或被杀死。”
然后,Joshua Carlton指出:“虽然推送消息可能很有用,但当客户端由于某种原因无法始终保持连接时,我们会遇到问题。为了解决这个限制,我们将编写两种不同的拉取消息方法,可以用作PUBLISH/SUBSCRIBE的替代品。我们首先从单收件人消息开始,因为它与我们的先进先出队列有很多共同之处。在本节的后面,我们将转向一种可以有多个收件人的方法。有了多个收件人,即使他们断开连接,我们也可以替换Redis PUBLISH和SUBSCRIBE,使我们的消息能够到达所有收件人。”
我们想知道,是否使用Joshua Carlton的第6.5.2节“多收件人发布/订阅替代方案”来替换Redis PUBLISH和SUBSCRIBE比利用UDP协议检测和修复断开连接损失更有效。
 Could we set a high tcp_max_syn_backlog in redis.conf to prevent either of

Joshua Carlson 的单一收件人消息和多收件人消息方法如何能在每秒 20,000 条消息、每条消息大小为 20 字节的负载下不断开连接?

@GuangshengZuo,redis.conf中的tcp_max_syn_backlog设置为多少可以防止在每秒20,000条消息(每条消息20字节)的负载下,Joshua Carlson的单收件人消息和多收件人消息方法中任何一个断开连接?谢谢。 - Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接