大历史下的 tcp:从早期拥塞控制 到 bbr 再到未来

TCP协议有了拥塞控制机制,为什么还会网络拥塞?

随着骨干带宽增长,拥塞被阻滞在接入网,大规模拥塞崩溃难再呈现,tcp 拥塞控制(不仅限于 tcp,但以 tcp 为主线来说)从避免崩溃,保证可用性逐渐转到提高效率。

过程曲折而漫长。

起初 aimd 挺好,为了更好,bic/cubic 相继出炉,此过程正与 linux 蓬勃发展同步,大概从 1990 年初一直持续到 2005 年前后,linux kernel 内置所谓 “拥塞状态机” 逻辑,以至于完全不同于传统 aimd 的 delay-based cc 比如 vegas 竟无处安放。

拥塞状态机其实就是 loss-based cc 的抽象,将 “拥塞避免”,“快速重传” 等这些状态与 tcp 语义的传输和重传强制捆绑,以至于只要出现丢包进入快速重传,必须无条件执行固定逻辑,比如降窗(比如 prr)。这种框架下,如果想在丢包时不降窗就无从谈起,显然 vegas 不适合这框架。但由于这种方式工作的足够好,vegas 几乎被遗忘。

进入 2010 年代,随着摩尔定律效应减弱,主机带宽逐渐追平交换带宽,而移动互联网兴起,图片,视频等大流量激增,单位带宽逐渐吃紧,带宽资源不能再继续以粗放方式被使用,另一方面,受限于时延 qoe,buffer 不能继续增大,cc 开始以带宽利用率为目标,pacing 代替突发降低报文到达率,减少对 buffer 的依赖。

bbr 在此背景下产生。

为支持 bbr,linux kernel 引入 cong_control 回调,允许 cc 自定义行为,开辟了拥塞状态机之外的新路。

但直到今日这条新路上大量的代码都在处理 “兼容公平性”。

当年 vegas 被诟病不能和 cubic 共存,解法其实是全网部署 vegas。如今 bbr 又落入寻求 “与 aimd(主要是 cubic) 公平混部” 的老路,而这些问题几乎不能彻底解决。

分布式网络是个博弈网络,即使 bbr 优秀到让人们明确想用 bbr 替换 cubic,但随着替换的进行,替换收益递减,人们的替换动机减弱,最终 bbr 占比将稳定在不到 80%,bbr 还是要兼容 cubic,因此 bbr3 或许是个好算法。

但数据中心则是个不同的场子。

如果在数据中心大搞公平混部就大可不必了,找经理开会能解决的事就不要用算法自适应。一个简单方法是增量部署算法默认设置在装机脚本,存量逐渐分批次切换。或全部 cubic,或全部 bbr,或全部 vegas。

最近一直强调同质,卡车从不考虑与轿车碰撞时的公平性问题。核心还是那些车轱辘话,让算法尽量少做甚至不做判断,猜测,评估,针对的事,简单才能高效,大一统对效率反而是拖累,俾斯麦明白的道理,将奥地利排除在帝国之外,主打一个纯净。
暂时不说关于同质的话题了,说恶心了。接下来看 bbr。
不管哪个场子,也不管目标是避免崩溃还是提高效率,拥塞控制的核心都是 数据包守恒,在这个视角下重新审视 bbr,看它有什么问题:
在这里插入图片描述

具体可参考 bbr 模型 以及 更合理的 bbr。

此前说过,bbr 看起来好只因为它的大开合动作,并且很多人理解的 “bbr 好” 就是和 cubic 相比 bbr 的吞吐更高,这是对拥塞控制最大的误解,你不光要看结果,还要看拿什么换的结果。其实 bbr 选的操作点非常不稳定,所以无法自适应收敛,需要一个状态机不断进行刺激和反应,总体上大开合的意思就是激进。如果操作点对了,什么都不需要做就能收敛。

看上图的下半部分,合理的 bbr 操作点更偏右,在这个操作点上,和理想情况相反,bbr 需要持续占据一些 buffer 空间,用它来做带宽变化的自动探测。

bbr 用 maxbw 追踪最佳操作点是追不到的,在多流共享带宽时更是捕风捉影。如果办不到就不要办了,计算是滞后的,且根本算不准,那么追踪 max(bw / rtt) 就豁然开朗:

  • 在 winmax 中追踪 alpha rounds 的 bw / rtt,将其 bw 记为 b;
  • 在 winmin 中追踪 k*alpha rounds 的 rtt,记为 minrtt;
  • 保持 inflight = b * minrtt + beta。

这就避开了复杂的状态机,probe,drain 等逻辑。围绕上面的 3 步算法做任何事都行,其实只这 3 步就够了。

本文不详细聊这个算法动力学,简单推理一下,如果有新带宽,max(bw / rtt) 会更新,bw 增加,inflight 增加,如果有效带宽减少,早晚 max(bw / rtt) 会滑走而更新,bw 减少,inflight 减少,而如果 bw 和 rtt 同时增加或减少,minrtt 在更长周期不改变,算法就可以自适应它们而改变 inflight。

