TCP RTO 与丢包检测

TCP RTO 是它 40 多年前唯一丢包检测策略,也是当前最后的丢包检测兜底策略,它几乎从没变过。

有个咨询挺有趣,以其案例为背景写篇随笔。大致意思是,嫌 TCP RTO 太大,游戏场景丢包卡顿怎么办?我提供了几行代码,果见成效。

不得不承认一个事实,如今绝大多数 TCP RTO 均在 200ms 左右,因为 minrto 规定为 200ms,而大多数 TCP 连接均为就近而稳定的 CDN 连接,排除少量贫困偏远地区(他们也不在乎网络质量~),裸测 RTT 中位数不超过 50ms,按照 VJ RTO 公式 srtt + 4·rttvar 计算,远小于 200ms。

依旧将 minrto 设置为 200ms,此中原因在于对 Delayed ACK 的适应,而 Delayed ACK 在 RFC1122 规定,其最大 timeout 为 500ms,但一般而言,Linux 系统设置为 40ms,Windows 系统为 200ms。因此 minrto = 200ms 足以覆盖大多数场景而不至于 RTO 过于激进产生的不必要重传加重网络拥塞,参见 TCP MIN_RTO 辩证考。

大家都以为 Linux 内核有个参数可以配置 minrto,就像以为有个参数可以配置 TCP timewait 时间一样,然而直到 6.x 内核,minrto 的 sysctl 配置才被支持,但早在 2014 年前后,各大 CDN 厂商就纷纷私下里支持了该配置,每当业务咨询连接超时问题时,该配置可谓神器,可想而知,如今 Linux 6.x 对其正式支持,也是这些厂商所为,提个派池而已。

我没有以 “配置一个更小的 minrto” 回应该咨询,因为这种配置往往会因为众口难调的原因而弄巧成拙:

  • 使用 sysctl 配置全局 minrto 无法适应所有尺度的 TCP 连接;
  • 使用 iproute2 配置单路由 minrto 同上,只是范围缩小些;
  • 使用 sockopt,ebpf 配置单连接 minrto 无法适应连接内的尺度变化;

我提供的是根据连接当前性质实时计算 RTO 的细粒度方案,专门针对 thin TCP stream,也就是拥塞无害的细长流,它有一份古老的文档:Thin-streams and TCP,早在 2.6 时代就部署。修改 tcp_rearm_rto 和 tcp_retransmit_timer:

  • 两个函数为 thin TCP stream 提供与 TLP 一致的超时时间以替换 RTO;
  • 重新定义 thin TCP stream;

可以简单理解上述修改,即放宽了 RFC8985-RACK-TLP “1.2. Motivation” 的约束,加上 “when the entire flight is lost and the stream is thin” 也能享受 TLP。

传统意义上,packet_out < 4 的连接被认为 thin TCP stream,因为 dupack/sacked 无法超过 3 而触发 fast retransmit,3 同样是传统意义上的阈值。我将其修改:

  • inflight < tp->reordering + 1 即为 thin TCP stream;

配合现有 TCP 重传策略,这就是一整套丢包检测和重传算法:

  • RFC6675 提供传统快速重传方案;
  • RACK/TLP 提供 tail drop 重传,兜底 RFC6675;
  • RFC5682 提供传统 RTO 兜底 RACK;
  • 我的算法为 thin TCP stream 优化 RTO;

当然,RTO 本身的计算方式无需改变,若不是有 Delayed ACK 捣乱,它还是要比 TLP PTO = 2·SRTT(若 inflight == 1,还要和 max_ack_delay 胶着) 更加优秀,参见 VJ 对 SRTT/RTO 公式参数的推导。

后面是关于丢包检测和重传的形而上话。

TLP 的细节我今年过年期间专门说过,它覆盖了 AAAL,AALL,ALLL,LLLL,>=5 L 等所有 packet_out > 1 的丢包场景,与 RACK 天然搭配。

我一向觉得 RACK 具有里程碑意义,因为它的引入,TCP 丢包检测变得更简单直观。RACK 取消了 FACK,ER(Early Retrans),thin Fast Retrans,NCR 等一众票凌乱离散的丢包检测和重传策略,全部统一到了自己的时间序中。代码简化了不少,统一于 net/ipv4/tcp_recovery.c。

可能正因为 RACK 有如此威力,RTO 变得极少被触发,反而被遗忘了,没人单独优化它。

但一旦涉及 RTO,就必须重新审视关于 TLP 和 RACK 的整个背景和适用前提。

