杭州待了一段时间,回到深圳过国庆假期,无奈温州皮鞋👞厂老板过节要回温州和上海,不在深圳,也就没有见着,很是遗憾!html
国庆节当天,就写这个了。经理不会弹琴,可是经理会弹琴。web
我本来可能会在想国庆节的凌晨到大清早写点什么呢,如今不用想了,就写BBR拥塞控制算法背后的数学吧,这个事情我是在杭州回深圳的路上忽然找到了最终结果的,我必须把它记录下来。其实在找到这个结果以前,好久好久,我就在思考这个问题了。算法
2016年大概十月中下旬,同事推荐了一个视频:
Making Linux TCP Fast:https://www.youtube.com/watch?v=hIl_zXzU3DA
跟随视频后的连接netdevconf的连接,还有一些slides和paper能够看:
https://netdevconf.org/1.2/session.html?yuchung-cheng
我也是那时,或者更早些一点,大概九月份的时候,接触了Google的BBR算法,应该算是国内第一批次的了,随后的一段至关长的时间,我对该算法进行了相对深刻的剖析以及思考,从解释Paper,分析源码,设计到优化,反正不知花了多少周五的通宵。数据库
随着后续这个BBR算法的逐渐普及,加入讨论的人也愈来愈多了,从最初的如何用起来到后面的各路大神的各路神技,可谓热闹非凡,我当时讲,TCP被大家玩坏掉了,BBR也难逃劫难…缓存
和CUBIC背后那精湛简介的数学收敛模型不一样,BBR是基于测量的一个算法,它甚至没有一个数学上的解释以证实 为何这样作就是最好的,以致于,不少人开始盲改,最终的效果和本身的预期,固然是截然不同。网络
我一直在思考BBR背后的数学,我总以为能用数学公式表达的东西才是真正肯定的,因此我但愿在我长时间思考后,能有一个数学上的解释,来解释BBR为何是高效率的,为何只能这样作。session
这几天,我感受成功了一点,因此不敢独享这回报,写此文以分享。app
先来个插曲。ide
不少人看到BBR不排队的特征后,第一想到的就是 不排队甚好,但稍微在缓存队列里堆点数据包也不错,否则怎么能赢了那些不守规矩的流呢? 因而乎就出现了各种所谓的 BBR优化,无一例外地都是把Reno/CUBIC那一套算法的 精髓 照搬到BBR,因而BBR就被玩坏了!svg
我也干过这种事,后来我跟BBR的做者Neal Cardwell交流,他告诉我 这增长了算法的复杂性,而且破坏了BBR的根本。
…
我退出了 BBR优化队伍,我也不玩了,我潜下心但愿能 从数学上证实BBR不排队就是最优的,只要排队就不行,一点队列也不行。本文写做前一天,我得了一些结论。记录这些结论并记录我是怎么想的,就是本文的主要内容。
温州皮鞋厂老板促使我开了场,让我第一次用数学来描述BBR算法。
当时是要计算一下 ***为何BBR在Startup阶段的gain是
***,详情看这里吧:
TCP BBR Startup gain计算总结和Startup失速问题:https://blog.csdn.net/dog250/article/details/80780346
如今,正文开始。
先说一下个人思路,因为我自从中学开始就是一个深度的数形结合控,但愿能把一切都画在一个坐标系里,而后无非就是找最高点,最低点,找规律这些了,所谓求极值,展现特征无非也就是那些惯用的方法, 求导,积分,数列展开这些,因此对于BBR算法,我依然循着这样的思路。
如今要作的,就是怎么把BBR的行为画在一个坐标系里。若是这一步作到了的话,我相信以我20年的经验顺水推舟事情就必定能成。
其实,BBR最初的slides和paper中,不断展现的图示是下面这个:
而后,我仔细观察了这两个坐标系,分别是BW(实际上是Deliveryrate) vs Inflight以及RTT vs Inflight,都有Infligh。其实,这两张图是用于展现BBR特征的,它只说了What,并无解释Why,实际上,难道Inflight不该该是 计算出来的 吗?若是说我能根据另外一个坐标系的曲线进行一系列计算,最后 推导出Inflight的值必须是那个值才能达到某种最优的效果,那就解释了Why。
就是这个思路。让咱们一步一步去作。
既然咱们把Inflight当成了一个结果而不是缘由,为了找这个缘由,咱们合并两个坐标系,消去公共的Inflight,那么咱们就能够获得RTT vs BW的曲线了!
为了数学上表述的方便,后面统一一下符号:
BW:
RTT:
Inflight:
临界的Inflight:
下图是消去
的方法:
首先给出图像的方程表示:
很简单,方程组联立就能够消去变量
。
咱们能够看到,最终 和 的取值范围就是那条开向第二象限的折线,如今的问题是,在这条折线中, 在哪里是最优的,而此时的Inflight值就是最适合灌进网络中的数据包的数量,换句话说,它反映了Cwnd应该取什么值。
问题转化为了 如何度量所谓的最优 。
通常工业界和经济学领域都会采用 ***产出/成本***的比值来衡量一个系统是否是优秀,换句话说就是 最优的系统是用最少的代价换取最高的收益。对于咱们目前的模型而言,用语言来表达,即 最少的时间传输最多的数据包。
所以,很显然,我给出下列的比值,最为衡量系统是否最优的度量:
问题变成了 P(w,t)取在哪里,上述的比值E最大?
肉眼看得出来, 取最大值 , 取最小值 便可,即取点 ,所谓的最优的 值就是 ,而此时,Inflight的值就是所谓的
这确实说明了Inflight取值为临界的刚好要使得队列增长的
时,系统的效能真的是最优的。
若是你将 在容许的定义域值域稍微偏离 点,你会发现 值均会减小,这反映在TCP数据传输上,就是:
不管发生了上述的什么状况,显然都不是什么好事。
这算完成了任务吗?证实了BBR是最优的。看起来算是吧…
若是这样就算是一个BBR背后完备的数学模型,这篇文章一个多月前就能写出了。。。
咱们发现,上面的推导基于一个明显的事实,即 用肉眼看,之因此能够用肉眼观测出最值,那是由于Yuchung Cheng和Neal Cardwell在描述BBR算法时,简化了模型,基于简化的模型,才给出了那两幅BW vs Inflight和RTT vs Inflight的坐标图示,在这两个图示中,全部的线均为直线。
所谓的简化模型,即假设数据包是间隔均匀匀速到达的,数据包也是匀速通过网络节点设备的。可是在实际上,这并非事实,真实的状况画在坐标系里并非直线,而是曲线,相似下面的样子:
此时若是咱们依然要求解
的极大值,很显然要求这条曲线函数
针对
的导数,这下麻烦有点大!我怎么能知道带宽
和传输时间
之间的关系呢?显然,必须有两者之间的关系,才能求导啊!
怎么办?这件事让我搞了一个多月时间!
我能理解数据包的到达实际上是柏松到达,被服务时间符合指数分布特征,可是我并无就着这个思路思考下去(否则我必定能想到排队论),而是但愿能先有一个通用的解。
起初,我是反着求解,我假设传输时间
已经能够用带宽
来表示,即
而后,就会有:
进一步按照求导法则针对
求导,推导以下:
若求
的极大值,那么它必定出如今曲线的拐点处,其导数必定为
,所以:
这即是最终的关系式,虽然我不知道 如何用 来表示,但这个关系是存在的,这是个广泛适用的关系。
我为获得这个关系式兴奋了一个周末,很是有成就感,虽然它如今看起来很简单,但在当时,这个想法真的显得来得太晚!
我是从初中开始就喜欢摆置坐标系的,一直到大学,几乎任何数学题,我都能采用数形结合的方案一题多解,某种程度上,我老婆就是当时我如此炫技追到的…最近几年,我用一样的方式设计了iptables的优化方案,DxR的优化方案…很少的几回失败包括Bloom Filter的形象化展现。
因此面对上述的表达式子,依然能够任意把玩。式子两边同时除以
:
看看左边右边分别是什么?
两个斜率一致的时候, 取值计算的 是最优的,即 曲线 上任意一点 和原点之间的直线与该点的切线共线! 的时候,该点 的 和 的取值为最优!
形象地看,咱们能够经过 操做 来获取最优的点,即:
从通过原点的t=0这条直线开始,任其绕着原点逆时针旋转,第一次切到曲线
的那个点,就是最优势。
很简单,是吧。
如今已经定性地把问题解决了,不管曲线 长什么样子,咱们能够从上述的操做步骤中获取最优的 点,进而求出Inflight值,最终肯定Cwnd。
然而,这并不能定量地分析,若是要定量地分析,则必需要有 的表达式。
这个表达式何来?我花了好长时间也没有思路。
再仔细看看带宽和RTT之间的关系,在固定的带宽下,RTT受到Inflight的影响,然而Inflight正是咱们要求解的,这貌似进入了一个循环,消除Inflight变量并没有法肯定两者的关系,这即是陷入了两难!
…
我略过了好多文字,这些文字描述了大概将近一个月的见闻,而后我就想到了 排队论, 排队论, 排队论, 排队论, 排队论!
排队论基于几率理论给出精确的逗留时长和到达率以及服务率之间的关系。
排队论是一个复杂的理论,能写几大部头都写不完,我本身也只是略懂一二,并非专门研究这个的,因此本着解决手头当前问题的广度优先原则,下面我依据排队论的一些结论性的公式进行推导,关于这个公式的推导,我会在本文后面给出一个附录。
咱们依然根据最简单的状况创建模型,即经典的M/M/1排队模型下的场景,在该场景下,先设如下的变量:
而后,有一些用到的定义以及公式,咱们根据这些公式来进行后续的关于BBR最优化的证实。须要声明的是,M/M/1排队模型是一个简化的模型,并不表明现网中运行BBR算法的TCP传输发包特征就必定符合这个模型,但这是一个很好的开始。
这些结论性的定义和公式以下:
有了这些,即可以创建BBR的模型了。
在一个带宽固定的网络中,咱们假设带宽为 (基于这种固定带宽的假设,实际上这是M/D/1排队模型,可是推导过程并没有伤大雅!),而咱们发送的带宽能够理解为 到达率, 即 ,此时咱们能够把 等效于RTT,所以RTT和带宽的关系则为:
根据咱们上面的那个最优解公式:
带入则有:
而这里的 则能够对 简单求导:
代入则有告终论:
最终,咱们发现了最有点 ,即:
这个结论有什么用呢?它意味着什么呢?
咱们再来看M/M/1模型中的另一个公式,即计算当前系统的用户数:
这意味着系统中只有一个用户,这意味着没有排队!!这意味着最优的状况,即 最大的时候,系统是没有队列堆积的!这个时候,咱们来计算一下BDP:
正解于天下!这也是我在这方面工做的一个里程碑,如今总结一下就是:
在M/M/1排队模型的假设下,BBR拥塞控制算法是效能E最优的。
然而,M/M/1模型只是一个开始,事实上,基于端到端的TCP协议,在链路上会通过很是多的中间节点,即,至少起码的,咱们也要在M/M/k排队模型上再次证实上述结论的正确性才行。
而这是简单的。
咱们假设一个端到端的链路上有 个中间节点,那么每个节点都遵循M/M/1排队模型的法则,综合起来就是M/M/k了,咱们假设这些节点的处理能力并不相同,并假设其中有一个能力最弱的节点m,其处理能力 ,在排队论模型中,只要有排队现象,就会增长时延而下降效能E,因此为了避免排队每个节点的到达率均要知足: ,因此最终的系统中的用户数是要小于 的,这就是说,系统的吞吐是由最弱的节点决定的这个典型的漏桶理论。
咱们来看BBR的名称,Bottleneck Bandwidth and RTT,其中以 Bottleneck Bandwidth 为M/M/k排队模型的依据保证了RTT不会由于排队引入的延迟而增长。
换句话说,BBR拥塞控制算法告诉你,别发太多包,超过Bottleneck Bandwidth的限额,你多发了也过不去,还平添时延,由于已经偏离了最优的操做点!
算法是OK的,表明了一种正确的方法,退一步,至少能够说是一种引向正确方法的趋势。然而在实现上,它的根基在于 测量的准确性。算法实现的具体实施过程当中,TCP协议固有的不可测量性是最大的掣肘,而这是TCP的固有缺陷所致使,永远也没法被解决!
那么QUIC的实现呢?我准备花大力气测测看。
在很早以前介绍BBR算法的文章中,我提到了 带宽和RTT互为正交 的概念:
Google’s BBR拥塞控制算法模型解析:https://blog.csdn.net/dog250/article/details/52895080
如今咱们能够基于本文上述的关于最优化的结论再来理解这个 正交。
先从固定的D/D/1排队模型看,咱们再看BW vs RTT图:
咱们能够看到最优势
处,带宽和RTT的乘积正好是矩形的面积,而它就是BDP,不管你在折线上怎么移动
点,你均没法得到更大的矩形面积,往左移动,面积减小,这意味着不够,效能固然低,往上移动,面积再也不增长,这说明多发数据包也没用,并不能增长有效BDP。
好完美的既视感!貌似打消了任何企图经过多发包来提高性能的念头,然而忽然发现这只是理想D/D/1排队模型下的结论。
稍微真实点的M/M/1排队模型下,是这样子的:
你会发现,在最优化点附近,仍是能够 经过比较小的RTT增长的代价,得到更多有效BDP的。这彷佛给了人们稍微增长一点Cwnd以理由和意义。黑暗压下来的时候,老是留下一丝的光亮,没有办法。
经过相对严格的数学推导,咱们发现BBR算法在BW vs RTT坐标系的曲线上的操做点确实是最优的,然而咱们又从一样一张图的M/M/1表述中发现了一点能够利用的Trick…
无论怎么说,不想排队是为了本身,然而制造排队则是毁了你们,你能控制的,仅仅是本身不排队,这是个博弈,答案却很是简单!
如此简单的数学推导,展现了事实,那么,为何路由器和交换机还要设计队列缓存呢?
从商业的角度,现在的存储设备愈来愈便宜,更多的缓存能够换取更多的 不丢包指标,极低的代价换一个噱头。
从工程的角度来看,队列不只仅是 为了缓存多出来的数据包,更多的是一种主动式的管理设施,好比流量整形,按照不一样的产品进行限速,优先级管理等等。
最后,从数学上看,假设数据包到达行为是泊松到达,其到达率指望是 ,那么为了得到最佳的效能,其服务率必然是 ,可是这些都是统计分布,到达率的指望只是一个均值,在可计算的几率下,到达率彻底能够达到 , …为了吸取这些统计峰值,则必须设计队列缓存。
如今的问题是转发节点设备上的缓存要设计多大?有了BW vs RTT这张图,这是能够计算出来的!
咱们依然假设这个模型是简单的M/M/1排队模型。我将D/D/1模型和M/M/1模型放在一张图里解释:
虚线和橘黄色真实的实线围成部分的面积就是节点须要的缓存的大小(事实上要稍微大一点,毕竟这里的RTT也是均值),由于它在泊松到达的正常波动范围内。
此外根据本文上面的推论,当
的时候,系统的效能E最大,在上图中,这也是能够解释的:
其中蓝线围成的区域面积为 最佳的BDP,这个是和D/D/1模型不一样的。
因为泊松到达的统计效应形成了不可避免的排队和空转,且两者不能抵消,所以必须设计缓存队列,曲线相对 往上下凸了,所以从原点出发相切于 的切线确定在 的左边,这意味着相对于D/D/1模型,M/M/1模型在其它条件都相同的状况下,损失了一点Inflight!这是统计的不肯定性带来的不可消除的代价!
因此说,在非主动管理的意义上,队列的做用是什么?队列的做用是,平滑泊松到达的统计特性引起的突发。突发老是存在的,为了能容忍这些突发, 而不至于丢包。
从示意图上看,即使是BBR,也是没法100%避免排队的,这是泊松到达的统计特征决定的,即使单一服务节点的服务率 是到达率 的1000倍(而不是计算出来的最优值2倍),也会有小几率的突发会形成轻微排队。故而,队列算是一个基础设施,必不可少,但你要明白,队列是用来干吗的!
然而,还有一个话题,与统计突发几率相等的对称的现象就是系统空转,而空转是没法弥补的,没有任务到达,系统确实什么也作不了。所以,引入主动队列管理是必要的,上一时间周期来不及处理的任务经过缓存队列推迟到下一个时间周期,填补空转期,这方面,我以为带突发的令牌桶这个设计,简单又直接。
1980年代的拥塞崩溃致使了1980年代的拥塞控制机制的出炉,某种意义上这属于见招拆招的策略,针对1980年代的拥塞,提出了1980年代的拥塞控制算法,即ss,ssthresh,congestion avoid这些。
说实话,这些机制完美适应了1980年代的网络特征,低带宽,浅缓存队列,美好持续到了2000年代。
随后互联网大爆发,多媒体应用特别是图片,音视频类的应用促使带宽必须猛增,而摩尔定律促使存储设施趋于廉价而路由器队列缓存猛增,这即是BBR诞生的背景。换句话说,1980年代的CC已经不适用了,2010年代须要另外的一次见招拆招。
若是说上一次1980年代的CC旨在 收敛,那么这一次BBR则旨在 效能E最大化,这里的E就是本文上面大量篇幅描述的那个E,至少我我的是这么认为的,这也和BBR的初衷 提升带宽利用率 相一致!
插个形象的gif,来自一篇blog:TCP BBR congestion control comes to GCP – your Internet just got faster
本文该结束了,国庆节假期第一天我实在是想出去逛逛,可是又能去哪儿呢?
刚到杭州的时候,有次出去逛,和技术网友聊天,说到了数据库和网络。我是不懂数据库的,一点都不懂,可是我知道,数据库和网络是两个一样极为重要的领域,我作了一个比喻。
网络是道路的话,数据库就是家,道路是要快速经过,越快越好,不要逗留,而家则待的越久越幸福。但是现在呢?城市道路是愈来愈堵,基本成了条状停车场,而人们在家的时间则是愈来愈短,到底发生了什么?这是否是和网络节点转发设备的队列缓存愈来愈大相一致呢?
然而,这是错误的!
我就不说Kafka了,那真是一个优秀且正确的设计。本文真的要结束了,附录中,我会给出关于M/M/1排队模型中一些结论的简单数学推导。
排队理论是一个很成熟的理论,介绍它的资料可谓汗牛充栋,若是想简单了解一下概念,那么Wiki老是一个好地方:
https://zh.wikipedia.org/zh-hans/等候理論
强调一句, 排队理论是现代分组交换网络的根基,记住,它是根基,若是没有这个理论做为支撑,基于 统计复用 构建的分组交换网的可行性都没法获得验证!!
即使它如此重要,也并不能阻碍它的鲜为人知。
本附录,我仅仅给出一个基于简单通用的M/M/1排队模型而构建的系统中,稳定状态下用户数量的推导,旨在开个场。
咱们假设一个单一的服务节点,它的队列容量是无限的,那么它可能存在于下面状态中的一种:
状态 表示有 个用户在系统中。
上述的状态根据到到达率 和服务率 来相互切换,好比当前系统排队 个用户,那么在 的时间间隔到达一个用户,系统随即切换到 个用户排队的状态,画成一个链,即:
这个系统若是是可用的,那么它就必定会进入一种所谓的稳定状态,稳定状态的特征是,进入单一状态 的几率等于离开该状态的几率,即:
这就是平衡方程:
上面的式子是核心中的核心,由于若是系统未达到一个稳定状态,那么系统将可能朝着两个方向发生雪崩:
因此一个可用的系统,它是平衡的,咱们基于上述的平衡方程作递推,可得解:
其中 ,所以上面的解等价于:
如今让咱们计算系统中的用户数,包括排队的用户数和正在被服务的用户数。
记系统用户总量为 ,一个显然的道理就是,系统中的用户总量等于各个状态与之几率的求和:
这就是结论!
其实,根据上述的状态转换平衡方程,以及泊松到达,马尔可夫模型,全部的排队论结论性的公式均可以推导出来,也是很是简单的,除了几率论以外,几乎没有任何前置知识,然而,它的结果却能够解释那么多好玩的事情,真的是很是棒。
关于排队论的应用之普遍,其实怎么说都不为过,我在今年6月份写过一篇关于排队spinlock优化的文章:
从CPU cache一致性的角度看Linux spinlock的不可伸缩性(non-scalable) :http://www.javashuo.com/article/p-xaxwkioc-gv.html
里面提到的马尔可夫链式模型就是排队论的一个典型,很是好玩。此外,咱们平常生活中的各类等待,开车时的各类拥堵,以及像某大型互联网公司的晋级晋等,均可以用排队理论进行建模和分析解释。
浙江温州皮鞋湿。 湿鞋皮州温江浙。