解释一下最后一步为啥要 + beta,这是 vegas 里的办法,目的是 “始终在 buffer 中保留一些报文”,效果是:

  • 有流退出,这些报文可以瞬间分享腾出的带宽;
  • 有流进入,这些报文避免当前流被挤占而抖动。

是不是简单又有趣。

那么 pacing 哪去了?和传统 bbr 不同,pacing 退居二线,而 inflight 成了第一控制要素,只要保持 inflight 就那么多,pa 不 pacing 不重要,反正都要回来,核心还是守恒律。

人们对 pacing 的误解在于以为 pacing rate 是端到端的,但它只对第一跳有效。数据包在网络转发过程中,其形式完全受交换机(等一切转发节点)当前状态的影响,在没有任何 aqm,qos 配置的简单 fifo 情形,一条流的 pacing rate 完全由该交换机当前的 buffer 构成决定。

端到端控制需要控制 inflight,而不是 pacing rate。

pacing 按照 delivery rate 的 n 倍吐,简单给前面第一跳交换机 buffer 留点 time slot,不用太精确算计,因为算了也没用,统计复用要按统计方法来,抓住统计量,追踪,过滤它们,做出判断,执行守恒律。

拥塞控制的核心是在 pipe 中保有多少 inflight,而不是以多大的 pacing rate 发送,所以控制要素还得是 cwnd,而测量 delivery rate 只做采集 bw / rtt 而计算 inflight。

好,该总结一下了。

tcp 拥塞控制从最初 1980 年代末的 aimd 随着 linux kernel 经过 1990 年代直到 2010 年代引入 bbr,要分清楚新的,旧的,就知道哪些是核心,而哪些是为了兼容公平性。其中摩尔定律,移动互联网,视频流的发展也对 tcp 拥塞控制的形态产生了甚至决定性的影响。

提到拥塞控制就是慢启动,拥塞避免,快速重传那一套非常教条,拥塞控制和丢包检测和重传是没有关系的两件事,恰巧 tcp 在初期实现 linux kernel 的拥塞控制算法时作为内置硬编码实现,而后来模块化时又没有将其分开,埃里克作为后来的妹忒呢儿自己可能对这方面也不是非常清楚,本没关系的逻辑就被拥塞状态机关联了起来,但如果网络发生拥塞,用 inflight = 100 来控制拥塞,这 100 个报文中并不规定哪些是新报文哪些是重传报文。

30 多年的发展让 tcp 拥塞控制算法自发多样化,但兼容公平性并不是每个场景都需要考虑,比如数据中心。bbr3 作为以兼容公平性为目标的算法,它进入通用 linux kernel 的目标或许能实现,但作为 bbr 本身,bbr4,bbr5 应该在其提高带宽利用率以及自身公平性方面有更多迭代。

最后,我认为以守恒律为核心的 inflight 控制才是高尚的,E = max(bw / rtt) 是一个好收敛点,以 inflight = bw * minrtt + beta。而不是捕风捉影的 pacing 计算。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

外包干了1年....字节跳动面试高频考点,懒加载

一、文章内容 什么是懒加载懒加载的优点什么时候使用懒加载学习懒加载前置内容实战懒加载图片 二、什么是懒加载? 从语法角度分析懒加载,懒是adj形容词,加载是名词;或者懒看为副词,加载作为动词,这样就能理解懒加载了就是懒懒的/地加载,更通俗的讲就是通过一种手段来加载.就…

java创建线程池的方法

简介 线程池是一种用于管理和重用线程的机制,它可以有效地管理线程的创建和销毁,减少线程创建和销毁的开销,并且能够控制并发线程数量,避免资源耗尽和系统过载。Java 提供了java.util.concurrent 包来支持线程池的实现。 1.Threa…

密码破解----zip文件密码字典、暴力破解

下边代码包含了暴力破解,使用字典破解zip的密码 from zipfile import ZipFile import os from tqdm import tqdm def passwd(path, pwd):# 获取文件的后缀名suffix_name os.path.splitext(path)[-1][1:]# print(suffix_name)# 如果是zip文件if suffix_name zip:#…

AIGC教育行业全景报告:AI助教和家教成真,学习机迎来新机遇

原文:AIGC教育行业全景报告:AI助教和家教成真,学习机迎来新机遇 - AI新智界 图片来源:由无界AI生成 经过一年的快速迭代,业内对于生成式AI将会率先落地于哪些行业已经有了答案。 教育领域,不仅被OpenAI列…

数字时代的风险评估:AI如何改变贷款分析

每样商品都有价格,但您能否负担得起?贷款非常适合生活中的大额支出,比如买房、买车或支付学费。偿还贷款可能会很棘手。根据最新的《家庭债务和信贷季度报告(Quarterly Report on Household Debt and Credit)》&#x…

2024年面试工具篇Postman面试题及答案

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

TypeScript之类