首先,Fast Retrans 和 TLP 均假设有足够的 seg 触发重传,RACK 取消掉的 thin Fast Retrans 亦依赖 ACK-selfclock,如果丢失 ACK-selfclock,还是要掉入 RTO。tail drop 可用 TLP 优化,但 pingpong 模式的应用遭遇 drop 则不能,在 RACK: a time-based fast loss detection algorithm for TCP 有个场景:

Structured request-response traffic turns more losses into tail drops. In such cases, TCP is application-limited, so it cannot send new data to probe losses and has to rely on retransmission timeouts (RTOs).

典型的很 thin 的 stream,很容易全部丢失,如此一来 ACK-selfclock 丢失,RACK,TLP 全都派不上用场。

其次,自定义 TCP 相关参数时代以来,网络环境已经发生重大变化,但这些参数的缺省值却很少发生改变,而这些缺省值往往影响 TCP 的性能。其中以 RTO 为严重,因为 RTO 由本地 clock 触发,它不像 ACK-selfclock 可在闭环上玩很多花活,行为和参数相互依赖,只需改变算法,不太依赖参数。

是时候重新测量新的统计值了,但如今庞大的互联网已经变得难以测量,虽然很难给出一个更合适的 minrto,但可以确定的是,哪些场景下可以不受 minrto 约束,这是我这个优化的初衷。

回到原点,minrto 保守化的原因在于避免不必要的重传而加重拥塞,但它与丢包不能及时恢复相比,要两权相害取其轻,对于 block 传输,自然要优先考虑避免拥塞问题,但对于 thin stream,比如游戏,远程登录等非 capacity-seeking 传输,其 inflight 不随带宽而增加,不足以对现代网络的负载产生可观测影响,因此它们并不是拥塞控制的目标。这是我这个优化的背景。

基于 “对 thin stream 要激进探测丢包并重传” 的观点,拥塞无害的 thin stream 不必矜持保守地等待超时,我给出该优化。在此之前,我曾经以三三两两倒序发送,尾部跟随乱序包等花活儿被经理表扬。

此外,有一个关于 TLP && inflight == 1 的讨论,标准的做法是 “PTO = 2 srtt + delayed_ack 容忍期”,但本着 “thin stream 拥塞无害” 的观点,代之以 “在唯一的报文后紧紧尾随一个曾经发送过乱序字节(或整个报文)以取消 receiver 的 delayed ack” 则更高尚,以无所谓的空间代价换宝贵的时间收益。

最后,说说 RFC4653-Non-Congestion Robustness (NCR) for TCP,从两个视角看看对它的态度:

  • 从 RFC 的视角,NCR 倾向于保守重传,以有机会区分乱序和丢包,充满了对 Robustness 的憧憬及展望;
  • 从 Linux Kernel 社区的视角,NCR 提供当 reordering 太高不能及时诱发 Fast Retrans 的接力,倾向激进;

换句话说,RFC 嫌现有 Fast Retans 太激进,容易错把乱序当丢包,以至于不必要降速,因此提出了 NCR 尽量不进入 Fast Retrans,而 Linux Kernel 社区则嫌现有 reordering-based Fast Retrans 太墨迹不能及时重传,以至 RTO,因此实现了 NCR 尽量进入 Fast Retrans。它们说的同一个东西,但目标不同。

显然,以 Linux Kernel 社区的视角,一旦 RACK 被引入,很多旨在优化 “不能及时重传” 的策略都没了继续存在的必要,NCR 自然下课了:tcp: remove RFC4653 NCR。

再看 RFC 的视角,下面的引述道出了我一直想表达的意思:

The requirement imposed by TCP for almost in-order packet delivery places a constraint on the design of future technology. Novel routing algorithms, network components, link-layer retransmission mechanisms, and applications could all be looked at with a fresh perspective if TCP were to be more robust to segment reordering.

如果 TCP 再健壮一点,能识别乱序,网络设备便无需对它做按序假设了,没有保序约束,并行处理便大行其道,这可以极大提高交换吞吐。

为了尽力实现这种健壮性,或者至少提供一个实验性的探讨,NCR 在确切进入 Fast Retransmit 之前给算法一定的时间来从重复应答中甄别出乱序。算法很简单,cwnd 个 seg 离开网络后仍然没有得到应答,就开始进入 Fast Retrans,而不再是 “收到 3 个重复应答”(早非如此了)。

如 RFC 正文,通过使 TCP 对非拥塞事件更具 Robustness,TCP-NCR 可能为未来互联网组件的设计开辟空间,其中就包括多路径传输。

