网卡多队列

本篇博文介绍一些有关网卡多队列的内容,该文为zstack培训-性能分析课程笔记1的扩展阅读。

网卡多队列源自于网络QoS问题,网络QoS问题提出的队列模型,对I/O的开发以及网络性能的调优具有很大的指导意义。

第一节的网络QoS给出原理及算法的指导;

第二节讲诉在驱动和内核中是如何调度这些队列的。

1、网络QoS1

该部分内容摘取自http://www.h3c.com/cn/d_201104/713021_97665_0.htm

在看网卡多队列之前,我们先来看看QoS(Quality of Service)。QoS即服务质量,网络的QoS包含很多个方面的内容,例如:带宽、时延、丢包率等。为了提高QoS,工程师们提出了一些行之有效的QoS模型。

网络中的通信由各种不同的应用流组成,这些应用对网络服务和性能的质量有不同的要求,例如:FTP下载业务希望获取更多的带宽,VoIP语音业务则希望减少延迟和抖动。根据网络对应用的控制能力的不同,可以将网络分为不同的QoS模型。

  1. Best Effort模型(尽力而为),这是最简单的模型,应用程序可以在任何时候,发出任意数量的报文,网络尽最大的可能性来发送报文,对带宽、时延、抖动和可靠性等不提供任何保证。

    它是Internet的缺省服务模型,通过单独的FIFO实现;

  2. DiffServ模型(区分服务),由RFC2475定义,在区分服务中,根据服务要求对不同业务的数据进行分类,对报文按类进行优先级标记,然后有差别地提供服务。

    区分服务一般用来为一些重要的应用提供端到端的QoS,它通过下列技术来实现:

    1)流量标记与控制技术:它根据报文的CoS(Class of Service,服务等级)域、ToS域(对于IP报文是指IP优先级或者DSCP)、IP报文的五元组(协议、源地址、目的地址、源端口号、目的端口号)等信息进行报文分类,完成报文的标记和流量监管。目前实现流量监管技术多采用令牌桶机制。

    2)拥塞管理与拥塞避免技术:WRED、PQ、CQ、WFQ、CBQ等队列技术对拥塞的报文进行缓存和调度,实现拥塞管理与拥塞避免。

  3. IntServ模型,由RFC1633定义,在这种模型中,节点在发送报文前,需要向网络申请资源预留,确保网络能够满足数据流的特定服务要求。

    IntServ可以提供保证服务和负载控制服务两种服务,保证服务提供保证的延迟和带宽来满足应用程序的要求;负载控制服务保证即使在网络过载的情况下,也能对报文提供与网络未过载时类似的服务。

1.1、FIFO队列

FIFO队列不对报文进行分类,当报文进入接口的速度大于接口能发送的速度时,FIFO按报文到达接口的先后顺序让报文进入队列,同时,FIFO在队列的出口让报文按进队的顺序出队,先进的报文将先出队,后进的报文将后出队。

FIFO队列具有处理简单,开销小的优点。但FIFO不区分报文类型,采用尽力而为的转发模式,使对时间敏感的实时应用(如VOIP)的延迟得不到保证,关键业务的带宽也不能得到保证。

1.2、PQ原理

PQ(Priority Queuing)需要网卡提供多队列支持,它将消息按照优先级分为四个队列,并且总是优先发送更高优先级队列的报文,这样做同样也会产生一些问题,比如,当高优先级队列总有报文时会导致低优先级“饿死”。PQ队列的特性使其能够保证实时业务的优先处理,对VoIP业务有较好的优化。

PQ队列根据网络协议、数据流入接口、报文长短、IP报文的ToS、五元组(协议ID、源IP、目的IP、源端口、目的端口)等条件来对数据报文进行分类。最多分为4类。

1.3、CQ原理

CQ(Custom Queuing)同样需要网卡提供多队列支持,它的原理与PQ相似,不同在于,它能够将报文最多分至17类,每类报文对应CQ中的一个队列,接口拥塞时,报文按匹配规则被送入对应的队列;如果报文不匹配任何规则,则被送入缺省队列(缺省队列默认为1,可配置修改缺省队列)。

CQ的17个队列中,0号队列为系统队列,它的优先级是最高的,总是要保证0号队列中的报文呗发送完。剩余的1到16号队列采用轮询方式,根据用户配置的额度依次取一定数量的报文发送,若轮到为空,则轮到下一队列。

CQ把报文分类,然后按类别将报文分配到CQ的一个队列中去,而对每个队列,又可以规定队列中的报文所占接口带宽的比例,这样,就可以让不同业务的报文获得合理的带宽,从而既保证关键业务能获得较多的带宽,又不至于使非关键业务得不到带宽。但由于采用轮询调度各个队列,CQ无法保证任何数据流的延迟。

1.4、WFQ原理

WFQ(Weighted Fair Queuing),加权平均队列。WFQ对报文按流特征进行分类,对于IP网络,相同源IP地址、目的IP地址、源端口号、目的端口号、协议号、ToS的报文属于同一个流,而对于MPLS网络,具有相同的标签和EXP域值的报文属于同一个流。每一个流被分配到一个队列,该过程称为散列,采用HASH算法来自动完成,这种方式会尽量将不同特征的流分入不同的队列中。每个队列类别可以看作是一类流,其报文进入WFQ中的同一个队列。WFQ允许的队列数目是有限的,用户可以根据需要配置该值。

在出队的时候,WFQ按流的优先级(precedence)来分配每个流应占有出口的带宽。优先级的数值越小,所得的带宽越少。优先级的数值越大,所得的带宽越多。这样就保证了相同优先级业务之间的公平,体现了不同优先级业务之间的权值。

