当前位置: 首页 > news >正文

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

分享一个 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)?” … 正好有朋友也厌倦了上面那些老掉牙的问题,要我帮忙新出一个面试题,问题已经被问过,所以延迟一周写下本文。

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

相关文章:

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

分享一个 TCP 面试题:单条 TCP 流如何打满香港到旧金山的 320Gbps 专线?(补充,写成 400Gbps 更具迷惑性,但预测大多数人都会跑偏,320Gbps 也就白给了) 这个题目是上周帮一个朋友想的,建议他别问三次握手&a…...

rsync 的用法

rsync 介绍下 用法 rsync是一个常用的数据同步工具,它能够在本地和远程系统之间同步文件和目录。以下是rsync的基本用法: 同步本地文件夹: bash Copy code rsync -av /path/to/source /path/to/destination其中,-a表示归档模式&…...

【LeetCode每日一题:[面试题 17.05] 字母与数字-前缀和+Hash表】

题目描述 给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。 返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。 示例 1: 输入…...

华为OD机试题 - 简易压缩算法(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:简易压缩算法题目输入输出示例一输入输出说明示例二输入输出说明…...

Kubenates中的日志收集方案ELK(下)

1、rpm安装Logstash wget https://artifacts.elastic.co/downloads/logstash/logstash-6.8.7.rpm yum install -y logstash-6.8.7.rpm2、创建syslog配置 input {beats{port> 5044 } }output {elasticsearch {hosts > ["http://localhost:9200"]index …...

LeetCode - 42 接雨水

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 42. 接雨水 - 力扣(LeetCode) 题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例1 输入&…...

python --生成时间序列,作为横轴的标签。时间跨越2008-2022年,生成每年的6-10月的第一天作为时间序列

python 生成制定的时间序列作为绘图时x轴的标签 问题需求 在绘图时,需要对于x轴的标签进行专门的设置,整体时间跨越2008年-2022年,将每年的6-10月的第一天生成一条时间序列,绘制成图。 解决思路 对于时间序列的生成&#xff0…...

【Unity VR开发】结合VRTK4.0:创建一个按钮(Togglr Button)

语录: 有人感激过你的善良吗,貌似他们只会得寸进尺。 前言: Toggle按钮是提供简单空间 UI 选项的另一种方式,在该选项中,按钮将保持其状态,直到再次单击它。这允许按钮处于激活状态或停用状态的情况&#…...

lottie-miniprogram在taro+vue的小程序中怎么使用

把一个json的动图展示在页面上。使用的是插件lottie-miniprogramhttps://blog.csdn.net/qq_33769914/article/details/128705922之前介绍过。但是发现使用在taro使用的时候他会报错。那可能是因为我们 wx.createSelectorQuery().select(#canvas).node(res > {console.log(re…...

C++回顾(二十二)—— stack容器 与 queue容器

22.1 stack容器 &#xff08;1&#xff09; stack容器简介 stack是堆栈容器&#xff0c;是一种“先进后出”的容器。stack是简单地装饰deque容器而成为另外的一种容器。添加头文件&#xff1a;#include <stack> &#xff08;2&#xff09;stack对象的默认构造 stack…...

逻辑优化基础-disjoint support decomposition

先遣兵 在了解 disjoint support decomposition 之前&#xff0c;先学习两个基本的概念。 disjoint 数学含义上的两个集合交集&#xff0c;所谓非相交&#xff0c;即交集为空集。 A∩BC⊘A \cap B C \oslash A∩BC⊘ support 逻辑综合中的 supportsupportsupport 概念是…...

保姆级使用PyTorch训练与评估自己的DaViT网络教程

文章目录前言0. 环境搭建&快速开始1. 数据集制作1.1 标签文件制作1.2 数据集划分1.3 数据集信息文件制作2. 修改参数文件3. 训练4. 评估5. 其他教程前言 项目地址&#xff1a;https://github.com/Fafa-DL/Awesome-Backbones 操作教程&#xff1a;https://www.bilibili.co…...

Java8新特性:Stream流处理使用总结

一. 概述 Stream流是Java8推出的、批量处理数据集合的新特性&#xff0c;在java.util.stream包下。结合着Java8同期推出的另一项新技术&#xff1a;行为参数化&#xff08;包括函数式接口、Lambda表达式、方法引用等&#xff09;&#xff0c;Java语言吸收了函数式编程的语法特…...

Java基准测试工具JMH高级使用

去年&#xff0c;我们写过一篇关于JMH的入门使用的文章&#xff1a;Java基准测试工具JMH使用&#xff0c;今天我们再来聊一下关于JMH的高阶使用。主要我们会围绕着以下几点来讲&#xff1a; 对称并发测试非对称并发测试阻塞并发测试Map并发测试 关键词 State 在很多时候我们…...

问心 | 再看token、session和cookie

什么是cookie HTTP Cookie&#xff08;也叫 Web Cookie或浏览器 Cookie&#xff09;是服务器发送到用户浏览器并保存在本地的一小块数据&#xff0c;它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。 什么是session Session 代表着服务器和客户端一次会话…...

Ubuntu 安装 CUDA and Cudnn

文章目录0 查看 nvidia驱动版本1 下载Cuda2 下载cudnn参考&#xff1a;0 查看 nvidia驱动版本 nvidia-smi1 下载Cuda 安装之前先安装 gcc g gdb 官方&#xff1a;https://developer.nvidia.com/cuda-toolkit-archive&#xff0c;与驱动版本进行对应&#xff0c;我这里是12.0…...

【漏洞复现】Grafana任意文件读取(CVE-2021-43798)

docker环境搭建 #进入环境 cd vulhub/grafana/CVE-2021-43798#启动环境&#xff0c;这个过程可能会有点慢&#xff0c;保持网络通畅 docker-compose up -d#查看环境 docker-compose ps直接访问虚拟机 IP地址:3000 目录遍历原理 目录遍历原理&#xff1a;攻击者可以通过将包含…...

磨金石教育摄影技能干货分享|春之旅拍

春天来一次短暂的旅行&#xff0c;你会选择哪里呢&#xff1f;春天的照片又该如何拍呢&#xff1f;看看下面的照片&#xff0c;或许能给你答案。照片的构图很巧妙&#xff0c;画面被分成两部分&#xff0c;一半湖泊&#xff0c;一半绿色树林。分开这些的是一条斜向的公路&#…...

中断以及 PIC可编程中断控制器

1 中断分为同步中断&#xff08;中断&#xff09;和异步中断&#xff08;异常&#xff09; 1.1 中断和异常的不同 中断由IO设备和定时器产生&#xff0c;用户的一次按键会引起中断。异步。 异常一般由程序错误产生或者由内核必须处理的异常条件产生。同步。缺页异常&#xff…...

SecureCRT 安装并绑定ENSP设备终端

软件下载链接链接&#xff1a;https://pan.baidu.com/s/1WFxmQgaO9bIiUTwBLSR4OA?pwd2023 提取码&#xff1a;2023 CRT安装&#xff1a;软件可以从上面链接进行下载&#xff0c;下载完成后解压如下&#xff1a;首先双击运行scrt-x64.8.5.4 软件&#xff0c;进行安装点击NEXT选…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...