NCR 提供两种策略,它们可以归为一类,即在进入 Fast Retrans 之前,以多大的兑换比进行 seg 守恒兑换,假设该比值是 p,积累 S 个 SACKed 段进入 Fast Retrans,简单推导一下实现:

S≥α⋅(W+p⋅W)\text{S}\geq \alpha\cdot(\text{W}+p\cdot\text{W})Sα(W+pW)

解得 α=1p+1\alpha=\dfrac{1}{p+1}α=p+11。因此,如 RFC4653 所述的建议,对于 Careful Limited Transmit,兑换比为 1:2,则 α = 2/3,而对于 Aggressive Limited Transmit,兑换比为 1:1,则 α = 1/2。除此之外,你可以给定任意兑换比,获得任意程度的 “关于 dupack 原因的最佳决策和响应性之间进行权衡”,当然,我觉得这个跟 PRR 有些许重合,只不过 PRR 是决定降速之后的策略,而 NCR 是降速之前的坚持窗口。

浙江温州皮鞋湿,下雨进水不会胖。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91458.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装php和配置环境变量

为了简单方便&#xff0c;先下载vscode然后下载对应的php安装包&#xff0c;然后配置环境变量&#xff0c;然后点击运行即可下载对应版本的php&#xff0c;这个版本凑合用然后下载完之后解压配置环境变量搜索环境变量将路径添加到环境变量中然后打开vscode添加变量具体看实际路…

Rabbit MQ的消息模式-Java原生代码

一.简单模式1.1.核心逻辑生产者 → 队列 → 单个消费者&#xff08;1:1 直连&#xff09;&#xff0c;消息被消费后自动从队列删除。1.2.关键特性无交换器&#xff08;其实使用的是默认交换机不是显示指定&#xff09;&#xff0c;直接指定队列 消息默认自动确认&#xff08;au…

【lucene】使用docvalues的案例

下面给出一段 可直接跑通 的 Lucene 8.5.0 示例代码&#xff0c;演示如何1. 建索引时为两个字段启用 DocValues&#xff08;一个 NumericDocValues&#xff0c;一个 SortedDocValues&#xff09;&#xff1b; 2. 用 IndexSearcher 按 DocValues 排序&#xff1b; 3. 用 Facet…

IntelliJ IDEA 配置 Maven 阿里云镜像加速源全流程

1. 为什么要加国内镜像源&#xff1f;国内网络访问 Maven 中央仓库经常超时、依赖下载极慢或失败。配置阿里云等国内镜像后&#xff0c;Java 项目依赖下载飞快&#xff0c;极大提升开发效率&#xff0c;是中国开发者必做优化&#xff01;2. 添加阿里云镜像源的步骤&#xff08;…

【worklist】worklist的hl7、dicom是什么关系

HL7和DICOM在Worklist系统中是互补的关系&#xff0c;它们各自承担不同的角色&#xff0c;但协同工作以实现完整的医疗信息系统集成。HL7与DICOM Worklist的关系1. 功能分工DICOM Worklist (Modality Worklist - MWL)主要用于影像设备获取患者和检查信息基于DICOM协议&#xff…

位运算-面试题01.01.判定字符是否唯一-力扣(LeetCode)

