大历史下的 tcp:一个松弛的传输协议

2024-05-07 22:04
文章标签 协议 历史 tcp 传输 松弛

本文主要是介绍大历史下的 tcp:一个松弛的传输协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果 tcp 是一个相对松弛的协议,会发生什么。

所谓松弛感,意思是它允许 “漏洞”,允许可靠传输的不封闭,大致就是:“不求 100% 可靠,只要 90%(或多或少) 可靠,另外 10% 的错误可检测到” or “不实现 100% 可靠逻辑,只负责 99%(或多或少) 大概率事件,忽略 1% 的小概率事件,由上层协议处理或不处理”。

前文谈到 tcp timewait,我说只需一个按连接递增的 16bit 全局 version option 就能不用 timewait 和 timestamps 而解决 segment 归属问题,timewait 可以直接取消,timestamps 另作他用。如此可卸载大量复杂性。

这题还有更松弛的解法,比如为每个连接随机生成一个 16bit 标识,或用当前时间生成一个摘要作为 tcp option 替代全局递增 version 做连接区分。如果没有松弛理念,经理肯定会说 “16bit 容易碰撞,要么你用 32bit 或 64bit?”,但相反的问题拉僵了他也考虑不到,问题是,旧连接 seg 进入新连接的概率比 16bit 摘要碰撞的概率更大吗,连续两次旧连接 seg 侵入新连接的平均时间比连续两次 16bit 摘要碰撞的时间更短吗?

不管怎样,真发生了怎么办,如何甄别?应用层校验啊。

设计一个绝对可靠的传输协议初衷是好的,但如果为保证绝对可靠而引入概率很低但复杂的机制使代码膨胀,就是坏的。综合来看,协议的可靠性是收益,而 cpu,内存的时空成本,人员维护成本都是开销。

保证交通工具 99.99% 的可靠性,剩下的交给保险公司,否则就要在飞机上挂巨型降落伞并防止降落伞故障而在地面铺巨型气垫了。

再来看保序。

保序指结果而不是过程,是目标管理,应该用内存拷贝(memcpy)而不是队列(queuing)的过程理解传输协议。

如果你有 100 个 cpu(就不扯 gpu 了),要把 10GB 的内存从一处拷贝到另一处,你会怎么做。这是一个非常经典的 “在规定时间内到某地集合” 的问题,逾期未到者会被催促,或干脆就不等了。因此,传输协议应交互的控制信息类似内存 bitmap(增量交互 or 差分交互,whatever) 而不是一个连续序列号空间(tcp scoreboard)。

要传输 10GB 数据,有 100 条路径可达目的地,协议应该可在这 100 条路径上随意喷洒 byte,效果是,对面的内存 bitmap 越来越密集,最终全部变成 1。而不是像 tcp 那样同时只能沿着其中一条路径传输 byte stream,然后发现这样效率很低后搞什么 mptcp,无非是缩小了问题而没有改变问题。

传输层属于端到端视角,不该看到 queuing,网络层的路由和转发才关注 queuing,传输协议要面向接口而不是面向实现。就像 memcpy,无论正着拷贝,反着拷贝,分若干块多个 cpu 一起拷贝均 ok,传输协议不必关注 byte 具体在哪条路径上传输,至于 byte stream 语义,就看你如何管理 buffer 以及如何交互 bitmap,这些反而是小事。

tcp 保序不松弛的原因在于它内置了 byte stream 语义,对 byte 间的相对位置就有了假设,如果假设先 x 后 y,则一旦先收到 y 而不是 x,就一定要做出 “修正逻辑”,对 tcp 而言,这就是 update scoreboard & mark lost & update reordering 那一块巨复杂的根源,等等,什么是 reordering,你看这就是过程管理而不是目标管理了吧。

再看拥塞控制。

