从一道面试题看 TCP 的吞吐极限

news2024/11/25 18:44:51

分享一个 TCP 面试题:单条 TCP 流如何打满香港到旧金山的 320Gbps 专线?(补充,写成 400Gbps 更具迷惑性,但预测大多数人都会跑偏,320Gbps 也就白给了)

这个题目是上周帮一个朋友想的,建议他别问三次握手,慢启动,快速重传,何时发 RST 了,来个情景分析吧。

如果候选人提到 TCP 序列号空间 4GB,香港到旧金山往返 200ms+,320Gbps 管道容量 8GB+,TCP 最大窗口受限,无法这个管道,至于后面说与不说,都算通过了。上来就 BBR 的,还得继续问三次握手。

下面是这个题目的解析。

先求一下 TCP 最大窗口。
在 32bit 的 unsigned int 圆环域上,两个数字顺时针间隔在一个半圆内才能无歧义比较大小(参考 Linux kernel 的 before,after 宏定义):
在这里插入图片描述
如上图的无歧义共识,TCP 窗口最大值被限制在 2^31 字节以内。

此外,根据 TCP 滑动窗口原理,sender 和 receiver 的窗口之间最大可相差一整窗:
在这里插入图片描述

因此,TCP 窗口的最终最大值为 2^31/2 = 2^30 字节。这是 TCP 窗口上限,即 1GB。200ms 链路,TCP 最多只能打满 1GB*8/0.2s = 160Gbps 的带宽。

如果允许稍微 patch TCP,如何填满 8GB 管道呢?这是个更有趣的问题。

Netflix 有个直接的方案,扩展序列号空间:64-bit Sequence Numbers for TCP

我这里重点说另一个 PAWS + Pacing 方案。

timestamp 是个天然升序标识,每 1ms 滴答一下,32bit timestamp 回绕一次要 49 天,值得使用。

320Gbps = 40GBps,大约 1ms 发出 40MB 数据,即每 100ms 发生序列号回绕。但只要控制 sender 的 pacing rate,每 1ms 送出 40MB 数据,就可将 rwnd 最大值扩至 2^31,不再受回绕限制:
在这里插入图片描述
道理很简单,1ms 粒度 pacing,相当于为 seq 增加了额外的顺序号,按 timestamp 编号每 40MB 数据,receiver 对 100 个 1ms 和 1ms 的 40MB 数据归并排序即可恢复 send 顺序:
在这里插入图片描述

注意,timestamp 指的是原始报文传输时的时间,即便发生重传,其timstamp 还是原始那个。

若发生丢包,由于 “since the sender and receiver windows can be out of phase by at most the window size【RFC1323-2.3】”,sender 和 receiver 之间最大 2^31 相差,在 2^32B 范围内,每个 seq 只出现一次,以 timestamp 做序号,自然不会有歧义。

大致算一下 2^31B 的窗口用 timestamp 做顺序号可以支撑多大的带宽。以 timestamp 的 1ms 精度,1ms 至少需要将 2^32 的两个半圆区分开,1ms 标识 2^31B 数据,即 16Tbps = 2TBps 的带宽。
在这里插入图片描述

进一步设想,若 timestamp 精度达到 us,所支撑的带宽将继续扩大,但系统开销也随之扩大,由于二者非线性关系,所以我不敢说 1000 倍。

以上是理论值计算,考虑到丢包,乱序,拥塞控制等因素,理论值几乎达不到,但它展示了一种可能性。

万变不离其中,我经常强调单调递增编码 packet,并设计新协议,但实际上 timestamp 就是一个天然编码标识,它确实编码了 “packet(每一个 segment 包含若干 byte)”,而非 Byte stream。