一、题目解析1、s[i]仅包含小写字母2、字符串的长度为[0&#xff0c;100]二、算法原理解法1&#xff1a;哈希表用哈希表记录s[i]的字符&#xff0c;如果有重复的&#xff0c;则返回false优化1&#xff1a;由于s[i]中只有小写字母&#xff0c;所以可以创建一个int hash[26]的数组…

wsl /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.28‘ not found

遇到的问题并没有解决&#xff0c;这个 glibc-2.28 应该是安装好了 Ubuntu18 问题描述&#xff1a;Ubuntu18 WSL 无法启动 VS Code &#xff0c;因为node版本问题 rootUbuntu18:~# code . /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.28 not found (required by /root…

Windows系统ffmpeg.dll丢失怎么办?从错误分析到永久修复的完整流程

您是否遇到过这样的情况&#xff1a;打开心爱的视频编辑软件时&#xff0c;系统突然提示无法启动此程序&#xff0c;因为计算机中丢失ffmpeg.dll&#xff1f;别担心&#xff0c;这个问题比您想象的要常见得多。作为专业的技术支持团队&#xff0c;我们已经帮助数千用户解决了类…

LaTeX 复杂图形绘制教程:从基础到进阶

系列文章目录 第一章&#xff1a;深入了解 LaTeX&#xff1a;科技文档排版的利器 第二章&#xff1a;LaTeX 下载安装保姆级教程 第三章&#xff1a;LaTeX 创建工程并生成完整文档指南 第四章&#xff1a;LaTeX 表格制作全面指南 文章目录系列文章目录前言一、​LaTeX 绘图工具…

用 Go Typed Client 快速上手 Elasticsearch —— 从建索引到聚合的完整实战

1. 准备工作 go get github.com/elastic/go-elasticsearch/v9小贴士 如果你的集群启用了安全特性&#xff0c;需要在 elasticsearch.Config 中配置 Username/Password 或 APIKey。Typed Client 通过 NewTypedClient 创建&#xff0c;内部复用 *http.Client&#xff0c;建议全局…

《义龙棒球科普》棒球是韩国的国球吗·棒球1号位

⚾ Why Baseball is Koreas NATIONAL SPORT? | KBO热血全解析 ⚾⚾ 1. 历史根源 & 情感纽带 Historical Roots & Emotional Bond美军引入 (1945后): 战后美军将棒球带入韩国&#xff0c;迅速扎根&#xff01;✨1982 KBO成立: 亚洲第二个职业棒球联盟诞生&#xff01;奥…

三坐标测量机路径规划与补偿技术:如何用算法看见微米级误差?

三坐标测量的微米级精度背后&#xff0c;是精密的路径规划算法与实时补偿技术在保驾护航。三坐标测量机的智能避撞算法保障了测量的安全与高效&#xff1b;温度补偿技术消除了环境的无形干扰&#xff1b;点云智能处理则让海量数据蜕变为精准的工程决策依据。 “智能避让路径”&…

Docker设置容器时间

一、前言前言&#xff1a;容器搭建好之后&#xff0c;容器的默认时区于本地时区不一致&#xff0c;这将导致日志文件中保存的时间为错误时间。二、操作1、进入docker 容器docker exec -it <容器名称> bash2、选择时区tzselect3、配置时区根据跳出来的配置选择Asia -> …

德国威乐集团亚太中东非洲PMO负责人和继明受邀为PMO大会主持人

全国PMO专业人士年度盛会德国威乐集团亚太中东非洲PMO负责人 和继明先生 受邀为“PMO评论”主办的2025第十四届中国PMO大会主持人&#xff0c;敬请关注&#xff01;嘉宾介绍&#xff1a;和继明先生&#xff0c;德国威乐集团亚太中东非洲PMO负责人&#xff0c;项目管理硕士MPM&a…

idea 集成飞算Java AI 教程

idea 集成飞算Java AI 教程一、介绍二、下载安装 飞算Java AI 插件方式一&#xff1a;从idea插件市场安装方式二&#xff1a;下载离线安装包三、飞算Java AI插件使用一、介绍 ​ 随着人工智能技术的发展&#xff0c;AI 编程助手逐渐成为提升开发效率的强大工具。上一篇教程是i…

2025.8.1

代码练习 //用指针访问对象成员 #include<iostream> #include<string> using namespace std; class Champion { public:Champion(int id, string nm, int hp, int mn, int dmg) {ID id;name nm;HP hp;mana mn;damage dmg;}void attack(Champion& chmp) {c…

一种新的分布式ID生成方案--ULID

一种新的分布式ID生成方案 ULID: 一种新的分布式ID生成方案 ULID (Universally Unique Lexicographically Sortable Identifier) 是一种较新的分布式ID生成方案&#xff0c;旨在解决传统UUID和雪花算法(Snowflake)的一些局限性。ULID的主要特点 可排序性&#xff1a;ULID按生成…

服务器中涉及节流(Throttle)的硬件组件及其应用注意事项

服务器中涉及节流&#xff08;Throttle&#xff09;的硬件组件及其应用注意事项 在服务器硬件中&#xff0c;“节流”&#xff08;throttling&#xff09;是一种保护机制&#xff0c;当组件温度过高、功耗过大或超出安全阈值时&#xff0c;系统会自动降低性能&#xff08;如时钟…

GitPython07-源码解读

GitPython07-源码解读1 1-核心知识 1&#xff09;从核心代码的第一行作为突破口2&#xff09;从Repo.init方法入手做追踪3&#xff09;subprocess到底做了什么&#xff1f;gitPython是不是执行的脚本&#xff0c;最终还是通过subprocess做到的4&#xff09;代码中貌似并没有实…

Java继承机制详解:从原理到实战应用

一、继承的本质&#xff1a;消除冗余&#xff0c;构建逻辑关系想象一个公司管理系统&#xff1a;普通销售员工&#xff08;CommissionEmployee&#xff09;和带底薪销售员工&#xff08;BasePlusCommissionEmployee&#xff09;共享大部分属性&#xff08;姓名、工号、销售额、…