再看 BBR 到 BBRv3 的公平性改进

从看一篇论文开始:Performance Evaluation of TCP BBRv3 in Networks with Multiple Round Trip Times,结论比较悲观:

  • 虽然 BBRv2/3 试图解决 BBRv1 的公平性问题,但结果依旧不够理想,BBR 的迭代依旧任重而道远。

BBR 即使到了 v3 也依然不能论证稳定收敛,也因此它没办法成为默认拥塞控制算法。工程界和学界虽越发成为熟人社会卷得厉害,以前也不入流的东西最后可能通过类似 “送礼”,“互捧”,“交易” 的途径就能标准化,但下限至少是能基本论证稳定和收敛,BBR 目前还差点。

总体而言,此文观点很明确且有用,比提出个优化点,实验室用 mininet,ns3,tc 模拟仿真一下吊打原生算法几十个百分点,然后水一篇论文强很多,说实话那些东西也只是像我这样没事写篇随笔发个朋友圈的水准。也许稍微好一点,也许还不如我,谁知道呢。

本文剩下的部分主要谈 BBR 内部公平性,展示它的难度,最后以描述外部公平性同样难甚至更难结尾。

作为常识,公平性必须靠 buffer 动力学驱动,在 buffer 挤兑中获得,遗憾的是,BBR 的 Probe 行为不但没有利用 buffer 制造多流收敛,反而放大了差异,倾向于利好 RTT 偏大的流,这是不公平性的根源。就好像一个胖子一点点把瘦子挤到边边一样,在不断接触中,一次挪一点。

来看看 Why。

此前我分析过,若不是 ProbeRTT 主动清空 buffer 堆积,实践中的 BBR 将占 buffer 越来越多(虽然在理论分析中,BBR 从不堆积 buffer 制造队列),这事实即使不看 draft 和代码,稍微想一下就能明白。这里我再重复讲一次(不啰嗦这些,本文也不剩啥了)。

只要 BBR 多流共存,任意一条当前 pacing rate 为 B1 的流只要 Probe 就一定能获得更大的 buffer 占比,从而一定能挤占出哪怕一丁点带宽 B2,且 B2 > B1 作为新的 maxbw 被 max-filter 记住,它随后的 Drain phase 仅能 drain 掉 inflight 中比 B2 · minrtt 多出来的那部分,剩下的 B2 · minrtt - B1 · minrtt 的部分就留在了 buffer 中。

现在用控制变量法,让其它流不进行 Probe,由于已经完成 Probe 的流挤出了更大的 B2,剩下的流即使保持各自当前 pacing rate,buffer 占用仍会增加,一直到这些流的 maxbw 纷纷过期,buffer 才停止增长。现在释放控制变量,让其自由 Probe,不等式传递原理,这种真实情况下一定比假设的情况占用更多 buffer。如此反复,随着 BBR 流持续,buffer 占用将越来越大。

Probe 停止,maxbw 会过期并跌落,buffer 会停涨,但它不会自动清空,只是维持。类似河流经过已经填满的湖泊,除非枯水不会自动排空湖泊一样。更何况,Probe 不会停止,因此 buffer 会一直涨下去:
在这里插入图片描述

若没有 ProbeRTT,buffer 将类似上图指示,从终点不断堆积下去。但在 ProbeRTT 之前,还得先看下 cwnd gain 对 inflight 的约束。

不知是有意还是无意(也许 Google BBR 团队从最开始真的就没意识到这个问题),BBR 增加了 cwnd_gain 作为约束,限制 inflight 最大只能到 2 · BDP,以限制 buffer 的疯涨,但这个限制让 RTT 更小的流的处境更加雪上加霜。

BDP = bw · RTT,先看 bw,BBR 流的 bw 通过 Qp = 1.25 · maxbw · minrtt 的 Probe 量在 buffer 挤占出来, 可见 minrtt 越小,Qp 越小,再看 RTT,由于 buffer 占用持续增长,RTT = RTprop + RTwait 持续增长,管道容量增加,inflight = maxbw · (minrtt + RTwait) > 2 · maxbw · minrtt 更容易首先满足 minrtt 小的流,因此 minrtt 小的流首先被 cwnd 限制。