一、类的定义 二、对象的创建 class Person{id:number;name:string;age:number 18;constructor(id:number,name:string){this.id id;this.name name;}introduce():string{return hello,I am ${this.name},and I am ${this.age} years old.} }let person new Person(1,zhan…

Linux-docker安装数据库redis

1.拉取redis镜像 docker pull redis # 下载最新的redis版本 docker pull redis:版本号 # 下载指定的redis版本ps:我这是已经下载最新版本的redis 2.查看redis镜像 docker images3.创建挂在路径并授权 mkdir -p /usr/local/redis/data mkdir -p /usr/local…

Ubuntu22.04配置ROS2+PX4仿真环境

Ubuntu22.04配置ROS2PX4仿真环境 主要参考源: https://blog.csdn.net/weixin_44174421/article/details/135827130 https://blog.csdn.net/Zecet/article/details/130474620 一、准备工作 确保网络能够连接到github,出错主要源自于此;确保…

2024/4/16 网络编程day4

/*TCP并发服务器端*/ #include <myhead.h> #define SER_IP "192.168.125.173" #define SER_PORT 8888 void sighanger(int signum){if(signumSIGCHLD){//子进程终止信号while(waitpid(-1,NULL,WNOHANG)>0);//循环回收僵尸进程} }int main(int argc, const c…

03_信号和槽

信号和槽 系统的信号和槽自定义信号和槽Lambda表达式 系统的信号和槽 下面我们完成一个小功能&#xff0c;上面我们已经学习了按钮的创建&#xff0c;但是还没有体现出按钮的功能&#xff0c;按钮最大的功能也就是点击后触发一些事情&#xff0c;比如我们点击按钮&#xff0c;…

12.哀家要长脑子了!

1.189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; ​ 方法一&#xff1a; 要注意这个k是可以大于0的&#xff0c;所以旋转数组的时候要一直保证是在1-n的范围内&#xff1a;%实现 把k个元素旋转放到前面&#xff0c;前面n-k个元素是向后移动的。 class Solution { …

【Phytium】飞腾D2000 UEFI/EDK2 适配 RTC(IIC SD3077)

文章目录 0. env1. 软件2. 硬件 10. 需求1. 硬件2. 软件 20. DatasheetCPURTC 30. 调试步骤1. 硬件环境搭建2. UEFI 开发环境搭建3. 修改步骤1. UEFI 中使能RTC驱动、配置RTC信息等1.1 使能RTC驱动1.2 修改RTC对应的IIC配置信息1.3 解决驱动冲突1.4 验证波形 2. 修改对应RTC驱动…

[lesson36]经典问题解析三

经典问题解析三 关于赋值的疑问 什么时候需要重载赋值操作符&#xff1f;编译器是否提供默认的赋值操作&#xff1f; 编译器为每个类默认重载了赋值操作符 默认的赋值操作符仅完成浅拷贝 当需要进行深拷贝时必须重载赋值操作符 赋值操作符与拷贝构造函数有相同的存在意义 …

零基础入门测试该学什么?超全整理,照着学就对了!

对于很多小白而言&#xff0c;想要转行软件测试岗位&#xff0c;却又怕自己从来没有接触过计算机&#xff0c;底子很薄弱&#xff0c;从而还没开始就打起了退堂鼓。也有许多初学者&#xff0c;在入门的过程中&#xff0c;苦于不知道该学什么&#xff0c;又该从何学起&#xff0…

代码随想录算法训练营第四十二天| 二维背包、一维背包、LeetCode 416.分割等和子集

一、二维背包 文章讲解/视频讲解&#xff1a;https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 状态&#xff1a;已解决 1.背包问题介绍 背包问题实则是一类问题的集合&#xff0c;有好多不同小类型&#xff0c…

单位优秀信息宣传员告诉你向媒体投稿你不知道的好方法

作为基层社区信息宣传工作队伍中的一员,我刚开始接手单位的信息宣传投稿任务时,真的是一片茫然。没有任何媒体编辑的熟人朋友,我只能硬着头皮,一家家地去联系媒体,沟通投稿的事宜。这个过程真的是既费事又费力,每次投稿都像是在茫茫大海中寻找那一丝被认可的机会。 因为媒体对稿…

VLAN Mapping原理描述

基本原理 路由器收到带Tag的数据报文后&#xff0c;根据配置的VLAN Mapping方式&#xff0c;决定替换外层Tag中的VLAN ID或优先级&#xff1b;然后进入MAC地址学习阶段&#xff0c;根据源MAC地址映射后的VLAN ID刷新MAC地址表项&#xff1b;根据目的MAC映射后VLAN ID查找MAC地…

T细胞耗竭

目录 T Cell Exhaustion T 细胞衰竭路径上的细胞和分子路标 研究起源 介绍 T 细胞耗竭的发生路径 耗尽的T细胞亚群的解剖分离和迁移 持续TCR刺激的收益递减 通过共调节受体进行发育微调 细胞因子介导的耗尽T细胞亚群的特异性 T细胞耗竭和表观遗传 T Cell Exhaustion…

面试问答之转账功能测试点详解

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…
最新文章