我被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
?
tcp囤积的大小是"完整连接队列"(三方握手完成,如本文所述)还是"不完整的连接队列"?
tcp-backlog
是完整连接队列的大小。事实上,Redis将此配置作为listen(int s, int backlog)
调用的第二个参数进行传递。
@对于这个问题,广生左已经有了一个很好的答案。所以我会专注于另一个。
如果它的意思是"完整的连接队列",那么我为什么要引发tcp_max_sync_backlog来限制不完整连接队列的大小?
引用您提到的文档:
该实现使用两个队列,一个SYN队列(或不完整连接队列)和一个接受队列(或完整连接排队)。处于SYN RECEIVED状态的连接被添加到SYN队列中,然后当它们的状态变为ESTABLISED时,即当接收到3向握手中的ACK数据包时,被移动到接受队列中。顾名思义,accept调用的实现只是为了使用来自accept队列的连接。在这种情况下,侦听系统调用的backlog参数决定了接受队列的大小。
我们可以看到complete connection queue
中的项是从incomplete connection queue
中移动的。
如果您有一个大的somaxconn
和一个小的tcp_max_syn_backlog
,那么您可能没有足够的项目移动到complete connection queue
,并且complete connection queue
可能永远不会满。在有机会移动到第二个队列之前,许多请求可能已经从第一个队列中删除。
因此,仅提高somaxconn
的值可能不起作用。你必须把他们两个都养大。
tcp囤积是接受队列或完整连接队列的大小。
正如你提到的医生所说:
在Linux上,情况有所不同,正如侦听系统调用的手册页中所提到的:
TCP套接字上囤积参数的行为随着Linux 2.2而改变。现在,它指定等待接受的完全建立的套接字的队列长度,而不是不完整连接请求的数量。可以使用/proc/sys/net/ipv4/tcp_max_sync_backlog设置不完整套接字的队列的最大长度。
这意味着当前Linux版本将第二个选项与两个不同的队列一起使用:大小由系统范围设置指定的SYN队列和大小由应用程序指定的接受队列
Redis服务器使用tcp囤积的配置来使用listen()指定接受队列的大小。SYN队列的大小由linux的管理员决定。
如果它的意思是";完整连接队列";,那么我为什么要提升tcp_max_sync_backlog来限制不完整连接队列的大小呢
提升tcp_max_sync_backlog的目的是避免客户端连接缓慢的问题。如果有一些速度较慢的客户端正在与redis服务器进行三向握手,而这些客户端读取响应和发送请求的速度较慢,那么它们将占用redis服务器的SYN队列很长一段时间,因为它们速度较慢。
在某些情况下,SYN队列将被填充,因为这些客户端效率低下。如果SYN队列已满,redis服务器将无法接受新客户端。因此,您应该引发tcp_max_sync_backlog来处理此问题。
昨天,我读了《Redis in Action》中约书亚·卡尔顿的第6章写道:"Redis发布和订阅的缺点之一模型是客户端必须始终连接才能接收消息,断开连接可能会导致客户端丢失消息,以及如果有一个慢订户。">
Joshua Carlton表示,"虽然推送消息可能很有用,但当客户端由于某种原因无法始终保持连接时,我们会遇到问题。为了解决这一限制,我们将编写两种不同的拉式消息传递方法,可以用作PUBLISH/SUBSCRIBE的替代品。我们将首先从单收件人消息传递开始,因为它与我们的先进先出队列有很多共同之处。Lat呃,在本节中,我们将转到一个方法,在该方法中,我们可以有多个消息的收件人。有了多个收件人,当我们需要将消息发送给所有收件人时,我们可以替换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的单收件人消息传递和多收件人消息传递方法在每秒20000条消息的负载下断开连接,其中每条消息是20字节?