目录
写在前面的话
恶补网络知识~下文参考华为文档,具体细节见此链接。
网络拥塞及其对策
拥塞的产生
拥塞是在共享网络上多个用户竞争相同的资源(带宽、缓冲区等)时发生的问题。
例如,由于广域网的带宽通常要比局域网的带宽小,当一个局域网的用户向另一个局域网的用户发送数据时,由于广域网的带宽小于局域网的带宽,数据将不可能按局域网发送的速度在广域网上传输。此时,处在局域网和广域网之间的路由器将发生拥塞,如图1所示。
拥塞经常发生于图2所示的情况:
速率不匹配:分组从高速链路进入设备,再由低速链路转发出去。
汇聚问题:分组从多个接口同时进入设备,由一个没有足够带宽的接口转发出去。
不仅仅是链路带宽的瓶颈会导致拥塞,任何用于正常转发处理的资源的不足(如可分配的处理器时间、缓冲区、内存资源的不足)都会造成拥塞。此外,在某个时间内对所到达的流量控制不力,使之超出了可分配的网络资源,也是引发网络拥塞的一个因素。
拥塞的位置
如图3,根据设备所处网络位置及报文的收发方向,可以一台设备的报文转发途径划分为:
1.接入侧上行
2.接入侧下行
3.网络侧上行
4.网络侧下行
一般情况下,上行方向不会发生拥塞,因为上行方向还未涉及到速率不匹配、汇聚问题,也不涉及转发处理的资源。拥塞一般发生在下行方向。
拥塞的影响
1.拥塞增加了报文传输的延迟和延迟抖动。
2.过高的延迟会引起报文重传。
3.拥塞使网络的有效吞吐率降低,造成网络资源的损害。
4.拥塞加剧会耗费大量的网络资源(特别是存储资源),不合理的资源分配甚至可能导致系统陷入资源死锁而崩溃。
拥塞的管理和对策
1.拥塞管理:指网络在发生拥塞时,如何进行管理和控制。处理的方法是使用队列技术,将从一个接口发出的所有报文放入多个队列,按照各个队列的优先级进行处理。不同的队列调度算法用来解决不同的问题,并产生不同的效果。
2.拥塞避免:通过监视网络资源(如队列或内存缓冲区)的使用情况,在拥塞有加剧的趋势时,主动丢弃报文,通过调整网络的流量来解除网络过载的一种流量控制机制。拥塞避免用于防止因为线路拥塞而使设备的队列溢出。
队列及拥塞管理
策略:决定报文转发的处理次序和丢弃原则(一般采用队列技术)。
队列技术:缓存中对报文进行排序的逻辑。
当流量的速率超过接口带宽或超过为该流量设置的带宽时,报文就以队列的形式暂存在缓存中。报文离开队列的时间、顺序,以及各个队列之间报文离开的相互关系则由队列调度算法决定。
高速缓存,用于报文的缓冲和转发,缓存由所有端口共享,各端口竞争使用。为了避免有的端口长时间抢不到缓存而出现断流,给每个端口分配了一块最小可用缓存,并且分配到端口的各个队列上,保证每个队列均有缓存可用。
当收到报文时,将报文放入缓存,网络不拥塞时,报文能被及时转发,不会在缓存中产生堆积。这种情况下报文在缓存中的时间为μs级,延迟时间可以忽略不计。
当网络拥塞时,报文在缓存中产生堆积,被延迟处理,延迟时间会大幅增加。延迟时间的大小主要取决于队列的缓存长度以及该队列获得的输出带宽,可以使用如下公式计算时延:
队列时延 = 队列缓存长度 / 队列输出带宽
单个队列的报文采用FIFO(First In First Out)原则入队和出队。
队列调度算法
1、先进先出FIFO(First In First Out)
2、严格优先级SP(Strict Priority)
3、轮询RR(Round Robin)
4、加权轮询WRR(Weighted Round Robin)
5、差分轮询DRR(Deficit Round Robin)
6、加权差分轮询WDRR(Weighted Deficit Round Robin)
7、加权公平队列WFQ(Weighted Fair Queuing)
FIFO
FIFO不对报文进行分类。FIFO按报文到达接口的先后顺序让报文进入队列,在队列的出口让报文按进队的顺序出队,先进的报文将先出队,后进的报文将后出队,如图1。
SP
SP(Strict Priority)调度就是严格按照队列优先级的高低顺序进行调度。只有高优先级队列中的报文全部调度完毕后,低优先级队列才有调度机会。
假设端口有3个采用SP调度算法的队列,分别为高优先(High)队列、中优先(Medium)队列、和低优先(Low)队列,它们的优先级依次降低。如图2,其中报文编号表示报文到达顺序。
在报文出队的时候,首先让高优先队列中的报文出队并发送,直到高优先队列中的报文发送完,然后发送中优先队列中的报文,直到发送完,接着是低优先队列。在调度低优先级队列时,如果高优先级队列又有报文到来,则会优先调度高优先级队列。这样,较高优先级队列的报文将会得到优先发送,而较低优先级的报文后发送。
SP调度的缺点是:拥塞发生时,如果较高优先级队列中长时间有报文存在,那么低优先级队列中的报文就会得不到调度机会。
RR
RR调度采用轮询的方式,对多个队列进行调度。RR以环形的方式轮询多个队列。如果轮询的队列不为空,则从该队列取走一个报文;如果该队列为空,则直接跳过该队列,调度器不等待。
WRR
加权轮询WRR(Weighted Round Robin)调度主要解决RR不能设置权重的不足。在轮询的时候,WRR每个队列享受的调度机会和该队列的权重成比例。RR调度相当于权值为1的WRR调度。
WRR的实现方法是为每个队列设置一个计数器Count,根据权重进行初始化。每次轮询到一个队列时,该队列输出一个报文且计数器减一。当计数器为0时停止调度该队列,但继续调度其他计数器不为0的队列。当所有队列的计数器都为0时,所有计数器重新根据权重初始化,开始新一轮调度。在一个循环中,权重大的队列被多次调度。
假设某端口有3个队列采用WRR调度,为每个队列配置一个权值,依次为50%、25%、25%,详细的调度过程如下:
首先计数器初始化:Count[1]=2,Count[2]=1,Count[3]= 1。
第1个轮询:
从队列1取出报文1发送,Count[1]=1;从队列2取出报文5发送,Count[2]=0;从队列3取出报文8发送,Count[3]=0。
第2个轮询:
从队列1取出报文2发送,Count[1]=0;由于Count[2]=0,Count[3]=0,队列2和队列3不参与此轮调度。
此时,Count[1]=0,Count[2]=0,Count[3]=0,将计数器重新初始化:Count[1]=2,Count[2]=1,Count[3]= 1。
第3个轮询:
从队列1取出报文3发送,Count[1]=1;从队列2取出报文6发送,Count[2]=0;从队列3取出报文9发送,Count[3]=0。
第4个轮询:
从队列1取出报文4发送,Count[1]=0;由于Count[2]=0,Count[3]=0,队列2和队列3不参与此轮调度。
此时,Count[1]=0,Count[2]=0,Count[3]=0,将计数器重新初始化:Count[1]=2,Count[2]=1,Count[3]= 1。
从统计上看,各队列中的报文流被调度的次数与该队列的权值成正比,权值越大被调度的次数相对越多。如果该端口为100Mbps,则可以保证最低权重的队列至少获得25Mbps带宽,避免了采用SP调度时低优先级队列中的报文可能长时间得不到服务的缺点。
WRR对于空的队列直接跳过,循环调度的周期变短,因此当某个队列流量小的时候,剩余带宽能够被其他队列按照比例占用。
WRR调度有两个缺点:
WRR调度按照报文个数进行调度,因此每个队列没有固定的带宽,同等调度机会下大尺寸报文获得的实际带宽要大于小尺寸报文获得的带宽。而用户一般关心的是带宽。当每个队列的平均报文长度相等或已知时,通过配置WRR权重,用户能够获得想要的带宽;但是,当队列的平均报文长度变化时,用户就不能通过配置WRR权重获取想要的带宽。
低延时需求业务(如语音)得不到及时调度。
DRR
差分轮询DRR(Deficit Round Robin)调度实现原理与RR调度基本相同。
DRR与RR的区别是:RR调度是按照报文个数进行调度,而DRR是按照报文长度进行调度。
DRR为每个队列设置一个计数器Deficit,Deficit初始化为一次调度允许的最大字节数,(假设为Quantum,一般为接口MTU)。每次轮询到一个队列时,如果报文长度小于Deficit,则该队列输出一个报文,且计数器Deficit减去报文长度。如果报文长度超过了Deficit,报文不被发送,Deficit值不变,继续调度下一个队列。每一次轮询之后,为每个队列加上Quantum,再开始新一轮调度。DRR调度避免了采用SP调度时低优先级队列中的报文可能长时间得不到服务的缺点。但是,DRR调度不能设置权重,且也具有低延时需求业务(如语音)得不到及时调度的缺点。
MDRR
MDRR (Modified Deficit Round Robin)是一种改良的DRR算法。MDRR和DRR实现类似,差别在于:MDRR调度允许Deficit出现负值,以保证长报文也能够得到调度。但下次轮循调度时该队列将不会被调度。当计数器为0或负数时停止调度该队列,但继续调度其他计数器为正数的队列。
假设某端口MTU=150Bytes,有2个队列Q1和Q2采用MDRR调度,Q1队列中有多个200Bytes的长报文,Q2队列中有多个100Bytes的短报文,则调度过程如图5。
由上图可以看出,经过第1~6轮MDRR调度,Q1队列被调出了3个200Bytes的报文,Q2队列被调出了6个100Bytes的报文。从长期的统计看,Q1和Q2的实际输出带宽比是1:1,为公平的比例。
与DRR相比,MDRR中拥有一个可以被优先服务的优先队列(Priority Queue)。这样可以保证特殊的队列的时延要求。也可以比较有效的分配带宽,是一种相对较好的调度算法。
WDRR
加权差分轮询DWRR(Weighted Deficit Round Robin)调度主要解决DRR不能设置权重的不足。DRR调度相当于权值为1的WDRR调度。
WDRR为每个队列设置一个计数器Deficit,Deficit初始化为Weight*MTU。每次轮询到一个队列时,该队列输出一个报文且计数器Deficit减去报文长度。当计数器为0时停止调度该队列,但继续调度其他计数器不为0的队列。当所有队列的计数器都为0时,所有计数器的Deficit都加上Weight*MTU,开始新一轮调度。
假设某端口MTU=150Bytes,有2个队列Q1和Q2采用DRR调度,Q1队列中有多个200Bytes的长报文,Q2队列中有多个100Bytes的短报文,Q1和Q2配置权重比为weight1:weight2=2:1。则WDRR调度过程如图6。
第一次调度
Deficit[1] =weight1* MTU=300,Deficit[2] = weight2* MTU=150,从Q1队列取出200Bytes报文发送,从Q2队列取出100Bytes发送;发送后,Deficit[1] = 100,Deficit[2] =50。
第二次调度
从Q1队列取出200Bytes报文发送,从Q2队列取出100Bytes发送;发送后,Deficit[1] = -100,Deficit[2] =-50。
第三次调度
此时两个队列都为负,因此,Deficit[1] = Deficit[1]+weight1* MTU=-100+2150=200,Deficit[2] = Deficit[2]+weight2 MTU=-50+1*150=100。
从Q1队列取出200Bytes报文发送,从Q2队列取出100Bytes发送;发送后,Deficit[1] = 0,Deficit[2] = 0。
由上图可以看出,经过第1~3轮WDRR调度,Q1队列被调出了3个200Bytes的报文,Q2队列被调出了3个100Bytes的报文。从长期的统计看,Q1和Q2的实际输出带宽比是2:1,与权重比相符。
WDRR调度避免了采用SP调度时低优先级队列中的报文可能长时间得不到服务的缺点,也避免了各队列报文长度不等或变化较大时,WRR调度不能按配置比例分配带宽资源的缺点。
但是,WDRR调度也具有低延时需求业务(如语音)得不到及时调度的缺点。
WFQ
加权公平队列WFQ(Weighted Fair Queuing)调度是按队列权重来分配每个流应占有出口的带宽。同时,为了使得带宽分配更加“公平”,WFQ以bit为单位进行调度,类似于图7的bit-by-bit调度模型。
Bit-by-bit调度模型可以完全按照权重分配带宽,防止长报文比短报文获得更多带宽,从而减少大小报文共存时的时延抖动。
但Bit-by-bit调度模型只是理想化的模型,实际上,WFQ应是按照一定的粒度,例如256B、1KB,或其他粒度,具体按何种粒度,与单板类型相关。
WFQ的优点:
1、不同的队列获得公平的调度机会,从总体上均衡各个流的延迟。
2、短报文和长报文获得公平的调度:如果不同队列间同时存在多个长报文和短报文等待发送,让短报文优先获得调度,从而在总体上减少各个流的报文间的抖动。
3、从统计上看,权重越小,所分得的带宽越少。权重越大,所分得的带宽越多。
拥塞避免
拥塞避免是指通过监视网络资源(如队列或内存缓冲区)的使用情况,在拥塞有加剧的趋势时,主动丢弃报文,通过调整网络的流量来解除网络过载的一种流控机制。
两种丢弃策略:
1、尾丢弃
2、WRED(Weighted Random Early Detection)
尾丢弃
拥塞避免传统的处理方法是尾丢弃(Tail Drop),当网络发生拥塞时,所有新到来的报文都被丢弃。
这种丢弃策略会引发TCP全局同步现象——对于TCP报文,如果大量的报文被丢弃,将造成TCP超时,从而引发TCP慢启动,使得TCP减少报文的发送。当队列同时丢弃多个TCP连接的报文时,将造成多个TCP连接同时进入拥塞避免和慢启动状态以降低并调整流量,称之为“TCP全局同步”。这样多个TCP连接发往队列的报文将同时减少,而后又会在某个时间同时出现流量高峰,如此反复,使网络资源利用率低。
WRED
加权随机早期检测WRED(Weighted Random Early Detection)是在队列拥塞前进行报文丢弃的一种拥塞避免机制。WRED通过随机丢弃报文避免了TCP的全局同步现象——当某个TCP连接的报文被丢弃,开始减速发送的时候,其他的TCP连接仍然有较高的发送速度。这样,无论何时总有TCP连接在进行较快的发送,提高了线路带宽的利用率。
WRED为每个队列都设定一对低门限和高门限值,并规定:
1、当队列长度小于低限时,不丢弃报文,丢弃概率为0%。
2、当队列长度超过高限时,丢弃所有新到来的报文,即进行尾丢弃,丢弃概率为100%。
3、当队列长度在低限和高限之间时,开始随机丢弃新到来的报文,且设定了一个最大丢弃概率,队列越长,丢弃概率越大。如果以报文长度为横坐标,丢弃概率为纵坐标,则丢弃概率曲线如图8。
WRED详细实现过程如图9,WRED为每个到来的报文赋予一随机数i(0<i%<=100%),并用该随机数与当前队列的丢弃概率比较,小于丢弃概率则新到的报文被丢弃。假设最大丢弃概率为a%,当前队列长度为m,对应的丢弃概率为x%,如果随机数0<i<=x,则丢弃新到的报文;如果随机数x<i<=100%,则不丢弃新到的报文,即对于新到来的报文有x%的概率被丢弃。
如图10,假设队列长度为m(低门限<m<高门限)时丢弃概率为x%,则当随机数落入区间[0,x]时新到的报文被丢弃;长度为n(m<n<高门限)时丢弃概率为y%,则当随机数落入区间[0,y]时报文被丢弃。区间[0,y]比[0,x]的范围大,随机数落入区间[0,y]比落入区间[0,x]的可能性大,因此,队列越长,新到的报文被丢弃的可能性越高。
假设有两个队列Q1和Q2,对应的最大丢弃概率分别为a%和b%,则两个队列的丢弃概率曲线图如图8-16。假设当队列长度为m时,Q1的丢弃概率为x%,Q2的丢弃概率为y%,则当随机数落入区间[0,x]时Q1新到的报文被丢弃;当随机数落入区间[0,y]时Q2新到的报文被丢弃。区间[0,y]比[0,x]的范围大,随机数落入区间[0,y]比落入区间[0,x]的可能性大,因此,相同队列长度时,最大丢弃概率配置得越大,丢弃可能性越高。
华为路由器支持为每个流队列FQ和每个类队列CQ配置WRED丢弃策略,且WRED区分三种丢弃优先级(对应红、黄、绿三种报文颜色),允许用户对每种丢弃优先级设定高低门限百分比和丢弃概率,因此WRED可以对各种业务流以及同一业务流内部不同的丢弃级别报文进行不同概率的丢弃。
丢弃策略的选择
对于实时性要求比较高的业务一般使用的是尾丢弃。因为这种报文要提供最大限度的带宽保证。采用尾丢弃是只有当报文队列达到最大长度时才会丢弃,由于使用PQ调度,抢占其他业务的带宽,所以当发生拥塞时,实时性的业务带宽能够得到最大的保证。
对于WFQ队列,一般采用WRED。由于WFQ队列是按权重分享带宽,容易发生拥塞,采用WRED策略有效的避免了TCP全局同步现象。
队列缓存对时延和抖动的影响
队列缓存
高速缓存,用于报文的缓冲和转发,缓存由所有端口共享,各端口竞争使用。为了避免有的端口长时间抢不到缓存而出现断流,它给每个端口分配了一块最小可用缓存,并且分配到端口的各个队列上,保证每个队列均有缓存可用。
队列缓存对时延的影响
当收到报文时,将报文放入缓存,网络不拥塞时,报文能被及时转发,不会在缓存中产生堆积。这种情况下报文在缓存中的时间为μs级,延迟时间可以忽略不计。
当网络拥塞时,报文在缓存中产生堆积,被延迟处理,延迟时间会大幅增加。从报文进入缓存到报文被调度出去的时间间隔称为缓存时延(也称为队列时延)。
缓存时延的大小主要取决于队列的缓存长度以及该队列获得的输出带宽,可以使用如下公式计算缓存时延的最大值:
缓存时延最大值 = 队列缓存长度÷队列输出带宽
队列缓存长度单位是Byte;队列输出带宽即队列整形速率,单位是bit/s,因此上述公式可表达为:
缓存时延最大值 = 队列缓存长度×8÷队列整形速率
从上述公式可以看出,缓存越大,缓存时延越大。
队列缓存对抖动的影响
抖动,也叫做延时的变化,是指同一业务流中不同分组所呈现的时延不同。数据包离开发送端时,是按照一定的间隔均匀发送,然而在通过网络时,这一均匀的间隔因数据包经历不同的延迟而遭到破坏,从而产生抖动。抖动会对语音、视频流等实时业务造成影响,分组到达时间的差异将在话音或视像中造成断续。为了解决抖动问题,通常语音/视频的接收终端会有去抖动缓存机制,但如果网络抖动过于严重,超出了接收终端的容忍度,依然会导致语音或视像的失真和断续。
网络抖动严重的原因主要是IP网络路由状态频繁变化,使得各数据包分别经由不同物理路由到达;或者网络节点流量拥塞,数据包在各节点缓存时间过长,使得数据包到达接收端的时间差较大。其中,后者是较为常见的原因。
根据抖动的定义可知:抖动=时延差。时延差越大,则抖动越大。那么,如果把时延都控制的很小,那时延差也就得到控制。即,通过控制时延,可间接控制抖动。例如,把时延控制在5µs之内,那么时延差也就控制在5µs,即抖动也控制在5µs之内。
在队列缓存对时延的影响中介绍过,缓存越大,缓存时延越大。那么,适当控制缓存长度,可控制时延,从而控制抖动。
队列缓存的设置
在配置WRED时修改队列缓存长度。
队列不能设置过短。如果某队列过短,缓存空间过小,流量即使速率不大也容纳不下,容易造成丢包,从而给使用TCP协议传输的业务带来抖动。
队列也不能设置过长。如果队列太长,时延过大。尤其对于TCP应用,通信两端会预测网络拥塞情况,在发送完一个报文后,启动超时定期器等待对方应答,如果在定时器超时前没有等到应答,发送方会重发报文。如果报文在网络中被缓存的时间过长,不丢弃与丢弃没有区别。
“队列缓存对时延的影响”中介绍过:
缓存时延最大值 = 队列缓存长度×8÷队列整形速率
此公式可推断出:
队列缓存长度(Byte) =队列整形速率(bit/s)×业务能容忍的最大时延(s)÷8
低优先级业务的时延通常要求≤100ms,高优先级业务的时延要求≤10ms。结合上述公式,推荐高优先级队列(CS7、CS6、EF)的长度设置为10ms×队列整形速率;低优先级队列的长度设置为100ms×队列整形速率。