TCP/IP 协议演进中的瓶颈,权衡和突破
所有(去掉 “几乎” 修饰)问题都来自于生长速度的不一致,换句话说,膨胀不是均匀的,从而产生瓶颈甚至触碰极限,TCP/IP 从协议到实现面临的多方问题与动物体型不能无限大,摩天大楼不能无限高本质上一样。
如今被高性能网络诟病的 BSD socket API 诞生之初的姿态是非常高的,1980 年代的网络非常慢,CPU 通过 socket API 不慌不忙地喂数据在当时是一个很直接很简单的方式,就算加上拷贝,上下文切换的拖累,网络依然相对很慢。彼时如果能料到网卡终有一天会远超 CPU,socket API 可能就会以一种更容易扩展的形式存在。如果认识到网络只是在当时慢但总归会变快,socket API 便会以更集约的方式而不是慢吞吞地将数据准备好。
如今的 DPDK,零拷贝技术终究还是以 work around 出现,几乎已经成了事实标准,但存量应用程序非常难(几乎不可能)迁移到新方案以获取高性能。现在网络快而 CPU 慢,再设计网络 API,它不应该是反过来(与 socket API 相反)慢吞吞将数据交给主机,而且网卡集约处理更多逻辑,也就是小经理们都正在做的事,不吹不黑,这事(至少目前)靠谱。
再看协议本身,IP 报文长度被限制在 64kB,可以太网 MTU 却只有 1500,这种错配意味着什么?虽然大家都清楚分层模型在层间不必耦合,各做各的,但总会有现实考虑。
设想 IP 允许一个无限长(64bit?128bit?)的报文长度,当需要在物理网络上发送这样的一个报文时,链路将回退到电路交换,而这正是分组交换网要避免的,即避免长时间占用线路。考虑到典型的 T1,E1 链路,发送一个占用线路不超过一个容忍值的报文,求其最大长度。64kB 在 1.5Mb/s T1 链路占据 0.3s 显得稍久但能容忍,同时考虑实际物理链路 MTU 有限以及网络带宽会随技术发展不断提高,这个实际的时间会更短,且越来越短,而 64kB 仅由 16bit 即可表达,对带宽和内存要求也不大。
随着带宽逐渐增大,压力给到了主机,因为发包收包越来越快,一个报文的持续间隔相对越来越短,主机被中断的频率越来越高,64kB 的长度显小了,tcp: BIG TCP implementation 我引用好几次,但终究是 work around。IPv6 仍然维持 64kB 长度限制,但允许扩展头发送巨型报文,这个方式就不错,兼容和扩展都有了。
以上两例旨在说明主机和网络发展不对称,CPU 和网卡的增长率不同产生了最初的设计并导致了最终的反转,然后 work around 以及下一代的修复,如此再循环。
这些经验教训似乎表明所有旧时的设计都是不足够的,但并非总是如此。
继续看 TTL,只有 8bit,在带宽,内存资源看似可以浪费的现在,8bit 是一个让人看一眼就觉得可怜就想拉长的字段,但它应该更长一些吗?
高速转发最大的阻力就在交换节点(路由器和各类交换机),随着带宽增长以及路由(主要是增量 IPv6 路由)汇聚规整化,更小的路由表在基建方面倾向于推动建设更长的链路,端到端的跳数应该减少而不是增加。全球的地理范围有限,网络扩展倾向于跳数增加,但路由汇聚抵消了新增的那一跳,互联网旨在构建连通性而不是在织蜘蛛网。所以直到 IPv6,TTL 依然只有 8bit。
再看 IP 地址本身,32bit 显然太短,但 160bit 绝对太长了,这是一个有争议的问题,IPv6 取 128bit 属折中,这里换一个视角,IPv6 128bit 的地址长度最大的问题在于地址空间大小和期望特性间的错配。
书写,记忆难度以及配置问题不值得一提,毕竟 IPv4 地址也不太容易书写记忆,所以才有了 DNS,且不必说计算机系统处理海量信息能力对人而言本就是降维打击。
过于庞大的地址空间意味着几乎无限的分配可能性,若稀疏分配,路由表的存储以及查询开销将变得巨大,若紧凑聚合分配,理论上离散的地址将聚集在一起有助于减小路由表条目,但也抵消了抗扫描的优势,此外,稀疏的空间抗扫描的同时,也几乎让攻击溯源变得不可能。各类 trade off 是非常难的,地址空间越大,问题越难,越容易遗留问题。
128bit 地址空间倾向于被塞入很多层间信息(反正够用),让人更容易以浪费的理念去使用。但不要忘了,塞入更多信息意味着暴露更多信息,这又是一个争议话题。MAC 地址,位置,类型,甚至公司机构的规模,都可能会被映射进地址空间,而 IP 的初衷只是一个 best-effort 核,无状态,不记名,128bit 空间本无碍,大地址空间便于路由管理,但它太大也容易被误用。
下一个问题,TCP/UDP 端口号 16bit,如果有下一代协议,它应该扩展到 32bit 吗?
事实上很少有人意识到这个问题,但很多工人都遭遇并排查过 timewait socket 太多导致建连失败,bind,connect 的 CPU 热点问题,在此背景下,很多把戏应声而出,包括魔改内核缩短 timewait 时间,stap -g 硬改 timewait 状态,甚至 Linux 内核在 bind,connect 分别遍历奇偶端口号选择端口,而这正是 CPU 热点的根源,总之一塌糊涂。
本质上这是由于 16bit 端口号空间过小导致。如果扩展到 32bit,问题就迎刃而解。主机简单递增并选择全局 32bit 变量作端口号即可,毫不费力。
随着网络速度越来越快,越要解放节点算力。随着网络带宽相对于主机的加速度越来越大,传输每字节的主机时间越来越小,因此协议必须越来越简洁,减少计算量!具体实例参见 QUIC,Falcon 等。
最后来看 TCP 序列号,32bit 够吗?
在 1970~1980 年代足够了,但随着带宽增加,序列号回绕问题必须面对,同时 32bit 的序列号空间也限制了最大 rwnd 只能达到 2^30(就这还是在 wscale 选项的支持下),导致更大的带宽无法被充分利用。同样的,各种复杂且难以理解的把戏就来自于这种原始设计的向后不兼容性。
设计一个向后兼容的序列号表示法并不难,由于数据包的自解释性,TLV 及其变体是常见的方式。可以限制最大的序列号空间为 16Byte,这是个天文数字,足够度量现实中可以想象的任意数据的长度,因此一个序列号可以是 1~16Byte,具体多少取决于一个额外的 4bit 长度,比如它是 1110b,说明后面 15Byte 都是序列号。
先这样,这就是今天要讲的故事。
浙江温州皮鞋湿,下雨进水不会胖。
相关文章:
TCP/IP 协议演进中的瓶颈,权衡和突破
所有(去掉 “几乎” 修饰)问题都来自于生长速度的不一致,换句话说,膨胀不是均匀的,从而产生瓶颈甚至触碰极限,TCP/IP 从协议到实现面临的多方问题与动物体型不能无限大,摩天大楼不能无限高本质上一样。 如今被高性能网…...

