丢包检测算法
TCP 在任何传输过程中对丢失的数据包使用重传,但是数据包丢失是如何发生的以及 TCP 如何检测它。在本文中,我们将讨论丢包检测算法。
什么时候发生丢包?
丢包的原因如下:
- 当接收方的缓冲区已满但发送方正在发送大量数据包时。
- 当中间设备(即路由器)的缓冲区已满并且发送方正在发送数据包时。
第一种情况与流量控制有关,接收方将其缓冲区大小通告给发送方,以免遇到这种情况。第二种情况与拥塞控制有关,发送方必须结合使用慢启动和 AIMD 来避免这种情况。
丢包检测算法:
Linux 内核使用了三种丢包检测算法。这些如下:
- RTO(重传超时)
- FR(快速重传)
- 机架(最近确认)
这些算法检测数据包丢失,发送方降低数据包传输到接收方的速率。
RTO 算法:
它最初是由Van Jacobson在 1988 年的“拥塞避免和控制”中提出的。
当发送方将数据包发送到飞行中时,它会启动一个计时器,这是 RTT 的函数。此计时器运行 RTO 时间段并等待确认到来。如果 ACK 没有在 RTO 周期内到达,则假定相应的数据包被丢弃。 RTO 是往返时间 (RTT) 的函数。它是基于“每个数据包”或“每个拥塞窗口 (cwnd)”计算的。当 RTO 计时器在 ACK 到来之前到期时,发送方得出网络拥塞的结论,并重新传输丢失的数据包并将等待时间 (RTO) 增加 2 倍。这称为二进制指数退避技术。这样做是为了让网络摆脱拥塞状态,让它呼吸。
Some important variables used in the computation of RTO
SRTT -> Smoothed RTT
RTTVar -> RTT Variation
RTO -> Retransmission TimeOut
R -> Current RTT measured
When the first RTT measurement (R) is made, the host must set:
SRTT = R
RTTVar = R ÷ 2
RTO = SRTT + (K x RTTVar), where K = 4 as proposed by Van Jacobson in 1988
When a subsequent RTT measurement (R) is made, the host must set:
RTTVar = (1 - β) x RTTVar + β x |SRTT - R|, where β = 1/4
SRTT = (1 - α) x SRTT + α x R, where α = 1/8
RTO = SRTT + (K x RTTVar), where K = 4
每当计算 RTO 时,如果小于 1 秒,则 RTO 应向上舍入到 1 秒。 RTO 可以设置一个最大值,只要它至少为 60 秒。当重传定时器超时(即没有收到ACK);发送方重传丢失的数据包,RTO = RTO x 2 RTO 的最大值应为 60 秒。
快速重传算法:
重新传输丢弃的数据包而不等待 RTO 计时器到期。如果收到“三个”重复的 ACK,则发送方重新传输丢失的数据包。发送方无需等待 RTO 时间段,而是等待直到收到三个重复的 ACK。这被称为快速重传,因为 3 个 ACK 副本比 RTO 花费的时间更少。现在,为什么它在收到“一个”或“两个”重复的 ACK 后不重新传输?因为看起来被丢弃的数据包实际上可能是“延迟的”,因此不建议不耐烦过早地重新传输数据包。现在,为什么它不等待超过三个重复的 ACK 来重新传输丢弃的数据包?因为如果它等待的时间更长,RTO 计时器可能会过期。快速重传的主要目标是避免等待 RTO 过期。
Duplicate ACK:
Sender send 6 packets to the receiver at a time. Suppose sender received the ACKs of packet 1 and 2.
Packet 3 is lost due to network congestion. Receiver received packet 4, 5 and 6.
When packet 4 is received at receiver, it sends the ACK of packet 2 but not for packet 4. ACK for packet 2 is already received. This is called Duplicate ACK.
TCP receiver always acknowledges the packets it has received in order. So, when 1-2-4-5-6 sequence goes out of order, receiver will send ACK for packet 2 only when it receives packet 4-5-6. It says that it has received till packet 2 in order. It will keep on sending duplicate ACKs until it gets all the packets in order.
After 3 duplicate ACKs for 4-5-6 packets, sender retransmits the packet 3. Receiver now gets all packets from 3-6 inorder and will send the ACK-6 which says that it has received till packet 6 inorder. This is called cumulative ACK.
FR 的局限性:
快速重传是一种启发式方法,它“有时”会比常规 RTO 机制更快地触发丢弃数据包的重传。快速重传机制不会取代常规超时;它只是增强了该设施。例如:如果数据包在 TCP 连接的“尾部”被丢弃,则快速重传机制无济于事,因为它至少需要三个重复的 ACK。
最近的确认算法:
一种称为尾部丢失探测 (TLP) 的新机制解决了数据包在 TCP 连接尾部丢失的问题。此外,谷歌还引入了一种新的丢包检测技术,称为最近确认(RACK)。
因此,当前的丢包检测方法是RACK → Fast Retransmit → RTO
Linux 内核使用所有 3 种丢失检测算法。先用RACK;当它不能达到目的时,Fast Retransmit 就会起作用;当两者都失败时,RTO 会来救援。