TCP 的演化史-sack 与 reordering metric

news2024/9/24 19:24:11

就着 TCP 本身说事,而不是高谈阔论关于它是如何不合时宜,然后摆出一个更务虚的更新。
从一个 case 开始。

按照现在 Linux TCP(遵守 RFC) 实现,以下是一个将会导致 reordering 更新的 sack 序列:
在这里插入图片描述
考虑一种情况,这两个携带 sack block 的 ack 本身乱序,而不是被 sack 确认的 data 乱序, 以上的 reordering 更新就是误判,而 reordering 是单调更新的,递增的 reordering 将影响 mark lost 的数量,进而影响 retransmit 效率。

reordering 误判对 rate-based cc 影响非常大,因为 rate-based cc 要求即使在 loss recovey 状态也要源源不断地发送数据以支撑测量,而 reordering 可能会造成 sender 等待,减少 retransmit。

上述误判情况由下图所示(sack block 上的数字标识 sack block 生成的顺序):
在这里插入图片描述
reordering 误判的依据在于,考虑 sender 发送 1~10,其中 1,3,5,7,9 丢失,receiver 依次收到 2,4,6,8,10. 假设 receiver 由于被其它 option 挤占空间,只能支持 max = 3 个 sack block 段,它 “一般”(下面解释为何不是一定) 会按照以下序列生成 sack block:

收到 2,发送 ack 1,携带 sack 2;
收到 4,发送 ack 1,携带 sack 4-2;
收到 6,发送 ack 1,携带 sack 6-4-2;
收到 8,发送 ack 1,携带 sack 8-6-4;
收到 10,发送 ack 1,携带 sack 10-8-6;

如果收到 8 或者 10 后发送的 ack 比收到 2 后发送的 ack 先到达 sender,就会出现第一幅图所示的场景。

为什么这么明显问题,Linux TCP 没处理呢?

因为 RFC 并未规定 sack block 的顺序一定是 LRR(Least Recently Received,类似 LRU,Least Recently Used) 链表的形式。在 RFC2018 第 4 小节 Generating Sack Options: Data Receiver Behavior 中有以下描述:

The SACK option SHOULD be filled out by repeating the most recently reported SACK blocks (based on first SACK blocks in previous SACK options) that are not subsets of a SACK block already included in the SACK option being constructed. This assures that in normal operation, any segment remaining part of a non-contiguous block of data held by the data receiver is reported in at least three successive SACK options, even for large-window TCP implementations [RFC1323]). After the first SACK block, the following SACK blocks in the SACK option may be listed in arbitrary order.

既然不是 MUST,sender 就不能对 sack block 假设任何时间序。对 receiver 而言,由于无法区分原始 seg 和重传 seg,如果是重传 seg,这个 LRR 时间序就不准了。

如果(仅如果) RFC 要求 sack block 保持 LRR 强序,那么 sender 收到的 sack block 就一定是这个强序,便不再受 ack 反向路径乱序影响。

我想的是,虽然 RFC 并未要求 MUST,但事实上应该非常大比例的 receiver 实现了 LRR 强序,这样做最简单。不然因为 RFC 的 maybe 摆布一个 arbitrary order 动机呢,图什么呢?

因此,管它 MUST or SHOULD/MAYBE,sender 假设 sack block 是 LRR 强序,如果真的大部分 receiver 命中了我的猜测,reordering 误判将会减少很多。当然,这个假设需要现网数据支撑。

如果真将 sack block 的 LRR 序从 SHOULD/MAYBE 改为 MUST,根据收到 sack option 中 sack block 的顺序,可更加精确处理 reordering 更新。后文基于该假设继续。

同样上面的 case,加入强序后,就更加精确且清晰:
在这里插入图片描述
显然,sender 可根据不同的 sack block 序列,判断出不同的 reordering metric,进而将 reordering 更新成不同值。

LRR 强序前,不能确保 sack block 顺序一定有确切含义,对 sender 就更不能确定其意义,sender 只简单将收到的 sack block 进行升序排序,用这个序列去 mask 所有 rtxq(retransmit queue),求两个区间链表的交集:区间列表的交集

LRR 强序后,sender 实现更简单了。按照 sack block 在 sack option 的天然顺序匹配发送顺序即可精确判断 reordering。dsack 亦可统一处理。

引入 rack 之后事情变得更简单,sender 可用 sack block 的 LRR 时间序与 rack 时间序做比对来精确判断 reordering:
在这里插入图片描述

照 sack block 顺序比对 rack 环,倒排即乱序,reordering 单调递增,rto 复位(rto 意味着路由可能发生了重收敛)。

由于重传歧义硬伤,sender 仍需稍微的启发判断,dsack 一个 seg 后,相信自然序(原始 seg 带来第 1 个 sack,重传 seg 带来第 2 个 sack),重传后的 sack 相信重传而非乱序,当然,也可以配置信任度量。

无论如何,sack block LRR 强序对 sender 带来更加确定的信息,该信息对 sender 的 cc 决策有益。并且实现更简单了,为什么不呢?

