0、摘要
当网络发生拥塞的时候,会严重影响TCP的吞吐量,这个问题在数据中心网络上表现更加严重。本文描述了这个问题原因,也列出了解决这个的一些方法。
1、问题表象
图1、多个发送者用TCP同时向一个接受者发送数据
如上图所示,当多个发送者通过交换机(或者路由器)相连与一个接收者相连,所有物理链路带宽都是1Gbit/sec,发送者和接收者之间建立4条TCP连接。
当只有一个发送者向一个接收者发送数据的时候,接收者每秒能够收到1Gbit的数据,实际吞吐量能够达到物理链路带宽的上限。但是当4个发送者同时向接受者发送数据的时候,接收者平均吞吐量无法达到1Gbit/s,远小于物理链路带宽限制。
2、TCP的滑动窗口
TCP协议有两个主要作用:(1)当网络发生拥塞并丢弃报文的时候,通过确认和重传机制保证数据可靠传输;(2)当网络发生拥塞的时候,避免由于快速重传数据导致拥塞越来越严重,使用满启动和拥塞避免算法;
最简单的确保数据可靠发送到对端的方法是“一问一答”式的确认协议,也就是:发出一个数据报,等待对方确认(ACK),然后再发下一个数据报。由于等待对方确认的过程花费了大量时间,使得物理链路的带宽不能得到充分利用。
TCP为了提高传输效率,使用滑动窗口机制,在没有收到对方确认时候,TCP可以同时发送很多个数据报,直到达到TCP的发送窗口大小的限制。减少TCP发送窗口的大小,可以起到降低TCP的发送速率的作用。
3、TCP的拥塞控制
数据报被网络丢弃最主要的原因是网络拥塞,如图1所示,多个发送者向一个接收者同时发送数据的时候,就会发生网络拥塞。此时交换机(或者路由器)就会丢弃一部分报文。
图2、当拥塞发生的时候,若继续向网络注入流量,拥塞将恶化
在广域网环境下,当网络拥塞发生之后,如果发送者以继续以很高的速率向接收者发送数据,并快速重传被丢弃的报文,将有越来越多的网络边缘计算机感受到拥塞影响,越来越多的计算机参与抢占网络带宽的行动,那么网络拥塞将得不到缓解,负向反馈循环导致网络瘫痪。
为了上述这种情况的发生,TCP规定每个参与者都必须约束自己的行为,当网络拥塞发生的时候,每个发送者都减小发送报文的速率。当TCP发送者检测到丢包的时候(重复ACK、或者超时),就把迅速减小自己的发送窗口到1个报文段的大小,此时发送者只能发出一个报文,并等待对方确认,当收到对方确认之后,再把自己的发送窗口增加一个报文段的大小。这个过程就是TCP的慢启动过程。
图3、TCP的满启动和拥塞避免
TCP的发送窗口(swnd)值是在对方接收窗口(rwnd)和自己拥塞窗口(cwnd)两者之间的取最小值,即:
swnd = min(rwnd, cwnd)
其中rwind是对方的接收窗口,也就是TCP包头里面的window域。cwnd是发送者自己计算的拥塞窗口,初始值是MSS(maxium segment size,TCP的最大报文段的大小),每收到一个ACK,cwnd加一。也就是说,开始的时候只能发一个报文,然后等待ACK。收到ACK之后,就发两个报文等待ACK。然后就是4个、8个,…。cwnd呈指数规律增长,这个就是慢启动过程。当cwnd达到ssthresh界限之后,就线性增长,这个是拥塞避免过程。如上图所示。
当发送者检测到丢包时,迅速把自己的cwnd减小到1,重新开始慢启动过程。发送者到接收者之间的网络流量也随着cwnd的增加而增大,随着cwnd的减小而减小。
4、TCP的全局同步问题
在网络设备上,从一个端口收到的报文会暂时存放在内存队列中,然后再从队列中按顺序取出报文,转发到另外一个端口上。拥塞在网络设备上的表现是队列被充满,新收到的报文因无处存放而被丢弃。
图4、采用尾丢弃算法的网络设备
当网络设备的队列被充满的时候,丢弃所有新到的报文,这是最简单、最易实现的处理方法。这个方法就是“尾丢弃”算法。
图5、尾丢弃算法导致TCP同步问题
使用尾丢弃算法的网络设备上,当队列满的时候,所有TCP流的报文都将被同时丢弃,由此引发的一个问题是:所有经过这个中间网络设备的所有TCP同时进入慢启动状态,此设备网络接口的流量陡降。然后所有TCP的窗口慢慢增加,流量也随之慢慢增加,增加到一定程度的时候,队列再次被队填满,所有TCP连接的流量再次同时陡降。如此往复,如图5所示。
所有TCP以相同的步调来执行“慢启动、丢包减速”的过程中,吞吐量随之剧烈颠簸,网络的带宽不能得到充分利用。这个就是TCP全局同步问题。
5、RED/WRED和FQ
为了解决上述TCP全局同步问题,现在的网络设备中增加了一种可选报文丢弃算法:随机早丢弃(random early drop),简写为RED。
图6、随机早丢弃算法
RED的原理是:网络设备的队列到达一定长度的时候,就开始丢弃以一定的概率随机的丢弃报文,随着队列长度的增加,报文丢弃的概率也随之增加。
图7、启用RED算法避免TCP全局同步
如上图所示,这样在队列未满的时候随机丢弃报文,可以避免所有TCP流同时进入慢启动过程,避免网络流量出现剧烈颠簸。如上图所示,浅蓝色线条(Managed Congestion with RED)表示启用了RED之后的流量。
图8、WRED算法
WRED算法把报文分成优先级不同的几个类别,对不同的类别,报文丢弃概率也不同,优先级高的丢弃概率低,如上图所示。
WRED是为了保障优先级高的TCP流能够得到更高的带宽,但是RED并不能严格保证所有TCP流都能得到相同的带宽。那么如何保证每个TCP流都能公平的得到相同的带宽呢?
图9、FQ调度算法
保证不同TCP流之间公平的分配网络带宽的方法是:把不同的TCP流数据报文放到不同的队列中,然后在不同的队列之间公平的取出报文,发送出去。对每个队列分别执行RED算法。如上图所示,这个就是公平队列(Fair Queuing)。
6、显式拥塞通知(ECN:Explicit Congestion Notification)
图10、显式拥塞通知
RED是通过尽早丢包的方法,来避免网络拥塞,但是丢包就要重传,重传就会重复占用线路带宽,导致网络资源利用率降低。ECN的目的就是解决RED的网络带宽利用率问题。当中间的路由器检测到拥塞即将发生的时候,就设置这个报文的ECN比特,接收方收到这个报文之后,就会给发送方发一个带有ECN-ECHO的TCP报文,发送方收到这个报文就知道网络已经拥塞了,应该降低发送速度,避免拥塞。
7、数据中心的TCP incast吞吐量陡降问题
前面几节提到的RED/WRED、FQ方法,在广域网上对TCP同步问题是很有效的,因为广域网的链路速率比较低,路由器内部报文缓冲区比较大,刚出现拥塞苗头的时候就开始丢包,接收端探测到丢包就给发送端反馈重复确认(duplicated ACK),发送端收到重复确认就开始满启动过程。此时路由器的缓冲区还没有被填满。
数据中心普遍使用以太网交换机,以太网交换机的报文缓冲区容量很小(注1),链路带宽却很大,从开始丢包,到报文缓冲区被填满的时间很短。因此RED算法在报文缓冲区很小的以太网环境下效果不好。虽然增加以太网交换机的报文缓冲区可以解决问题,但是这将导致成本大幅增加。详见附件《iSCSI应用的incast问题》。
TCP incast throughput Collapse跟TCP global_synchronization问题的本质是相同的,只是在不同的环境中表现出来的,解决问题的方向也不同。
增加交换机的报文缓冲区是可以解决这个问题的。
7.1、减小TCP 最小RTO设置
虽然TCP的重传超时值(RTO)值是动态计算出来的,但是这个RTO有一个范围。在Linux操作系统上,这个范围是200ms – 120sec。也就是说,一旦发生了丢包,最少需要经过200ms才能重传这个数据包。这个最小值在以太局域网上就显得有点大了,一般局域网的时延只有几个us,丢弃一个包就需要等待200ms才能开始重传下一个数据包,这会导致物理线路的带宽不能得到充分利用。
图11、减小TCP RTO的效果
减小操作系统默认配置MIN_RTO,可以快速重传丢弃的数据包,能够提高物理线路的利用率。上图是不同MIN_RTO的吞吐量结果。
7.2、减小TCP接收窗口
如上节所述,更改MIN_RTO只能在发送端实现,不能在接收端实现。在接收端端解决这个问题的方法是减小TCP接收窗口大小,减小接收窗口可以达到降低该TCP连接吞吐量的作用。恰当的降低同一个网络接口上所有TCP连接的接收窗口值,能够把接收流量控制在接近物理带宽的水平。
图12、减小TCP RTO的效果
当 Sum(all_tcp_rcvwnd) = 2*RTT*BW时,能够让一个接口所有TCP接收流量控制在接近物理带宽的水平。详见附录《ACM:用减小TCP窗口的方法.pdf》。
上图是减小TCP窗口的测试结果,其中ICTCP是减小了窗口TCP的吞吐率总和。
这个方法是在接收端实施的,对于《附录B.1阵列iSCSI问题》的场景是无效的,但是对于《附录B.2 N8000和E6000交换板的兼容问题》则有效。
7.3、其他方法
n 增加SRU(server request size)
n 以太网流控(IEEE 802.3x Flow-control)
启用IEEE 802.3x以太流控机制可以保证主机和以太网交换机之间不丢包,当交换机的报文缓冲区充满的时候,交换机会向发送数据的主机发送xoff pause帧,收到该帧的主机停止发送数据,直到xoff超时或者收到交换机发送的xon帧。
图13、IEEE 802.3x xoff导致sender4和receiver2之间的流量受影响
这个方案的问题是,802.3x的xoff可能影响其他没有发生拥塞的数据流。如上图所示,当启用了以太网流控后,当连接Receiver的端口发生拥塞时,Sender4的端口上会收到xoff帧,此时虽然连接Receiver2的端口没有发生拥塞,但是sender4到Receiver2的数据流会因为sender4收到了xoff而受到影响。
IEEE 802.3x是一个成熟标准,目前所有千兆以太网交换机和千兆网卡都支持这个标准。
n 增加以太网交换机队列大小
购买更加昂贵的以太网交换机,交换机内部带有大的报文缓冲区(200ms*all_port_bw),并且支持RED功能是可以解决这个问题。
这个方案的是在很多情况下是不可行的,因为需要增加用户的采购成本,很可能不会被用户接受。
n IEEE 802.1Qau
目前IEEE Data Center Bridging (DCB)工作组正在定义一个新的标准IEEE 802.1Qau,这个标准的主要目的也是解决上文描述的拥塞问题。
这个标准的方法是:在发生拥塞的交换机上,向后发送BCN(反向拥塞通知)消息,收到BCN消息的网卡停止发送数据流。
图14、减小TCP RTO的效果
IEEE 802.1Qau与IEEE 802.3x的区别是:IEEE 802.1Qau的BCN消息是拥塞点和发送主机的网卡之间的,而IEEE 802.3x的xon/xoff帧一根网线两端的两个MAC之间的。IEEE 802.3x会导致拥塞向整个网络扩散,IEEE 802.1Qau不会。
IEEE 802.1Qau与TCP/IP ECN的区别是:IEEE 802.1Qau是拥塞点直接给发送主机的网卡发送BCN消息,而TCP/IP ECN消息需要通过接收端反馈给发送端,所以IEEE 802.1Qau比TCP/IP ECN延迟更小。
IEEE802.1Qau标准2010年发布,目前支持这个标准的交换机和网卡还不多,因此这个方案不能解决现网的问题。