我在网上看到延迟确认与 Nagle 算法结合可能会出现性能问题。但据我了解,Nagle 算法就是延迟确认。如果它们不一样,那有什么区别?
答案1
它们不是一回事,但有某种关联,当一起使用时可能会出现一些陷阱和问题。
延迟确认
延迟 ACK 可视为在接收端实施的措施。使用延迟 ACK,ACK 不会立即发送,而是延迟一段时间(通常为 200 毫秒),以期将需要发送的 ACK 与本地应用程序希望在另一个方向发送的一些数据合并或“搭载”。
延迟 ACK 使应用程序有机会更新窗口并可能发送立即响应。具体而言,在字符模式远程登录的情况下,延迟 ACK 可以将服务器发送的段数减少 3 倍(ACK、窗口更新和回显字符都合并在一个段中)。
此外,在一些大型多用户主机上,延迟 ACK 可以通过减少要处理的数据包总数来大幅减少协议处理开销。但是,ACK 的过度延迟可能会扰乱往返时间和数据包“时钟”算法。rfc1122
延迟 ACK 用于避免此类情况:
Client Server
| |
|----- Request ---->|
| |
|<------ ACK -------|
| |
|<---- Response ----|
| |
|------- ACK ------>|
使用延迟 ACK,TCP 将在单个段中发送请求 ACK 和响应。
Client Server
| |
|----- Request ---->|
| |
|<-- Response/ACK---|
| |
|------- ACK ------>|
John Nagle 提到本论坛
延迟 ACK 是一种赌注,即另一端几乎立即回复您刚刚发送的内容。除了某些 RPC 协议外,这种情况不太可能发生。因此,ACK 延迟机制一次又一次地输掉了赌注,延迟 ACK,等待可以搭载 ACK 的数据包,得不到它,然后延迟发送 ACK。
Nagle 算法
Nagle 算法可以看作是在发送端实现的,为了提高效率,尝试始终发送全尺寸的 TCP 数据包。
取自 TCP/IP 图解(第 1 卷):协议(作者:W. Richard Stevens)
Nagle 算法认为,当 TCP 连接中有未确认的未完成数据时,小段(小于 SMSS 的段)不能发送,直到所有未完成数据都得到确认。相反,TCP 会收集少量数据,并在确认到达时以单个段的形式发送。此过程有效地迫使 TCP 进入停止等待行为,它会停止发送,直到收到任何未完成数据的 ACK。
从实际角度来看,正如 John Nagle 在本论坛。
如果关闭 Nagle 算法,然后快速将单个字节发送到套接字,则每个字节将作为单独的数据包发出。这会使流量增加一个或两个数量级,吞吐量也会相应下降。
延迟 ACK 与 Nagle 算法交互
延迟 ACK 和 Nagle 算法交互的描述见TCP/IP 图解(第 1 卷):协议(作者:W. Richard Stevens)
假设客户端使用延迟 ACK 向服务器发送请求,而服务器响应的数据量不足以容纳在单个数据包中。
这里我们看到,客户端在收到来自服务器的两个数据包后,保留了 ACK,希望可以搭载发往服务器的其他数据。通常,只有当两个数据包是全尺寸时,TCP 才需要为它们提供 ACK,而它们不在这里。在服务器端,由于 Nagle 算法正在运行,因此在返回 ACK 之前不允许向客户端发送其他数据包,因为最多允许一个“小”数据包未完成。延迟 ACK 和 Nagle 算法的结合会导致一种死锁形式(双方都在等待对方)。
您还可以阅读有关 Nagle 算法与延迟 ACK 交互引起的问题这张纸作者:斯图尔特·柴郡(Stuart Cheshire)。
答案2
Nagle:在收到确认之前不要发送小数据包
延迟确认:延迟发送确认,直到收到足够多的小数据包
所以他们陷入僵局