byte 大小固定没弹性,byte-based 滑动窗口没扩展性,带宽越大,传输字节越多,越快回绕。而 packet 不固定,它提供 1B ~ mss B 的弹性,且 mtu 可随底层传输技术发展而增加(如巨帧),显然 packet-based 滑动窗口可扩展性更佳。可见,2^32B = 4GB 的序列号空间直接参与传输和确认不适应长肥网络,不过在 byte/packet-based 滑动窗口争论正当时(参见:The design philosophy of the darpa internet protocols 第 10 节),管道既不长,更不肥,选择 byte-based 没毛病。

回到这个面试题,为什么不能上来就说 BBR,因为 cwnd limit 前,先碰到 rwnd limit,这才是硬伤,是壁垒。所以必须先解决 rwnd limit 问题,突破 rwnd 限制,至于 BBR,只是优化。

这个题目主要考察 3 个点,首先是对 TCP 协议头字段的理解,主要是 seq 和 wcale option,其次是对数字的敏感,比如东亚到加州湾区的时延,再次就是根本问题和次要问题的甄别能力,刚接触 BBR 的可能觉得 BBR 能解决一切问题,从而把根本问题疏忽了。

至于更多讨论,参见另一篇文章:流控问题两则。

现在来看可靠保序传输的本质。

要在 receiver 恢复 sender 端顺序,需顺序标识数据。将数据顺序装入 packet,然后顺序标识 packet 即可,但这个我已说过太多,现在看如何顺序标识数据本身。

TCP 序列号算一种顺序标识,但它会面临回绕歧义。TCP 将最大窗口限制在 2^30B 消除了歧义,但同时也限制了其填充长肥网络的能力。在引入 timestamp 后,可重新审视这个问题。

无论 seq space 多大,它终究被定义在环形域上(计算机算术一切数据类型都在环形域),环形域无歧义比较大小需在一个半圆内,当这个环形域不够大时,就会遇到 TCP 一样窗口限制,但若将这个环形域定义足够大,却可能占用额外报头空间,最好就是根据实际所需将环形域定义成变长(比如 QUIC)。但还有别的解法。

当我们发现时间序是一个天然顺序后,这个环形域便可分级解释,就像 MMU 分级页表一样。将顺序标识分为两层,外层是时间序,内层是环形域的半圆,设序列号空间 m 位,timestamp 精度为 n,只需要在 1 个 n 时间内能最大识别 2^(m-1)B 即可,也就是说,同一 timestamp 编码一个半圆。

m = 32,n = 1ms 就是 TCP 的情况,解释是,只要在 1ms 内发送数据不超过 2^31B 即可。2^31B 就是 2GB,对于 TCP,它可以支撑的带宽为 2TBps,与 RTT 无关。对于 receiver,执行两层归并排序,首先将时间分割为精度为 n 的 slot,根据 timestamp 将报文对应到 slot,再根据 seq 将报文在该 slot 内排序:
在这里插入图片描述
为什么 RTT 消失了?

RTT 并没消失,它回绕需要太久的时间,以至于可以将它近似为绝对单调递增量,前面算过,以 1ms 精度滴答的 timestamp 发生回绕需要 49 天,远超一个报文在互联网上最长逗留时间,当然,如果处在比地球大的多的星球,这一点需要修正。

这里有一个 packetization 过程,一个 slot 即一个 packetization 单位,内容是一个没有歧义的半圆内的 seq。

原始报文的 timestamp 时间序和 seq 字节序共同消除了保序歧义,另一面,为保证可靠传输,丢包重传还需要一个报文( whatever 原始报文 or 重传报文)实际发送的时间序列号,用来消除原始报文和重传报文的歧义,这个虽然不是流控必须的,但对拥塞控制意义重大,不得不察,但这方面我强调过太多,不再啰嗦。

现在可以和 Netflix 的方案(见上面链接)对应了,二者殊途同归,Netflix 方案直接采用了 64bit 序列号,而 PASW + Pacing 也使用 64bit 序列号,只是将它分为了 32bit 原始序列号和 32bit timestamp 两层。在我看来,PAWS + Pacing 更灵活,可以适配不同时钟精度和不同带宽。

