让人非常easy误解的TCP拥塞控制算法
正文
非常多人会觉得一个好的TCP拥塞控制算法会让连接加速,这样的观点是错误的。恰恰相反,全部的拥塞控制算法都是为了TCP能够在贪婪的时候悬崖勒马,大多数时候。拥塞控制是减少了数据发送的速度。
TCP拥塞控制的终极目标绝对不是加快数据发送的速度,这样的理解非常自私且肤浅!它的终结目标是在公平占有带宽的前提下无限度提高带宽的利用率!
假设你仅仅关注一个独立的TCP连接本身,那么你或许永远都不可能设计出什么比較好的算法,但假设你不从一个独立的连接入手,貌似更加虚无飘渺,毕竟你能拿到且驾驭的仅仅有一个连接!
考虑一个进程调度器的设计,从2.6.23開始。大家普遍觉得Linux调度器迎来了一个新的阶段,即CFS阶段,相比之下。O(1)调度器仅仅像是一个过渡,而之前的O(n)调度器就略显0基础了。当时我也关注了这个新调度器好一阵子,正如我这段时间关注TCP BBR一样...So,我们来看一下CFS究竟好在哪里,以至于它能够占领Linux默认调度器这头把交椅。
首先我们反问。CFS让进程执行的速度更快了吗?非也,有点经验的都知道。对于追求高吞吐的环境,CFS反而让进程执行的速度更慢了。比較肤浅的认知角度,一般非常easy将“好”和“快”紧密联系在一起,但事实上。站在更高的层次。你看到的将不再是一个独立的进程,而是一整机器里面全部的进程!
CFS究竟好在哪里?
从其名字上就能够看出,其优点在于“全然公平”!
它治疗了O(1)调度器中差点儿全部的不公平调度导致的症状。比方IO消耗型与交互进程之间的抢占与饥饿问题,比方调度粒度问题。等等全部这些问题,引入一个虚拟时钟后。公平性得到了非常精确的度量。这些问题终于得到了解决。
从開始到最后,没有不论什么独立的进程“被加快了执行速度”!
终于,CFS让全部进程在公平持有CPU时间的前提下,让CPU尽可能满负荷运转,即提高了CPU的利用率。整个过程没有毛刺,非常平滑。
----------------------------------------------------
间中,我们来看看平滑取代毛刺的优点,眼睛仅仅要直视就是那么的帅!《德国佬又火了!奥迪终于把球形轮胎造了出来…》!
----------------------------------------------------
如今回到TCP本身,BBR和当年的CFS一样,引起了众人的关注。我想我已经引出了“怎样设计一个好的TCP拥塞控制算法”的思路了。
站在全球互联网上空往下看。你看到的是全部的TCP连接,而不仅仅是你的机器上建立的那一个或者那几个。
这就是格局不同,你的偏见自然也就消除了。上海自然要和北京竞争。但北京不这么看,不管哪里好了,都是它北京的,不是吗?怎样让全部的TCP连接公平共享全部的互联网带宽,是TCP拥塞控制算法的根本!注意两个关键点,其一。公平地共享,其二,尽可能全部的带宽。
这个问题是一个世界难题,没有进程调度器那么简单!
进程调度器是作用于一个CPU的。或者简单点说,作用于一台机器。
这台机器就在你的手上。你,也就是调度器的设计者全然能够看清楚当前机器里发生的一切,一切不公平症状,一切浪费现象能够让设计者尽收眼底,你能够强制性拿一个进程的资源给予还有一个进程。你也能够杀死过于贪婪的进程...对于TCP而言,根本没有一个能够站在全球互联网往下看的高人,TCP拥塞控制是全然分布式的,每个设计者都仅仅能看到自己机器上的那一部分连接。
然而,TCP拥塞控制之所以如此难并非什么所谓分布式导致的。事实上分布式一点也不难,难点在于TCP拥塞控制总是被误解。所以说在设计算法的时候。稍不留神就会南辕北辙。本来是避免拥塞的,实际上是添堵的。
为什么会被误解?事实上凯撒早就说过,人们总是看到自己希望看到的。
这句话还有还有一层意思,人们乐于把自己看到的局部当成全部。
人们能够一眼看到一整机器的进程。所以设计出一个好的进程调度器是非常easy的,所以CFS出现了。可是大家看不到全部的TCP连接。大家看到的仅仅是自己的TCP连接,所以大家仅仅能臆測,我好。你也好。至于算法是否添堵,可能全然不是出于恶意,而全然是目光的短浅和格局之不高导致的。
一个正确的,且好的TCP拥塞控制算法应该是顾及全部的连接的,假设TCP不够快,那就应该让全部TCP都提速,这点体现了带宽利用率的提高。假设TCP已经足够快。那不论什么连接都不能更快,这点体现了公平性。
换成人话非常简单。假设你觉得开车走省道慢,那就上快速,假设你已经在快速公路上,请不要变道超车。
多么简单的道理,可还是能看到道路上变道超车的,我可能表达有问题,是全部的司机都在玩变道超车,假设让这些人来设计TCP拥塞控制算法,会好到哪里去呢?不幸的是。世界上TCP单边加速玩的最火的那批人,和这批中国好司机是同一批人,不管什么资源,唯一的目标除了抢,还是抢。
事实上。我并非一个道德说教者。说什么人人为我,我为人人的算法才是一个好的算法,说的就好像我自己做到了似的...
我是被两位大师骂了才知错就改了。事实上我也走火入魔过...
前一段时间吧。我改动了一个拥塞算法。呈给一位大师评解,姑且叫大师1吧。值得"炫耀"的就是我这个算法非常快,甚至比BBR还要快,可是被恶损了一顿,我的算法“竞赛肯定第一”,可是却“不负责任”...这样的是毁人品的算法。后来,我试着让两个或者多个执行同一个算法的流一起数据传输,果然...一些流会瞬间把剩余的流带宽压榨到0!连敌友都不分了,简直就是流氓算法啊!
这个算法从此也就阅后即焚了,全然不可用。
...
假设这还不算,那么还有一位大师2则彻底让我觉得自己根本就狗屁都不懂。
这位大师在国外,跟我有时差,且能读中文但不写中文,我与之相反。我是能读英文但写起来费劲。所以仅仅能邮件交流。
主题还是拥塞控制。我由于急功近利仅仅是问了“怎么让TCP数据发送速度更快”这样的问题,答案非常简单。忽略拥塞控制并补偿性重传即可。然后我就写了一个“忽略拥塞控制的拥塞控制算法”。而且挑衅般的作为回应。然后的邮件里就出现了fxxk词汇,还有suck...说我根本就不懂主要的原则,并力劝我辞去工作回家细致学习和思考。
我都快哭了。
...........
大师2的教导在大师1之前。可是大师1给了我详细怎么做的方向和方法。我除了发自内心的感谢之外,能做的就是写一些“抨击TCP拥塞控制算法”的文章来把人人为我,我为人人的基督教理念传递给很多其他的人。
出于对两位大师以及各路朋友的尊重,我不会贴出与之相关的代码,邮件原文以及聊天记录。消化加工后的理念,由我这里直接始发。
BBR
本文的最后,我通过BBR算法略微聊一下什么样的算法是正确的算法。BBR和当年的CFS一样,这个我已经说过了。可是BBR眼下仍处在比較0基础的阶段,起初呢,我觉得它的问题在于:
1.收敛太慢,即不会即时降速降窗。而是要在几个RTT内完毕;
2.向上探測太迟。难道问题1是对这个的补偿也说不准;
3.大BDP缓存下的抢占性有待商榷;
4.BBR依托的SDN基础设施...
...
能够看到,这样的最初的领悟体现了我个人多么深厚的技术功底。然而后来。经大师指点,我才发现。原来BBR的最大问题在于,它引入的新拥塞控制框架非常easy被误用,详细的请參见http://blog.csdn.net/dog250/article/details/54754784
假设几个三流的比我还差的人使用新框架写算法,那么互联网崩溃指日可待。幸运的是。即便崩溃,也仅仅是国内的互联网崩溃,在这个领域,国外的月亮就是圆的,毕竟人家比我们受教育程度更深。懂得博弈理论。即便从自私者的角度来看。损人不利己的事情也是做不来的。
值得注意的是,有知识不代表有文化。我一直觉得国内的大学事实上就是技校,特别是华中科技大学。差点儿是定向给华为,BAT等巨头培养高级技工的。
回到BBR。对于BBR带来的新框架,最严重的是,之前有人拼速度拼重传的时候,会有prr降窗。这点是不受算法模块控制的。如今好了,直接写个回调,全然绕开了降窗。大家都去添堵去了TCP设计的原则层面,RFC里貌似也把公平性提到了至高的地位。由于假设不把公平性作为基本原则。那么整个环将不是闭合的。带宽资源早晚会用尽,此时盲目的AI非MD过程将会促使大家都想往前抢,最后谁也过不去,如此一来。互联网将全然不可用!基于这点。全部搞“TCP单边加速”的个人和厂商都是在做钻空子的坏事,其出发点就是错误的。
当然。这类厂商的出发点往往不是TCP层面的。而是业务层面的,这倒是无可厚非。毕竟不是一个领域,我也无权过问太多,TCP对于它们而言仅仅是工具。真到哪天互联网崩溃了。他们还是会用卡车运硬盘的方式来进行数据传输的,到时候,快速公路上堵的水泄不通的运硬盘的卡车与TCP一样,也仅仅是个工具,而已。
----------------------
怎么样的做法是正确的呢?
先来介绍一个君子算法,即LEDBAT算法,能够看看http://www.rfc-base.org/txt/rfc-6817.txt,其wiki是https://zh.wikipedia.org/wiki/LEDBAT
它的思想在搞“加速”的那帮人看来,事实上有点搞笑。它的存在是为了填补CUBIC之流不Bloat Buffer时候的空隙的,一旦有其他流量造成了排队,LEDBAT立即腾地方退让。这样的算法是应该被“加速者”第一时间抛弃的算法,可是它在iOS和Win10里却大行其道,LEDBAT主要用于软件更新,这样的事一般能够在后台默默进行。优先级比較低。所以发明一个后台静默的君子式LEDBAT算法。实则是在提高带宽利用率上无所不用其极啊。然而这个算法又不会跟其他的流量争抢带宽,丝毫不会应该高优先级流量的公平性,难道不是非常帅的算法吗?LEDBAT在表达的是,你们去前面堵着去吧,我没你们重要,我慢慢走即可。。。
BBR不是君子式算法,它是要參与公平竞争的,我不主动欺负人。可是被人欺负,我不会怕事的。因此BBR在LEDBAT上添加了Probe More的过程。同一时候,与LEDBAT退让不同,BBR将其改成了轻柔缓和的Drain Less。
全部这些都不是近期刚刚出现的,在此之前,Vegas算法则代表了一种正确的做法,它终于没有上位是由于Vegas部署有个前提,那就是同一时间全部部署成Vegas,然而这是不可能的。仅仅要有Reno或者CUBIC在,Vegas的“正确做法”就会吃亏。
现实就是这样,劣币驱良币。CUBIC明明是错误的算法,但由于它能够利用率非常低但非常简单的方法快速收敛到可用带宽,所以就一直是大家认可的算法。全部人都在默默忍受着Bufferbloat,而这个问题带来的额外排队延迟会大大减少交互式TCP连接的交互体验,同一时候严重影响实时性的协议。比方NTP之类。
CUBIC是一定会堵路的,Buffer被堵了之后。交互应用的数据就会被排队,时延添加,交互性自然下降。
我一直好奇的问题是。为什么Reno。CUBIC之流在经过慢启动之后的AI增窗过程叫做拥塞避免,相反,这样的盲目的一路走到黑的增窗方式一定会导致拥塞的,即拥塞不可避免。这个过程是玷污了“拥塞避免”这个词呢,还是说仅仅是一个定义呢?以下的一篇文章给出答案,如今的时间是周六早上7点半,该睡一会儿了。
写在最后的序:
“昨夜入城市。归来泪满襟”的那是傻逼,自己不养蚕便是了,干嘛妒忌别人穿丝绸。今天又是周末。又能够半夜起来折腾,本文写作開始于五点半,完毕于早七点二十,在此之前,我花了一个小时时间读了《卢比孔河》之25页。再之前的一个小时。我看了一些关于道路规划的东西。主要在令人不安的电脑上...如今,本来我想睡一觉,然而睡不着。就想去登高望远。仅仅可惜旁边的山都太矮小了...自从甘孜归来,深圳的山就成小土堆了...实际一点。去买菜。做饭才是解决之道。做什么饭呢?哈哈。重庆带来的老火锅!
----我希望你能看到这篇文章。