不光如此,这个 cwnd-limited 问题甚至限制 Probe,越是被压制的流越是被继续压制。由于 minrtt 更小流的 BDP 组分中 RTwait 占比很大,即使它的 Probe 加速比更高,其 bw 增量也不足以弥补 RTwait,maxbw 涨太慢,RTwait 值太大,BDP = maxbw · (minrtt + RTwait) 很快遭遇它的上限 2 · maxbw2 · minrtt。BBR 团队和讨论组早就发现这个问题,BBRv3 进行了修正,Probe 期间的 cwnd_gain 从 2 提升到了 2.25,但并没解决本质问题。

所以,BBR 高度依赖 ProbeRTT,但主动突然排空 buffer 的行为让 BBR 的 ProbeBW 状态被中断,buffer 队列没了,但只是把队列转到了 sender 的发送缓冲区,在端到端的数据生成处看来,数据只是 bufferbloat 在了尚未进入网络协议栈的第 0 跳,ProbeRTT 远没有解决问题,只是转移了问题。
核心问题还是要让算法自动感知 RTT 的升高,无论是 RTwait 的升高还是 minrtt 本来就高,这两种情况下,算法都要倾向于抑制 Probe,无论是缩短 Probe 时间,还是降低 pacing gain。

再一次,第一个想到的还得是靠 sigmoid 做激发函数,不过这次先简单点,直接用两个 sigmoid 来线性叠加,背后的意思是提供两个负反馈:

  • 队列越长,即 RTT - minrtt 越大,越倾向于抑制 Probe;
  • RTprop 越长,越倾向于抑制 Probe;
  • 用 sigmoid 函数去量纲,归一。

操作如下:

S i g m o i d ( x , α , β , γ ) = α 1 + e β ⋅ x + γ \mathrm{Sigmoid}(x,\alpha,\beta,\gamma)=\dfrac{\alpha}{1+e^{\beta\cdot x}}+\gamma Sigmoid(x,α,β,γ)=1+eβxα+γ

A = B = 1 A=B=1 A=B=1

K = A ⋅ S i g m o i d ( R T T − R T p r o p , α 1 , β 1 , γ 1 ) + B ⋅ S i g m o i d ( R T p r o p , α 2 , β 2 , γ 2 ) K=A\cdot\mathrm{Sigmoid}(\mathrm{RTT-RTprop},\alpha_1,\beta_1,\gamma_1)+B\cdot\mathrm{Sigmoid}(\mathrm{RTprop},\alpha_2,\beta_2,\gamma_2) K=ASigmoid(RTTRTprop,α1,β1,γ1)+BSigmoid(RTprop,α2,β2,γ2)

G a i n = S i g m o i d ( K , α , β , γ ) \mathrm{Gain}=\mathrm{Sigmoid}(K,\alpha,\beta,\gamma) Gain=Sigmoid(K,α,β,γ)

用实际现网数据训练,求出最佳拟合的几个 α,β,γ 就可以了。那句废话 A = B = 1 旨在表明一个点,两个并列的 Sigmoid 函数没必要加权,也许你会觉得 “单纯 RTprop 大” 和 “单纯 RTwait 大” 需要区别对待,其实不必,因为 Sigmoid 有个激发特性,只要 RTprop 和 RTwait 没有一起大,它们和的 Sigmoid 函数就可以很小,只需调整 α2,β2,γ2 让其向右偏,这意味着 RTprop 的作用力比 RTwait 更大,反之向左偏就倾向于 RTwait 的作用力更大。

如果不想实现复杂函数(特别是内核中),可分析现网数据后直接用 python 生成一张算好的表,将其粘贴在代码里,代码里查表大概就跟我一个函数几千个 if 分支差不多的意思了。

为了能抵抗并容忍 minrtt 噪声,前几天刚发明一个 minrtt 采集算法,参考 BBR minrtt 的采集,两个算法叠加,让人不明觉厉,可以水一篇论文了。

但且慢,这些启发式把戏难道不是我一直嗤之以鼻的吗,我一再强调 RTT 的不准确性,算不准就别算,所以除却这些可能适合论文或蒙骗经理的把戏,还有一个更加实用的方法。

参考 L4S & TCP Prague,TCP Prague 的 draft 提到一种 极简主义算法 来去除 RTT 相关性,从而解决 AIMD 场景的 RTT 不公平性。模仿该思想,一个正确实用的算法就来了:

P r o b e Q u o t a = M a x B W ⋅ R T p r o p + 0.25 ⋅ min ⁡ ( R T p r o p , δ ) \mathrm{ProbeQuota}=\mathrm{MaxBW}\cdot \mathrm{RTprop}+0.25\cdot\min(\mathrm{RTprop},\delta) ProbeQuota=MaxBWRTprop+0.25min(RTprop,δ)