回到 RFC2018,看看初衷。

The SACK option SHOULD be filled out by repeating the most recently reported SACK blocks that are not subsets of a SACK block already included in the SACK option being constructed.

sack block 被安排成 LRR 弱序(may be listed in arbitrary order),原因二,首先 sack option 长度有限,要为最新的接收事件的数据生成 sack block,其次 sack option 长度又不是那么有限,安排冗余信息可以抵御 ack/sack 丢失,提高鲁棒性:

  • Sending a selective acknowledgment for the most recently received data reduces the need for long SACK options.
  • The redundant blocks in the SACK option packet increase the robustness of SACK delivery in the presence of lost ACKs.

按照现代的观点,考虑到 sack block 以及反向 ack 本身的乱序对 reordering 的影响,sack block 数量越多越容忍反向路径 ack 乱序,确实如此,4 个 block 够了(如果被其它 option 挤占可能不足 4 个),况且就算最多只有 4 个 block,只要能零散接收,sack block 就能像滑动窗口(最大 4 段)一样一直滑下去,覆盖所有 ofo(out of order) seg,由于每个 seg 最多可出现4次,即可提供冗余。sack 的该机制是好的,非常好的。

演化过程是见招拆招的过程,远不是全局视角下的设计过程。遇到问题,痛点是解决这个问题,看看初衷问题和 RFC2018 的来源:
在这里插入图片描述
sack 解决了问题,sack 就是好的。RFC2018 引入时的 loss recovey 算法依然如旧:
在这里插入图片描述
彼时 sack 仅仅可区分对待了 sacked seg,避免不必要的重传。新式的 loss recovey 算法要等后续发布。

标识 sack 相关 loss recovey 算法的 RFC6675 以及前身 RFC3517 均未引入 reordring 的影响,直到 RFC4737 才引入 reordering 度量:Packet Reordering Metrics,这是 2006 年的事,sack 被引入 TCP 时尚无 reordering issue,更谈不上为它提供精准信息。但无论如何,现在 sack 和 reordering 以及 rack 可以结合,并且高尚。
说下本文的缘起。

我用 packetdrill 做 sack 测试,构造了本文图 1 的 ack 乱序 case,触发了 reordering 更新后 mark lost 便不及时了(按照 scoreboard update 算法,保留 reordering 个 sacked seg),影响了 retransmit 效率。

So?若做 TCP 双边,我觉得一定要确保 receiver 生成 LRR 强序 sack block,多些确切信息总不会错,TCP 就是不确定信息太多才复杂。若做 TCP 单边,我觉得要假设 receiver 生成 LRR 强序 sack block,就算它不是,损失也不多,况且大概率它是,不然对它有什么好处呢?

对了,reordering 的更新不仅和 sack 有关,和 cumulative ack 也有关系。此外,关于反向路径对正向 rate-based 发送的影响,我还有另外一个建议:TCP 时间戳的妙用 以及 TCP 拥塞识别。

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

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

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

相关文章

【Spring】谈谈你对IOC和AOP理解(2023最新)

