1. 简介 (Introduction)
Van Jacobson的包守恒原则(packet conservation principle)[Jacobson88]定义了一个自时钟过程,其中向接收方交付的N个数据段会生成确认,数据发送方使用这些确认作为时钟来触发向网络发送另外N个数据段。
像Reno[RFC5681]和CUBIC[RFC9438]这样的拥塞控制算法建立在这个自时钟过程的概念基础之上。它们通过使用拥塞窗口(congestion window, "cwnd")来限制"inflight"(连接在给定时间估计在网络中飞行的数据量)来控制传输协议连接的发送过程。此外,这些算法要求传输协议连接在响应丢包时减少其cwnd。快速恢复(fast recovery,参见[RFC5681]和[RFC6675])是使用来自确认的反馈来执行此cwnd减少的算法。其既定目标是通过在恢复期间依靠返回的ACK来将更多数据时钟化进入网络,从而维持发送方的自时钟。
在没有比例速率降低(Proportional Rate Reduction, PRR)的情况下,快速恢复通常通过等待大部分往返时间(round-trip time, RTT)(对于Reno[RFC5681]是半个往返时间的ACK,或对于CUBIC[RFC9438]是30%的往返时间)后才发送任何数据来调整窗口。
[RFC6675]通过计算"pipe"(发送方对网络中仍然未确认的字节数的估计)使支持选择确认(Selective Acknowledgment, SACK)[RFC2018]的快速恢复更加准确。使用[RFC6675],快速恢复通过在每个ACK上根据需要发送数据来实现,以允许pipe上升到与ssthresh(由拥塞控制算法确定的快速恢复的目标窗口大小)匹配。这在许多存在严重丢包的情况下保护快速恢复免于超时。然而,[RFC6675]有两个显著的缺点。
首先,因为它在快速恢复开始时对cwnd进行大的乘法减少,如果整个窗口的后半部分的数据或ACK丢失,它可能导致超时。其次,携带SACK选项且暗示大量缺失数据的单个ACK可能导致pipe估计器出现阶跃不连续性,这可能导致快速重传发送大量突发数据。
PRR以一种避免这些过度窗口调整的方式调节快速恢复期间的传输过程,使得传输平稳进行,并且在恢复结束时,实际窗口大小将尽可能接近ssthresh。
PRR的方法受到Van Jacobson的包守恒原则的启发。PRR尽可能依赖自时钟过程,并且仅轻微受到估计器准确性的影响,例如对飞行中数据量的估计。这就是该算法在导致其他估计器不确定性的事件存在时仍能保持精确性的原因。
当inflight高于ssthresh时,PRR通过以与已交付数据和ssthresh成比例的速率时钟化出传输,平稳地将inflight降低到ssthresh。
当inflight低于ssthresh时,PRR在两个降低边界(Reduction Bounds)之间自适应选择,以限制由所有机制(包括瞬态应用程序停顿和丢包本身)导致的总窗口减少。作为基准,当可能存在相当大的拥塞时,为了谨慎,PRR使用其保守降低边界(Conservative Reduction Bound, CRB),它严格遵守包守恒。当恢复似乎进展顺利时,PRR使用其慢启动降低边界(Slow Start Reduction Bound, SSRB),它比PRR-CRB更激进,每个ACK最多增加一个段。
PRR-CRB满足附录A中描述的强包守恒边界(Strong Packet Conservation Bound);然而,当在实际网络中作为唯一方法使用时,它的性能不如[RFC6675]中描述的算法,后者在大量情况下被证明更激进。PRR-SSRB通过在某些情况下允许连接相对于PRR-CRB每个ACK发送一个额外的段来提供折衷。尽管PRR-SSRB不如[RFC6675]激进(传输更少的段或花费更多时间传输它们),但由于在恢复期间额外丢包的概率较低,它的表现优于后者。
包守恒原则的原始定义[Jacobson88]将被推定为丢失的包(例如,标记为重传候选的包)视为已离开网络。这个想法反映在PRR使用的inflight估计器中,但它不同于附录A中描述的强包守恒边界,后者仅基于到达接收方的数据来定义。
本文档规定了相对于[RFC6937]中PRR早期版本的几个主要变更。首先,它引入了一个新的自适应启发式方法,取代了一个手动配置参数,该参数决定当inflight低于ssthresh时PRR的保守程度(是使用PRR-CRB还是PRR-SSRB)。
其次,该算法规定了非SACK连接(未通过"SACK-permitted"选项协商SACK[RFC2018]支持的连接)的行为。第三,该算法确保即使在发送方经历高度重新排序并在大量序列空间已被SACKed后才开始丢包恢复的情况下,也能保持平稳的发送过程。
最后,本文档还包括关于PRR与拥塞控制和丢包检测算法集成的额外讨论。
自2011年首个广泛部署的TCP PRR实现[First_TCP_PRR]以来,PRR在多个TCP实现中拥有广泛的部署经验。