所以,我有个建议,TCP 在同时启用 timestamp 和 wscale 时,wscale 需另作解释,将其最大值限制在 15 而不是 14,而 timestamp 也另解释为顺序号,为 2 倍的滑动窗口(即以 wscale 最大值 15 取代 RFC7323 规定的 14)消除回绕歧义。

从刚毕业参加工作面试一直到此后的 10 年多,被面试官问了无数次 TCP 三次握手,为什么三次,TimeWait,快速重传之类的问题,自己作为面试官也问了候选人无数次这般问题,我上一次被问这些是大约 5 年前,但也差不多从那时起我也不问候选人这些问题了,我想了一些更好玩的,比如 “如何用 TCP 实现不可靠传输(考察 ACK/SACK/滑动窗口)”,“如何旁路修改传输中的 TCP 数据(考察 RFC5961)?” … 正好有朋友也厌倦了上面那些老掉牙的问题,要我帮忙新出一个面试题,问题已经被问过,所以延迟一周写下本文。

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

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

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

相关文章

C#:Krypton控件使用方法详解(第十六讲) ——kryptonCheckedListBox

今天介绍的Krypton控件中的kryptonCheckedListBox。下面介绍控件的外观属性如下图所示:Cursor属性:表示鼠标移动过该控件的时候,鼠标显示的形状。属性值如下图所示:UseWaitCursor属性:表示鼠标在控件中等待时&#xff…

问ChatGPT:零基础如何学好.Net Core?

更多开源项目请查看:一个专注推荐.Net开源项目的榜单 ChatGPT横空出世,一下子让全球互联网企业都慌了,纷纷表示:马上跟进发布ChatGPT,媒体纷纷报道大有改变教培行业。 下面我们问问ChatGPT:零基础如何学好…

EasyCVR视频融合平台开放插件功能:支持EasyNTS与EasyShark抓包

EasyCVR视频融合平台基于云边端一体化架构,具有强大的数据接入、处理及分发能力,平台支持海量视频汇聚管理,能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅…

GPS/GPRS车载定位系统智能终端设计μC/OS-Ⅱ调度液晶显示汽车行驶记录仪电路

wx供重浩:创享日记 对话框发送:gps电路 免费下载完整无水印论文报告(包含主板电路图和采集板电路图) 文章目录一、绪论二、车载智能终端三、车载智能终端的硬件结构及设计四、车载智能终端的软件结构及设计五、总结和展望附录一 汽…

小i机器人登陆纳斯达克:市值4.2亿美元,与苹果打了10年专利侵权官司

‍数据智能产业创新服务媒体——聚焦数智 改变商业要问当前科技圈里最靓的仔是谁?那当然是非 ChatGPT莫属。当下谁能推出真正意义上的中国版ChatGPT,并且在这轮AI浪潮竞争白热化阶段中笑到最后,已经成为人们关注的焦点。美东时间3月9日&…

使用chatgpt写6.5分作文范文

其实使用chatgpt最大的背单词好处就是你可以看到真正的外国人的思维到底是如何的。而且,你也可以看到chatgpt这个模型,如果是编写代码的话,你如果使用中文,它编写的效果是没有英文输入的好的,为什么呢?因为…

Vector - CAPL - log回放模块函数

Replay log回放模块作为我们常见的问题分析小工具,是大部分车载圈老人的必备工具,不过自从CANoe软件11.0之后的版本变动依然无法阻挡每一个车载人使用的热情,除了我们常见的手动回放log外,我们工作中还有一部分低概率以及极低概率出现的问题,这时候我们就需要通过自动化对…

python趣味编程-2048游戏

在上一期我们用Python实现了一个盒子追逐者的游戏,这一期我们继续使用Python实现一个简单的2048游戏,让我们开始今天的旅程吧~ 在 Python 免费源代码中使用 Tkinter 的简单 2048 游戏 使用 Tkinter 的简单 2048 游戏是一个用Python编程语言编码的桌面游…

阅读笔记DeepAR: Probabilistic Forecasting with Autoregressive Recurrent Networks

