网络拥塞控制(十) 总结
也是总结的时候了,写完了TCP的多个经典的拥塞算法,但是由于这方面的优化算法还有很多,没办法能够一一讲完,所以下面对其他的一些比较典型的也进行一个简单的介绍:
Fast TCP: Fast TCP由于后来没有对开源界做贡献了,因为作者本人自己创办了公司,把Fast TCP变成了商业产品,所以后续的学术研究就比较少了。Fast TCP是从TCP vegas的思想发展而来,利用网络延时进行拥塞判断。之前讨论过,基于延迟的算法是对整个网络的拥塞控制有好处的,但是和当前的基于丢包的算法来说两者不公平。所以估计作者后面也做了很多的改进。
ECN:显式拥塞通知,该算法的思想是想借助路由器,因为拥塞的状况中间的路由器是最清楚的,所以让路由器在发现有拥塞现象时在连接的TCP或者IP头里面打上拥塞的标记,让终端自己去根据标记进行处理。这种思想需要中间所有的路由设备均能支持才能在整个广域网上使用起来,所以推广起来不是那么容易的事情。目前Win7、Linux均都已支持ECN标记的处理。
UDT:UDT是一个开源的基于UDP实现的可靠传输协议,对于想知道如何去实现一个可靠的传输协议可以说值得参考。严格地来说UDT没有对TCP进行优化,不能算是一种TCP的优化,但是在UDT里面实现的拥塞算法是和UDP或TCP没有关系的,UDT采用的是一种带宽估计的算法,在利用包对进行带宽的探测,然后由接收方把估计的带宽反馈到发送端,发送端的拥塞算法就是把拥塞窗口利用一个函数无限逼近于带宽值,这种思想对于传输的稳定性非常好,因为是一个无限逼近,所以永远不会超过带宽的值,而不是像TCP一样在平衡状态后继续一直往上增大窗口,从而在平衡状态能够维持比较久。但是缺点也显而易见,带宽的估计不是特别的精确,尤其是在小带宽环境和有丢包的环境下误差有点大,当然我们需要明白作者开发UDT的需求不是为了小带宽和丢包环境的。
很多人都会有一个初步印象就是实现一个类TCP看上去都会是一件很容易的事,不就是加上连接机制,重传机制,定时器机制,序列化机制等就可以保证TCP能够工作了,download点开源的各种实现或者Linux内核,很快就可以改造出一个自己可用的版本出来。没错,一个可用的TCP实现确实就这样完成了,但是一个可用的版本和一个高性能版本的TCP实现那差别就远的很了。该系列的文章已经从TCP的发展进行了描述过逐步引发的一些问题,下面再列举一些问题来说明:
1. 对各种网络环境的适应能力。现在的各种网络环境都存在不一样的特征,例如有高达Gbps的网络需要超大的传输能力,家用ADSL的小带宽需要保持稳定吞吐能力,卫星网络/跨国网络有着很大的延时和一定的丢包率,3G存在异构的网络,跨运营商的网络有着很大的丢包率(主要是在中国的跨运营商之间),等等,这些不同的网络环境对TCP算法的挑战性非常大。
2. 对不同应用的适应能力。有数据备份应用需要大量的文件传输,有对交互延时非常敏感的如RDP/Citrix/网游等应用,有一直只发送小包(发送的包长度小于MSS)的应用,也有不停的发送大包的应用,还有两边同时发送和接收数据的应用。而一旦实现的不好,就有可能对某些传输应用效果很好,但是对某种特殊的应用就很差,例如TCP的Nagle算法,ACK回复机制,如何控制突发性,重传算法等。曾经我就碰到过很多这种问题,因为多传输了一个包导致多回复了一个ACK,最终造成性能下降1/3,因为突发(尤其是重传时的突发)没有控制好导致500-600KB的带宽却也只能达到100KB的性能。
3. 对连接的友好型和抢占性。1条TCP连接是否能够有利用完整个带宽的能力,同时上万条连接并发是否有能够足够公平友好,从而充分利用带宽,而不是造成带宽的浪费?否则某些连接速度是快了,但是其他的连接速度就降下来了。同时抢占过重导致网络中延迟变大,从而交互性应用体验性非常不好。
上述这些问题,把TCP各种机制融合成为了一个整体,任何地方一个小小的改动可能会造成整体性能急剧的下降,测试的工作量也是一个非常复杂的工程。为了解决这些问题,对于TCP的优化的算法已经多达二十多种,包括公开的、私有的或者专利化的,在维基百科上都可以看到这些算法的列表。
要解决上述各种问题,已经不是简单的拥塞控制对拥塞窗口进行调整可以解决的,需要结合很多其他的方面的信息,例如:
1. 最重要的是要提高重传数据的准确度且尽快地重传已经丢失的包,这两者看上去本身有点矛盾,因为要尽快地重传就有可能造成误判,错误的重传反而浪费原本宝贵的带宽资源。我尝试过给在丢包环境下每个包都直接重传两遍,这样相当于非常早的进行了重传,但是效果却还不如判断后再重传。
2. 发送数据的平稳性,很多小带宽的网络不能突然间发送过多的数据包,否则很快就会把网络再次陷入拥塞,导致速度比小流量的稳定发送更慢,控制这个发送的突发性值得考虑。
3. 如何判断当前已经达到了最佳值,否则最佳值之后上涨过快可能又会导致网络进入拥塞从而降低吞吐,实际上BICTCP/CUBIC在稳定后的增长速度都是比较快的,否则就又没办法达到高BDP网络的吞吐,所以利用网络带宽估计是一个比较靠谱的反馈,也有不少论文涉及到此方法,实际使用如UDT。