目录一.IOC(Inversion of Control)1.IOC是什么?2.IOC的实现原理二.AOP(Aspect Oriented Programming)1.AOP是什么?2.AOP的实现原理3.说一下AOP都有哪些基本理念?或者是AOP的术语4.Advice(通知)的类型有哪些5.AOP的应用场景6.使用AOP实例(日志…

jvisualvm远程监控Java程序

启用远程监控: 方式一:启动参数进行配置 启动远程应用需指定jmx相关配置 java -jar -Djava.rmi.server.hostname远程服务ip -Dcom.sun.management.jmxremote.port18888 -Dcom.sun.management.jmxremotetrue -Dcom.sun.management.jmxremote.sslfa…

运动耳机推荐、最值得入手的运动耳机清单共享

现在市面上各式各样的运动蓝牙耳机着实让人挑花了眼,怎样才能从纷繁复杂的市场中挑选出专业性、安全性、舒适性等各个方面都做地可圈可点的运动蓝牙耳机可真不是一件易事啊,甚至连不少老朋友都会踩坑,为了能让大家挑到真正的运动蓝牙耳机,为此…

Dev C++ 调试功能详细总结

原文链接: Dev C 调试功能详细总结https://mp.weixin.qq.com/s/H9VwLNcJ0tY3j3265R0_7Q 大家好,我是CodeAllen(康哥),今天是2023年2月25日,继上一篇介绍了我在Windows端经常用来验证代码的工具Dev C的基本…

pytest测试框架——pytest.ini用法

这里写目录标题一、pytest用法总结二、pytest.ini是什么三、改变运行规则pytest.inicheck_demo.py执行测试用例四、添加默认参数五、指定执行目录六、日志配置七、pytest插件分类八、pytest常用插件九、改变测试用例的执行顺序十、pytest并行与分布式执行十一、pytest内置插件h…

【经典蓝牙】蓝牙AVRCP协议分析

协议简介 蓝牙AVRCP协议是蓝牙设备之间音视频的控制协议。定义了音频/视频的控制、浏览、查询、通知等一系列的命令集。常用来蓝牙耳机对手机的音乐进行控制,以及获取手机的音乐信息等场景。AVRCP协议有两个角色,分别是controller(CT&#x…

MFC 使用GridCtrl表格控件

1、以前使用GridCtrl大多作为静态库,但是程序使用的时候体积会很大,有网友询问能不能封装为动态库使用,刚好最近抽空仔细看了一下,封装出来。 2、具体封装过程不再赘述,具体测试如下所示: CGridCtrl m_Gri…

JavaScript Window

文章目录JavaScript Window浏览器对象模型 (BOM)Window 对象Window 尺寸其他 Window 方法JavaScript Window 浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话"。 浏览器对象模型 (BOM) 浏览器对象模型(Browser Object Model (BOM))…

LeetCode100_100. 相同的树

LeetCode100_100. 相同的树 一、描述 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3], q […

【数据结构】手撕红黑树

目录 一、红黑树简介 1、红黑树的简介 2、红黑树的性质 二、红黑树的插入(看叔叔的颜色就行) 1、为什么新插入的节点必须给红色? 2、插入红色节点后,判定红黑树性质是否被破坏 2.1情况一:uncle存在且为红 2.2情…

微信商城小程序怎么做_分享实体店做微信商城小程序制作步骤

各行各业都在用微商城小程序开店,不管是餐饮店还是便利店,还是五金店。都是可以利用微信小程序开一个线上店铺。实现线上跟线下店铺更加全面的结合。维护好自己的老客户。让您的客户给您拉新,带来新客户。小程序经过这几年的快速发展和不断升…

【量化回测必看!】Backtrader保姆级教学+免费行情源 框架介绍

前言 想开始量化学习不知道如何入手?市面上的学习资料太多不知道该怎么看? 博主将从零基础讲解回测框架,一步步完成量化数据源的搭建,让你10天内成为量化高手 博主同时将视频课程内容在B站更新,可以关注“量化NPC”获…

学习 Python 之 Pygame 开发魂斗罗(五)

学习 Python 之 Pygame 开发魂斗罗(五)继续编写魂斗罗1. 加载地图2. 修改角色尺寸和地面高度继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗(四)中,我们完成了角色的移动和跳跃还有射击,由…

Redis源码---整体架构

目录 前言 Redis目录结构 前言 deps目录 src 目录 tests 目录 utils 目录 重要的配置文件 Redis 功能模块与源码对应 前言 服务器实例 数据库数据类型与操作 高可靠性和高可扩展性 辅助功能 前言 以先面后点的方法推进无特殊说明,都是基于 Redis 5.0.…

AI Codec,视频模板技术,高效视频处理,RTC+AI,感知编码,CV-CUDA,窄带高清AI...

AI Codec,NPU硬件加速Topic《基于AI和NPU的Codec变革》孔德辉 中兴微电子 多媒体技术总监伴随通信容量(包括5G以及千兆有线网络)的发展,高带宽为更多用户接入超高清视频提供了可能。但是随着用户数量的增加,高质量的压…

排序基础之选择排序法

目录 前言 一、什么是选择排序 二、实现选择排序 三、使用泛型扩展 四、使用自定义类型测试 前言 今天天气不错,这么好的天气不干点啥实在是有点可惜了,于是乎,拿出键盘撸一把! 来,今天来学习一下排序算法中的选…

港科夜闻|全国政协副主席梁振英先生率香港媒体高管团到访香港科大(广州)...

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、全国政协副主席梁振英先生率香港媒体高管团到访香港科大(广州)。2月21日下午,在全国政协副主席、广州南沙粤港合作咨询委员会顾问梁振英先生的带领下,香港20余家媒体的高管及知名媒体人士到访香港科大…

电脑技巧:分享8个Win11系统必备小技巧

目录 1、让任务栏显示“右键菜单” 2、任务栏置顶 3、还原经典右键菜单 4、Win11版任务管理器 5、新版AltTab 6、开始菜单不再卡 7、为Edge浏览器添加云母效果 8、自动切换日/夜模式 Win11在很多地方都做了调整,但由于涉及到诸多旧有习惯,再加上…

SRE中 的SLO,SLI等知识 归纳

SLA Service Level Agreement 服务质量/水平协议SLO Service Level Objective 服务质量/水平目标SLI Services Level Indicator 服务质量/水平指标下面用人、事、物的逻辑进行阐释。人和事用从上到下,从左到右的顺序。客户 - 每 1 个客户在使用产品服务时&…

gin 框架初始教程

一 、gin 入门1. 安装gin :下载并安装 gin包:$ go get -u github.com/gin-gonic/gin2. 将 gin 引入到代码中:import "github.com/gin-gonic/gin"3.初始化项目go mod init gin4.完整代码package mainimport "github.com/gin-go…