软件测试面试八股文,查漏补缺(附文档)
大家好,最近有不少小伙伴在后台留言,准备面试了,又不知道从何下手!为了帮大家节约时间,特意准备了一份面试相关的资料,内容非常的全面,真的可以好好补一补,希望大家在都能拿到理想的…...

IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具
文章目录 一、IDEA二、建立第一个 Java 程序三、IDEA 常用设置四、IDEA 集成版本控制工具(Git、GitHub)4.1 IDEA 拉 GitHub/Git 项目4.2 IDEA 上传 项目到 Git4.3 更新提交命令 一、IDEA 1、什么是IDEA? IDEA,全称为 IntelliJ ID…...
YOLOv10-1.1部分代码阅读笔记-transformer.py
transformer.py ultralytics\nn\modules\transformer.py 目录 transformer.py 1.所需的库和模块 2.class TransformerEncoderLayer(nn.Module): 3.class AIFI(TransformerEncoderLayer): 4.class TransformerLayer(nn.Module): 5.class TransformerBlock(nn.Module)…...

机器人革新!ModbusTCP转CCLINKIE网关揭秘
在当今这个科技日新月异的时代,机器人技术正以前所未有的速度发展着,它们在工业制造、医疗服务、家庭娱乐等多个领域扮演着越来越重要的角色。而随着机器人应用的普及和多样化,如何实现不同设备之间的高效通信成为了一个亟待解决的问题。开疆…...

JWT包中的源码分析【Golang】
前言 最近在学web编程的途中,经过学长提醒,在进行登陆(Login)操作之后,识别是否登陆的标识应该要放入authorization中,正好最近也在学鉴权,就顺便来看看源码了。 正文 1. 代码示例 在进行分…...
SpringBoot数据字典字段自动生成对应code和desc
效果:接口会返回orderType,但是这个orderType是枚举的类型(1,2,3,4),我想多返回一个orderTypeDesc给前端展示,这样前端就可以直接拿orderTypeDesc使用了。 1. 定义注解 …...