其中 δ 为一个经验的,统计意义上的 RTprop 中位数或其它的典型值,在不同网络中有不同的典型值。

修改下面的函数即可:

static void bbr_update_cycle_phase(struct sock *sk,const struct rate_sample *rs,struct bbr_context *ctx)
{...case BBR_BW_PROBE_UP:

总之,BBR 的公平性之路还有很长的路要走,不仅仅是 BBR 内部的公平性,还有与 cubic 等 AIMD 算法共存时的外部公平性。

外部公平性,这很大程度上是因为存量 TCP 多数使用久经考验和论证的 cubic 等 AIMD 算法,想当年 Reno AIMD 算法上线时,它是一个从零到一的过程,并不需要考虑外部公平性,而内部公平性非常好论证,随后的 bic,cubic 也只是简单迭代,可一旦涉及完全不同的机制,比如 Vegas,考虑到部署后的公平性,基本就是胎死腹中。看,BBR 为了外部公平性,又回到了老路,哪怕只是为了兼容,可能它必须兼容。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

locust压力测试

安装 pip install locust验证是否安装成功 locust -V使用 网上的教程基本上是前几年的,locust已经更新了好几个版本,有点过时了,在此做一个总结 启动 默认是使用浏览器进行设置的 # 使用浏览器 locust -f .\main.py其他参数 Usage: locust […

优先队列和单调队列(双端队列实现的)

这里写自定义目录标题 一、优先队列与单调队列二、优先队列2.1 概念2.2 增删查 判空2.3 示例代码 三、双端队列四、单调队列4.1 单调递增队列4.2 单调递减队列 一、优先队列与单调队列 二、优先队列 2.1 概念 一种特殊的队列,它与普通队列的主要区别在于元素的出…

如何在idea中写spark程序

在 IntelliJ IDEA 中编写 Spark 程序是一个高效且便捷的方式,以下是一个详细的步骤指南,帮助你在 IntelliJ IDEA 中创建和运行 Spark 程序。 一、环境准备 安装 Java: 确保已经安装了 JDK 1.8 或更高版本。可以通过以下命令检查:…

BERT BERT

BERT ***** 2020年3月11日更新:更小的BERT模型 ***** 这是在《深阅读的学生学得更好:预训练紧凑模型的重要性》(arXiv:1908.08962)中提到的24种较小规模的英文未分词BERT模型的发布。 我们已经证明,标准的BERT架构和…

SpringBoot启动警告:OpenJDK 64-Bit Server VM warning

问题描述 以Debug模式启动Spring boot项目之后,日志打印:OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended, 警告信息 解决方案:配置VM opt…

“该虚拟机似乎正在使用中“

当某一天打开虚拟机突然弹出"该虚拟机似乎正在使用中"。 遇到这种问题的解决方法很简单,出现这种问题是因为错误关闭虚拟机导致,当我们点击获取所有权时发现不能解决问题。这里分享一种简单的解决方法。 打开虚拟机的文件目录 找到lck文件夹下…

【CSS】层叠,优先级与继承(三):超详细继承知识点

目录 继承一、什么是继承?2.1 祖先元素2.2 默认继承/默认不继承 二、可继承属性2.1 字体相关属性2.2 文本相关属性2.3 列表相关属性 三、不可继承属性3.1 盒模型相关属性3.2 背景相关属性 四、属性初始值4.1 根元素4.2 属性的初始值4.3 得出结论 五、强制继承5.1 in…

Android LiveData关键代码

1、observer方法 public void observe(NonNull LifecycleOwner owner, NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() DESTROYED) {// ignorereturn;}LifecycleBoundObserver wrapper …

Docker-高级使用

前言 书接上文Docker-初级安装及使用_用docker安装doccano-CSDN博客&#xff0c;我们讲解了Docker的基本操作&#xff0c;下面我们讲解的是高级使用&#xff0c;请大家做好准备&#xff01; 大家如果是从初级安装使用过来的话&#xff0c;建议把之前镜像和搭载的容器数据卷里面…

Spring Boot常用注解详解:实例与核心概念

Spring Boot常用注解详解&#xff1a;实例与核心概念 前言 Spring Boot作为Java领域最受欢迎的快速开发框架&#xff0c;其核心特性之一是通过注解&#xff08;Annotation&#xff09;简化配置&#xff0c;提高开发效率。注解驱动开发模式让开发者告别繁琐的XML配置&#xff…

TRO再添新案 TME再拿下一热门IP,涉及Paddington多个商标

4月2日和4月8日&#xff0c;TME律所代理Paddington & Company Ltd.对热门IP Paddington Bear帕丁顿熊的多类商标发起维权&#xff0c;覆盖文具、家居用品、毛绒玩具、纺织用品、游戏、电影、咖啡、填充玩具等领域。跨境卖家需立即排查店铺内的相关产品&#xff01; 案件基…

经验分享-上传ios的ipa文件

.ipa格式的二进制文件&#xff0c;是打包后生成的文件&#xff0c;无论我们是放上去testflight测试还是正式上传到app store&#xff0c;都需要先上传到苹果开发者中心的app store connect上的构建版本上。 在app store connect上&#xff0c;上传构建版本的功能&#xff0c;它…

docker(3) -- 图形界面

1. 前言 在wsl(8) – 图形界面文章中介绍了wsl2默认是支持图形界面的&#xff0c;现在我们尝试下在docker中运行gui程序试试看。 2. x11-apps 启动一个docker&#xff0c;安装一些gui小程序&#xff0c;然后运行&#xff0c;发现会失败。ubuntu_base详见文章wsl(6) – 安装d…

Docker容器跑定时任务脚本

最近搞了一个Docker容器跑脚本&#xff0c;想设置一个定时任务&#xff0c;每天8点运行一次&#xff0c;结果死活不成功。排查了一天&#xff0c;有一点当局者迷了&#xff0c;明明时间是对的&#xff0c;明明时区是对的&#xff0c;定时任务也是启动的&#xff0c;它就是不执行…

【Linux】什么是完全限定域名

FQDN 是 “完全限定域名” (Fully Qualified Domain Name) 的缩写。 FQDN 是一个互联网上特定计算机或主机的完整且唯一的域名。它详细说明了该主机在域名系统 (DNS) 层级结构中的确切位置。 一个 FQDN 通常由以下几个部分组成&#xff0c;从左到右依次是&#xff1a; 主机名…

小结:BFD

*BFD&#xff08;双向转发检测&#xff0c;Bidirectional Forwarding Detection&#xff09;是一种快速、轻量级的故障检测机制&#xff0c;用于检测网络中两点之间的连通性。它广泛应用于各种场景 1. 检测 IP 链路 应用场景&#xff1a; BFD 用于检测两台设备之间的 IP 层连…

配置Spark历史服务器,轻松查看任务记录

在大数据处理中&#xff0c;Spark是一个强大的分布式计算框架。但当Spark服务重启后&#xff0c;之前的运行记录就会消失&#xff0c;给我们排查问题和分析任务执行情况带来不便。这时&#xff0c;配置Spark历史服务器就显得尤为重要&#xff0c;它能帮助我们保存和查看历史任务…

(六)RestAPI 毛子(外部导入打卡/游标分页/Refit/Http resilience/批量提交/Quartz后台任务/Hateoas Driven)

文章目录 项目地址一、外部导入打卡功能1.1 创建实体1. Entry实体2. EntryImport实体3. 添加数据库配置4. 创建表 1.2 创建DTOs1.3 创建GetEnties Controller 二、游标分页2.1 创建所需要的DTOs1. 创建游标分页的请求参数2. 创建CollectionResponse3. 添加游标编码和解码的DTO …

Node.js CSRF 保护指南:示例及启用方法

解释 CSRF 跨站请求伪造 (CSRF/XSRF) 是一种利用用户权限劫持会话的攻击。这种攻击策略允许攻击者通过诱骗用户以攻击者的名义提交恶意请求,从而绕过我们的安全措施。 CSRF 攻击之所以可能发生,是因为两个原因。首先,CSRF 攻击利用了用户无法辨别看似合法的 HTML 元素是否…

Flink介绍——实时计算核心论文之Dataflow论文总结

数据流处理的演变与 Dataflow 模型的革新 在大数据处理领域&#xff0c;流式数据处理系统的发展历程充满了创新与变革。从早期的 S4 到 Storm&#xff0c;再到 MillWheel&#xff0c;每一个系统都以其独特的方式推动了技术的进步。S4 以其无中心架构和 PE&#xff08;Processi…