zi,t∈Rz_{i,t}\in \mathbb{R}zi,t​∈R表示时间序列iii在ttt时刻的值。给一个连续时间段t∈[1,T]t\in [1, T]t∈[1,T],将其划分为context window[1,t0)[1,t_0)[1,t0​)和prediction window[t0,T][t_0,T][t0​,T]。用context window的时间序列预测prediction window…

关于异常控制流和系统级 I/O:进程

💭 写在前面:本文将学习《深入理解计算机系统》的第六章 - 关于异常控制流和系统级 I/O 的 进程部分。CSAPP 是计算机科学经典教材《Computer Systems: A Programmers Perspective》的缩写,该教材由Randal E. Bryant和David R. OHallaron 合著…

C 去除字符串中重复字母(LeetCode)

🌟前言摆烂太久,好久没有更文了,小九和大家一起看看题写写题找回手感吧,也希望这篇文章可以帮助正在寻找解题答案的朋友,你们的支持就是我最大的动力!求三连!求关注呀!🌟…

信息系统项目管理师第4版教材的变化:PMBOK第六版和第七版的叠加

昨天下午,软考官方网站突然发布了第4版考纲和教材,这让很多在准备今年上半年信息系统项目管理师考试的考生们有些紧张。那么这次教材改版主要的变化是什么,5月份的考试是否会按照新版的教材来考呢?让我们逐个章节进行分析。信息化…

Spark RDD编程基本操作

RDD是Spark的核心概念,它是一个只读的、可分区的分布式数据集,这个数据集的全部或部分可以缓存在内存中,可在多次计算间重用。Spark用Scala语言实现了RDD的API,程序员可以通过调用API实现对RDD的各种操作,从而实现各种…

数据结构刷题(二十三):47全排列II、51N皇后、37解数独

1.全排列II题目链接思路:回溯之排列问题并且有数组排序标记数组。 回溯三部曲同46. 全排列。过程图:https://programmercarl.com/0047.%E5%85%A8%E6%8E%92%E5%88%97II.html#%E6%80%9D%E8%B7%AF注意:本题的去重操作主要在树层上。就是说同一树…

2.JVM常识之 运行时数据区

1.JVM核心组成 2.JVM 运行时数据区(jdk8) 程序计数器:线程私有,当前线程所执行字节码的行号指示器 jvm栈:线程私有,Java 虚拟机栈为 JVM 执行 Java 方法服务 本地方法栈:线程私有,本…

SpringBoot接口 - 如何统一异常处理

SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?为什么要优雅的处理异常如果我们不统一的处理异常,经常会在controller层有大量的异常…

【Java】初识Java

Java和C语言有许多类似之处,这里就只挑不一样的点来说,所以会比较杂乱哈~ 目录 1.数据类型 2.输入与输出 2.1三种输出 2.2输入 2.3循环输入输出 //猜数字小游戏 //打印乘法口诀表 3.方法 //交换两个数(数组的应用) //模…

栈的应用-算数

本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。如上图所示,计算器由两个堆栈组成,一个堆栈 S1​ 存放数字,另一个堆栈 S2​ 存放运算符。计算器的最下方有一个等号键,每次按下这个键,计算器就…

Form Generator扩展 文本 组件

一、form-generator是什么?✨ ⭐️ 🌟 form-generator的作者是这样介绍的:Element UI表单设计及代码生成器,可将生成的代码直接运行在基于Element的vue项目中;也可导出JSON表单,使用配套的解析器将JSON解析成真实的表单。 但目前它提供的组件并不能满足我们在项目中的…

kubeadm探秘

为什么kubeadm可以用于生产?第一是kubeadm已经被官方收编,可以在官网文档中找到它的身影。另外一个是kubeadm是用golang调用k8s的命令去执行创建k8s集群的。查看一下kubeadm的代码即可知道。本文来源于csdn作者 sunican挨个打开目录查看文件可知&#xf…