TencentOS 2.4 final 安装mysql8.0备忘录
准备 tencentOS 2.4 与Red Hat Enterprise Linux 7 是兼容的。 我们首先从oracle官网上下载mysql的源文件。 下载完成后你会得到以下文件: mysql84-community-release-el7-1.noarch.rpm 安装 首先你需要切换到root用户下。 1.安装源文件 yum localinstall my…...

Hadoop HA安装配置(容器环境),大数据职业技能竞赛模块A平台搭建,jdk+zookeeper+hadoop HA
HA概述 (1) 所谓HA(High Availablity),即高可用(7*24小时不中断服务)。 (2) 实现高可用最关键的策略是消除单点故障,HA严格来说应该分为各个组件的HA机制,H…...
使用javascript读取波形文件数据,并生成动态的波形图
代码如下: // HTML5 Canvas 动态波形生成器 // 使用JS读取波形文件并生成动态波形// 创建Canvas并设置上下文 const canvas document.createElement(canvas); canvas.width 800; canvas.height 400; document.body.appendChild(canvas); const ctx canvas.getC…...
服务器系统维护与安全配置
一、硬件系统的安全防护 硬件的安全问题也可以分为两种,一种是物理安全,一种是设置安全。 1、物理安全 物理安全是指防止意外事件或人为破坏具体的物理设备,如服务器、交换机、路由器、机柜、线路等。机房和机柜的钥匙一定要管理…...

大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!
大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!DeepSeek-V3上线即开源;OpenAI 发布高级推理模型 o3https://mp.weixin.qq.com/s/9qU_zzIv9ibFdJZ5cTocOw?token47960959&langzh_CN 「青稞大模型Weekly」,持…...
Spring Boot自定义注解获取当前登录用户信息
写在前面 在项目开发过程中,难免都要获取当前登录用户的信息。通常的做法,都是开发一个获取用户信息的接口。 如果在本项目中,多处都需要获取登录用户的信息,难不成还要调用自己写的接口吗?显然不用! 以…...
js创建二维空数组
js创建二维空数组 错误使用原因分析分析1举个例子:解释: 正确创建二维数组总结: 错误使用 今天在写代码的时候,需要创建一个长度为2的空二维数组,我当时第一反应就是,使用let arr new Array(2).fill([])&…...
AF3 checkpoint_blocks函数解读
checkpoint_blocks 函数实现了一种分块梯度检查点机制 (checkpoint_blocks),目的是通过分块(chunking)执行神经网络模块,减少内存使用。在深度学习训练中,梯度检查点(activation checkpointing)是一种显存优化技术。该代码可以: 对神经网络的块(blocks)按需分块,并对…...

下载并使用CICFlowMeter提取网络流特征(Windows版本)
CICFlowMeter简介 CICFlowMeter是一款流量特征提取工具,从原始的pcap包中聚合流,并提取流特征到csv格式的文件中。使用CICFlowMeter提取的特征有助于后续基于网络流的分析与建模 官方github地址:https://github.com/ahlashkari/CICFlowMete…...

深入了解JSON-LD:语义化网络数据的桥梁
目录 前言1. JSON-LD概述1.1 什么是JSON-LD?1.2 JSON-LD的优势 2. JSON-LD的核心概念2.1 上下文(Context)2.2 词汇表(Vocabulary)2.3 标注语言(Markup Language) 3. JSON-LD的语法与结构3.1 基本…...

分布式 IO 模块助力冲压机械臂产线实现智能控制
在当今制造业蓬勃发展的浪潮中,冲压机械臂产线的智能化控制已然成为提升生产效率、保障产品质量以及增强企业竞争力的关键所在。而分布式 IO 模块的应用,正如同为这条产线注入了一股强大的智能动力,开启了全新的高效生产篇章。 传统挑战 冲压…...
webrtc源码编译【linux/安卓】
编译webrtc库 环境ubuntu22.04 推荐在linux里运行一个docker容器,在新环境里搭建。 准备工作 #我使用了下面的安装命令。目前知道的必须需要的 git python3 unzip ninja jdk file lsb-release apt install -y git curl build-essential python3 python3-pip pyt…...
亚矩阵云手机
亚矩阵云手机是一个集成了云计算、大数据、人工智能和边缘计算等先进技术的云平台,它通过ARM虚拟化技术在云端运行手机应用,提供了全面、高效且稳定的服务。以下是对亚矩阵云手机的详细解析: 技术基础与架构 1.ARM虚拟化技术:亚矩阵云手机基于ARM服务器和…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...