WFQ优点在于配置简单,有利于小包的转发,每条流都可以获得公平调度,同时照顾高优先级报文的利益。但由于流是自动分类,无法手工干预,故缺乏一定的灵活性,且受资源限制,当多个流进入同一个队列时无法提供精确服务,无法保证每个流获得的实际资源量。WFQ均衡各个流的延迟与抖动,同样也不适合延迟敏感的业务应用。

1.5、CBQ原理

CBQ(Class Based Queuing)基于类的队列。CBQ首先根据IP优先级或者DSCP、输入接口、IP报文的五元组等规则来对报文进行分类;对于MPLS网络的LSR,主要是根据EXP域值进行分类。然后让不同类别的报文进入不同的队列。对于不匹配任何类别的报文,报文被送入系统定义的缺省类。

CBQ包括一个低时延队列LLQ(Low Latency Queuing,低时延队列),用来支撑EF(Expedited Forwarding,快速转发)类业务,被绝对优先发送,保证时延。进入EF的报文在接口没有发生拥塞的时候(此时所有队列中都没有报文),所有属于EF的报文都可以被发送。在接口发生拥塞的时候(队列中有报文时),进入EF的报文被限速,超出规定流量的报文将被丢弃。

另外有64个BQ队列(Bandwidth Queuing,带宽保证队列),用来支撑AF(Assured Forwarding,确保转发)类业务,可以保证每一个队列的带宽及可控的时延。系统调度报文出队列的时候,按用户为各类报文设定的带宽将报文出队发送。这种队列技术应用了先进的队列调度算法,可以实现各个类的队列的公平调度。当接口中某些类别的队列没有报文时,BQ队列的报文还可以公平地得到空闲的带宽,和时分复用系统相比,大大提高了线路的利用率。同时,在接口拥塞的时候,仍然能保证各类报文得到用户设定的最小带宽。

最后还有一个WFQ队列,对应BE(Best Effort,尽力传送)业务,使用接口剩余带宽进行发送。

CBQ可根据报文的输入接口、满足ACL情况、IP Precedence、DSCP、EXP、Label等规则对报文进行分类、进入相应队列。对于进入EF和AF的报文,要进行测量;考虑到链路层控制报文的发送、链路层封装开销及物理层开销(如ATM信元头),建议EF与AF占用接口的总带宽不要超过接口带宽的75%。

CBQ可为不同的业务定义不同的调度策略(如带宽、时延等),由于涉及到复杂的流分类,对于高速接口(GE以上)启用CBQ特性系统资源存在一定的开销。

1.6 RTP原理

RTP优先队列(Real Time Protocol Priority Queuing) 。

RTP优先队列是一种保证实时业务(包括语音与视频业务)服务质量的简单队列技术。其原理就是将承载语音或视频的RTP报文送入高优先级队列,使其得到优先发送,保证时延和抖动降低为最低限度,从而保证了语音或视频这种对时延敏感业务的服务质量。

RTP优先队列将RTP报文送入一个具有较高优先级的队列,RTP报文是端口号在一定范围内为偶数的UDP报文,端口号的范围可以配置,一般为16384~32767。RTP优先队列可以同前面所述的任何一种队列(包括FIFO、PQ、CQ、WFQ与CBQ)结合使用,它的优先级是最高的。由于CBQ中的EF完全可以解决实时业务,所以不推荐将RTP优先队列与CBQ结合应用。

由于对进入RTP优先队列的报文进行了限速,超出规定流量的报文将被丢弃,这样在接口拥塞的情况下,可以保证属于RTP优先队列的报文不会占用超出规定的带宽,保护了其他报文的应得带宽,解决了PQ的高优先级队列的流量可能“饿死”低优先级流量的问题。

2、多核CPU,网卡多队列

1中所介绍的不同多队列调度方式,本质上还是在对网卡带宽进行分配调度,这对于单个CPU来说情况并没有任何改变(单核CPU:所有的苦都是我一个人承担)。

随着网络IO的带宽不断提升(万兆网卡,多个万兆网卡。。),单核CPU已经无法满足网卡的需求了。这时候就需要多个CPU一起来处理网卡的多个队列。

2.1、网卡驱动的支持

2.6.21版本后Kernel支持网卡多队列特性,当网卡驱动加载时,驱动判断当前网卡型号,得知网卡硬件FIFO的数量,再结合CPU核数,最终通过Sum = Min得出要激活的网卡queue数量,同时申请同样数量的中断,再通过中断亲和给不同的CPU核分配不同的FIFO。

当某个FIFO收到报文时,出发相应的中断,收到中断的CPU执行中断服务程序,获取该FIFO上的数据报文。需要注意的是,在设置中断亲和性的时候最好将不同的FIFO分配给不同的CPU核,这样才能使得并发效率最佳,同时同一FIFO的tx和rx中断最好绑定到一起。

这样CPU的各个核就可以并发地收发数据报文。

2.2、识别多队列网卡

通过lspci命令可以看到物理网卡上的FIFO数量

1
$ lspci -vvv

若出现MSI-X:Enable+ Count值 > 1,那么该网卡为多队列网卡。多队列网卡驱动给每个queue申请了MSI。MSI-X是MSI数组,Enable+指使能,TabSize是数组大小。

通过ethtool命令课设置网卡队列

1
2
$ ethtool -l eth0 #查看eth0网卡channel状态
$ ethtool -L eth0 combined 4 #将网卡队列数设置为4

# 4、参考

  1. QoS的基本原理:http://www.h3c.com/cn/d_201104/713021_97665_0.htm