传统意义上狭义的拥塞控制就是 tcp 拥塞控制,它本质上是在控制 inflight,比如通过控制 cwnd 将 inflight 限制在合理范围内,通过 pacing 减缓突发,显然控制的是报文数量是标量。然而 tcp 将这标量绑在 scoreboard 上,这意味着必须在 scoreboard 这个连续序列号空间把标量一个个数出来,但重传报文重传一次后就不能识别乱序,控制 inflight 的标量还没数完可能 scoreboard 就失效了,于是被迫跌入 rto retrans。后来 rack 为 scoreboard 上的报文贴上了时间戳,才能在时间维度区分同一个报文的多次传输,当然,rack 也并非只用于 tcp。

将一个标量绑在 scoreboard 序列号空间有个最大的问题现在才提,这种耦合事实上自己断送了拥塞控制的另一条路,除了控制 inflight 外,还可以换另一条路或多路径负载均衡,而 tcp 一旦这样做就必然会打乱 scoreboard 上报文相对顺序假设,造成 sender 采用更多 “修正逻辑”,后果就是大量乱序导致的不必要重传,甚至假 rto。

若采用 bitmap 交互应答确认,拥塞控制就能彻底独立出来。receiver 只需在应答中用特定字段标识收到的报文数量,标量的事直接用标量表示,sender 自然可以直接算出 inflight,从 bitmap 中选出下一批报文填充 inflight 维持守恒律即可。

端到端拥塞控制的本质从不是什么端到端的 qos,而是用 inflight 适配网络管道,管道并不局限于单条路径,至于你是追求管道效能最高(E = bw / delay 最大),还是追求吞吐最高(bw 最大),或管道利用率最高(bw * min_delay 最大),以此来区分你使用哪种拥塞控制算法。

更有用的是,bitmap 而不是顺序序列号交互应答确认可以让协议更加柔性,receiver 可自行决定这次传输是可靠的还是允许有损的。

不针对 tcp,下图是一个传输协议的统一描述,可用于 quic,rdma 以及各种 rpc:
在这里插入图片描述

历史上,由于 buffer 小,带宽低,惜字如金多交互,时间换空间,tcp 等协议不得不如此设计,但悲哀的是这些历史遗留的传统理念却深深影响了几乎所有现代传输协议的设计和实现。

tcp 协议,无论从 rfc 规范,linux 实现还是日常运维,包含很多很贱很小概率很恶心的 issue,这些 issue 仅在两种场景下最有用,一个是面试,一个是业务咨询,并且如果你花了大量时间解决一个业务咨询后一般会将此问题用于面试,反过来也一样。大致可归为 “timewait 类”,“为什么乱序”,“为什么被 reset”,“窗口上不去” 几个恶心点,但这些问题大多不会严重影响业务,我本人被这类问题恶心了 18 年,期间曾做的一个 dcn transport 就是针对 tcp 的最大反驳,只有三千行代码,竟至少与三万行的 tcp 等效而无不及。本文借几个典型 issue 探讨一番。

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

这篇关于大历史下的 tcp:一个松弛的传输协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/968515

相关文章

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端

Modbus-RTU协议

一、协议概述 Modbus-RTU(Remote Terminal Unit)是一种基于主从架构的通信协议,采用二进制数据表示,消息中的每个8位字节含有两个4位十六进制字符。它主要通过RS-485、RS-232、RS-422等物理接口实现数据的传输,传输距离远、抗干扰能力强、通信效率高。 二、报文结构 一个标准的Modbus-RTU报文通常包含以下部分: 地址域:单个字节,表示从站设备

从希腊神话到好莱坞大片,人工智能的七大历史时期值得铭记

本文选自historyextra,机器之心编译出品,参与成员:Angulia、小樱、柒柒、孟婷 你可能听过「技术奇点」,即本世纪某个阶段将出现超级智能,那时,技术将会以人类难以想象的速度飞速发展。同样,黑洞也是一个奇点,在其上任何物理定律都不适用;因此,技术奇点也是超越未来理解范围的一点。 然而,在我们到达那个奇点之前(假设我们能到达),还存在另一个极大的不连续问题,我将它称之