当前位置: 首页 > 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选…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...