摘要
- 比例速率缩减(PRR)不是重新判断拥塞有多严重,而是依据每个 ACK 所报告的交付进展,计算本次可以发送多少字节,让实际在途量平滑靠近拥塞控制算法已经选定的
ssthresh。 - ACK 在这里是一张窄义的运行回执,不是“路径已经恢复”的证书;可信的部署必须分别留存目标由谁选择、PRR 走了哪条分支、实际发了什么、是否启用 pacing,以及结果是否真的改善。
窗口到达目标,不等于恢复过程正确
设想一次丢包发生时,发送端估计网络中仍有二十个报文段,拥塞控制算法把恢复结束时的目标定为十。旧式快速恢复可能立即砍低窗口,然后等在途量下降;等到条件满足,又一次放出多个报文段。RFC 9937 的示例把其中一段称为“半个窗口的沉默”。如果 pipe 之类的在途估计突然跳变,还可能出现相反的问题:瞬间得到过大的发送机会,形成突发。
PRR 处理的不是最终“十”这个数字,而是到达十的节奏。ACK 每返回一次,发送端才重新核算一次额度。自时钟没有被一刀切断,主动缩窗也不必集中在一个时刻完成。
这一机制首先出现在 Nandita Dukkipati、Matt Mathis、Yuchung Cheng 和 Monia Ghobadi 共同发表的 2011 年论文中。研究观察了短流、应用停顿、突发丢包、ACK 丢失与乱序、以及一次确认多个报文的 stretch ACK。论文指出,当时的机制可能把窗口压得过低,也可能在重度丢包时放出大突发;在其测量对象中,PRR 与早期重传研究让遭遇丢包的连接延迟下降了 3% 至 10%,具体取决于响应大小。这个数字属于那项研究,不能外推成所有网络的收益承诺。
2013 年的实验性 RFC 6937 由 Mathis、Dukkipati 和 Cheng 共同署名。2025 年 12 月发布的标准轨 RFC 9937 取代了它,作者为 Mathis、Neal Cardwell、Cheng 和 Dukkipati。这条证据链说明 Dukkipati 从原始测量问题、实验规范到修订标准都与 PRR 有持续、公开的联系;它既不支持“单独发明”,也不意味着她控制所有实现。
先把四种权力拆开
理解 PRR 的关键,不是背公式,而是看清谁能决定什么。
第一,拥塞控制算法选择 ssthresh。它是本次快速恢复希望达到的在途量目标。Reno、CUBIC 或其他符合接口条件的算法可以作出这一选择。PRR 不负责判断拥塞应该让窗口缩到多小,也不拥有目标。
第二,丢包检测与确认处理提供观察。RFC 9937 把 DeliveredData 定义为发送端对“当前 ACK 表明自上一个 ACK 以来已有多少字节到达接收端”的最佳估计。这里的“最佳估计”不能省略:它是局部证据,不是网络全景。
第三,PRR 计算 SndCnt,也就是收到这个 ACK 后究竟允许发送多少字节。第四,另一个发送选择函数决定这些额度用于重传缺失数据,还是发送新数据。PRR 管数量与时机,不管所选字节的身份。
把这些责任拆开,正体现了最小初始规范的价值:共同层对需要互操作的计算写得足够精确,但不把需要其他状态的选择强塞给同一个模块。一个 ACK 到达,并不会因此获得决定目标、解释丢包原因或宣告恢复成功的权限。
把交付进展变成放行时钟
恢复开始时,发送端记录 RecoverFS,即它估计本轮最初可能完成交付的飞行量;同时把累计交付记入 prr_delivered,把恢复期间已经发出的数据记入 prr_out。
当估计在途量仍高于 ssthresh 时,PRR 根据“已经交付的比例”和“目标相对原始飞行量的比例”,计算截至当前本应放行多少数据,再减去已经发出的 prr_out,得到本次 SndCnt。整数运算向上取整,避免细碎进度永久丢失。
于是,ACK 的角色更像一张会触发限额更新的回执。小步交付带来小步放行;如果中间几个 ACK 丢失,后续 ACK 可以一次报告更多累计进展,算法会补足应有额度,却不会仅因估计量出现断崖式变化就无上限突发。
这是一种很克制的信任:发送端无需在每次放行前知道拥塞的“终极真相”,只需验证一项与本次动作相称的事实。交付进展可以驱动额度,不能篡夺 ssthresh 的制定权。
低于目标时,谨慎也要有边界
重度丢包可能让 inflight 落到 ssthresh 以下。若始终严格按已交付量一比一放行,恢复可能过慢;若看到空位就激进补满,又可能制造下一轮丢包。RFC 9937 因此保留两种 Reduction Bound。
默认的 Conservative Reduction Bound(CRB)把发送紧紧约束在交付进展上。只有当 SafeACK 为真,Slow Start Reduction Bound(SSRB)才可在原额度上最多增加一个发送端最大报文段。SafeACK 为真必须同时满足:累计确认号前进,而且这个 ACK 没有表明又出现新的丢包。
2025 年修订版把两种边界的选择改成自适应,与令牌桶流量监管器暴露出的特殊场景有关。令牌耗尽后,监管器可能突然大量丢弃,而端系统事先看不到令牌补充速率。发送端依据此前性能选出的 ssthresh 可能明显过高。新规则因此先保守,等窄义的“进展良好”证据出现,才允许多一个报文段。
名称不能超过事实。SafeACK 并不表示整条路径安全,只表示当前 ACK 满足这一处分支允许有限加速的两个条件。
收尾仍可能突发
每次实际发送时,PRR 都增加 prr_out。本轮结束后,它把 cwnd 设置为 ssthresh,让最终状态明确。但 RFC 9937 同时指出,这一步在某些情况下可能允许连续报文段突发,因此建议实现使用 pacing 来缓和流量。
这条警告很重要。PRR 没有宣称所有时间风险已经消失;规范中提到的一些软 pacing 潜在效果也并未全部量化。标准成熟度说明算法接受过公开审查,不等于某个二进制文件实现正确,更不等于某项业务已经获得收益。
RFC 9937 记录,自 2011 年首个广泛部署的实现以来,PRR 一直是 Linux TCP 对默认及所支持拥塞控制模块采用的快速恢复算法。这是运行代码的历史证据,但仍不能回答某台机器昨天走了 CRB 还是 SSRB、是否启用了 pacing、或者用户延迟是否改善。
运维需要一张逐次可复核的回执
可信记录应先标明实现或内核版本、拥塞控制模块、丢包检测触发条件、本轮开始时的 cwnd、inflight 与 RecoverFS,以及哪个组件以什么配置选择了 ssthresh。
对每个相关 ACK,至少保留累计确认是否前进、新增丢包、DeliveredData、SafeACK 的值与原因、实际选择的比例分支或 CRB/SSRB、算出的 SndCnt、真正发送的字节和新的 prr_out。重传还是新数据的选择也应单独记录,不能混进 PRR 的功劳或责任。
结束时还要记录最终窗口与在途估计、pacing 状态、是否出现收尾突发、超时或重复丢包,并把延迟与有效吞吐的分布和可比较的控制组对照。测试应覆盖乱序、应用停顿、支持条件下的 SACK 与非 SACK,以及令牌桶监管。负面证据不能删:ACK 可以持续前进,而路径或应用表现依然恶化。
这样,主张才有清晰层次。ACK 报告交付;拥塞控制选择目标;PRR 计算额度;发送器选择字节;运行代码执行;测量结果决定效果。RFC 的标题不能替任何一层签字。
来源
- IETF Datatracker — Nandita Dukkipati
- Linux 内核 — 首个广泛部署的 TCP PRR 实现
- Heng Lu — Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
- Heng Lu — On the Agency Problem at the Core of Internet Governance
- Heng Lu — Running-Code Primacy
- Google Research — Excellent Papers for 2011
- Google Research — Nandita Dukkipati
- Google Research — Proportional Rate Reduction for TCP
- Google Research — RFC 6937 论文记录
- RFC 6937 — Proportional Rate Reduction for TCP
- RFC 9937 — Proportional Rate Reduction
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
