QOS队列类型简介(CQ、PQ、WFQ、CBWFQ
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QOS队列类型简介(CQ、PQ、WFQ、CBWFQ相关的知识,希望对你有一定的参考价值。
参考技术A 对于网络单元,当分组到达的速度大于该接口传送分组的速度时,在该接口处就会产生拥塞。如果没有足够的存储空间来保存这些分组,它们其中的一部分就会丢失。分组的丢失又可能会导致发送该分组的主机或路由器因超时而重传此分组,这将导致恶性循环。 造成拥塞的因素有很多。比如,当分组流从高速链路进入路由器,由低速链路传送出去时,就可能产生拥塞。分组流同时从多个接口进入路由器、由一个接口转发出去或处理器速度慢也可能会产生拥塞。 拥塞管理是指网络在发生拥塞时,如何进行管理和控制。处理的方法是使用队列技术。将所有要从一个接口发出的报文进入多个队列,按照各个队列的优先级进行处理。不同的队列算法用来解决不同的问题,并产生不同的效果。常用的队列有FIFO、PQ、CQ、WFQ、CBWFQ、LLQ等。1、FlFO(先进现出队列) 先进先出队列(First In First Out Queuing,简称FIFO)不对报文进行分类,当报文进入接口的速度大于接口能发送的速度时,FIFO按报文到达接口的先后顺序让报文进入队列,同时,FIFO在队列的出口让报文按进队的顺序出队,先进的报文将先出队,后进的报文将后出队。 Internet的默认服务模式是Best-Effort,采用FIFO队列策略。
2、PQ (Priority Queueing,优先队列) PQ使用了4个子队列,优先级分别是high,medium,normal,low。PQ会先服务高优先级的子队列,若高优先级子队列里没有数据后,再服务中等优先级子队列,依次类推。如果PQ正在服务中等优先级子队列,但是高优先级里又来了数据包,则PQ会中断中等优先级子队列的服务,转而服务高优先级子队列。每一个子队列都有一个最大队列深度(queue-size),如果达到了最大队列深度,则进行尾丢弃。
PQ优点: 1)对高优先级的数据流提供了低延迟的转发 2)大多数平台上都支持该队列机制 3)支持所有的ios版本 PQ缺点: 1)对单一子队列而言,会继承FIFO队列的所有缺点 2)对低优先级的数据流而言,可能会被“饿死”,因为只有高优先级队列里有数据,PQ就不会服务低优先级队列 3)需要在每一跳上都手工的配置分类
3、CQ(Customized Queue,用户定制队列) CQ最多可包含16个组(即group-number的取值范围为1~16),在每个组中指明了什么样的数据包进入什么样的队列、各队列的长度和每次轮询各队列所能连续发送的字节数等信息。CQ对报文进行分类,将所有报文分成最多至17类,分别属于CQ的17个队列中的一个,然后,按报文的类别将报文进入相应的队列。 CQ的17个队列中,0号队列是优先队列,路由器总是先把0号队列中的报文发送完,然后才处理1到16队列中的报文,所以0号队列一般作为系统队列把实时性要求高的交互式协议报文放到0号队列。1到16号队列可以按用户的定义分配它们能占用接口带宽的比例,在报文出队的时候,CQ按定义的带宽比例分别从1到16号队列中取一定量的报文在接口上发送出去。其中,按带宽比例分别发送的实现过程是这样的,16个普通队列采用轮询的方式进行调度,当调度到某一个队列时,从这个队列取出一定字节数的报文发送,用户通过指定这个字节数,就可以控制不同队列之间的带宽分配比例。 用户在指定每个队列每次调度时发送的字节数时,需要把握所配数值的大小,因为这关系到轮询中配置增加的粒度。例如,为了实现4个队列间的1:2:2:4的关系,我们可以配置这4个队列发送字节数为:1、2、2、4,也可以配置为:500、1000、1000、2000。但在考虑了线路的MTU后,若MTU为500,则后一种方式较好。因为在轮询时,所剩配额不够发送当前报文时,会只累加配额,然后等下次调度,显然当前条件下.第二种方案浪费在轮询空转上的时间要少。 PQ赋予较高优先级的报文绝对的优先权,这样虽然可以保证关键业务的优先,但在较高优先级的报文的速度总是大于接口的速度时,将会使较低优先级的报文始终得不到发送的机会。采用CQ,将可以避免这种情况的发生。CQ可以把报文分类,然后按类别将报文被分配到CQ的一个队列中去,对每个队列,可以规定队列中的报文应占接口带宽的比例,这样,就可以让不同业务的报文获得合理的带宽,从而既保证关键业务能获得较多的带宽,又不至于使非关键业务得不到带宽。当然CQ中的实时业务不能获得象PQ一样好的时延指标。
注:难道是PQ+WRR的组合?
4、WFQ(Weighted Fair Queueing,加权公平队列) WFQ是一个复杂的排队过程,可以保证相同优先级业务间公平,不同优先级业务间加权。队列的数目可预先配置,范围是(16-4096)。 WFQ,在保证公平(带宽、延迟)的基础上体现权值,权值大小依赖于JP报文头中携带的IP优先级(Precedence)。WFQ对报文按流进行分类(相同源IP地址,目的IP地址,源端口号,日的端口号,协议号,Precedence的报文属于同一个流),每一个流被分配到一个队列,该过程称为散列。WFQ入队过程采用HASH算法来自动完成,尽量将不同的流分入不同的队列。在出队的时候,WFQ按流的优先级(precedence)来分配每个流应占有出口的带宽。优先级的数值越小,所得的带宽越少。优先级的数值越大,所得的带宽越多。这样就保证了相同优先级业务之间的公平,体现了不同优先级业务之间的权值。 如:接口中当前有8个流,它们的优先级分别为O,2,2,3,4,5,6,7。则带宽的总配额将是:所有(流的优先级+1)的和。即:1+3+3+4+5+6+7+8=37 每个流所占带宽比例为:(自己的优先级数+1),(所有(流的优先级+1)的和)。即,每个流可得的带宽分别为:1/37,3/37,3/37,4/37,5/37,5/37,6/37,7/37,8/37。 由此可见,WFQ在保证公平的基础上对不同优先级的业务体现权值,而权值依赖于IP报文头中所携带的IP优先级。
WFQ优点 1)配置简单(不用手工分类) 2)保证所有的流都有一定的带宽 3)丢弃野蛮流量 4)大多数平台上都支持 5)支持所有IOS版本 WFQ缺点 1)每个子队列都继承了FIFO的缺点 2)多个不同的流可能会被分入同一个队列(流的数量超过了配置的队列数) 3)不支持手工分类 4)不能提供固定带宽保证 5)因为使用了复杂的分类和调度机制,对系统资源有一定的限制
5、CBWFQ(class-based weighted fair queuing,基于类的加权公平队列) CBWFQ通常使用ACL定义数据流类别,并将注入宽带和队列限制等参数应用于这些类别。CBWFQ是网络中的一个队列配置方案,其允许通信基于标准分类,例如访问控制列表,输入界面名,协议和服务质量(QoS)标志。CBWFQ扩展了加权公平队列WFQ功能的标准来提供自定义通信类型支持。
CBWFQ特点: 1)能够给不同的类保障一定的带宽 2)对传统的WFQ作了扩展支持用户自己定义流量的分类: 3)队列的个数和类别是一一对应,给每个class 保留带宽
CBWFQ与WFQ的区别: WFQ: 用户无法控制分类,由HASH算法自己决定 CBWFQ:让用户对流量自己来分类 WFQ 对正常流量 处理没问题,但是对语音流量显得”太公平”(语音要求低延迟) CBWFQ:考虑到公平特性,并没有考虑到语音的应用
6、LLQ(Low Latency Queueing,低延迟队列) LLQ为基于类别的加权公平排队(CBWFQ)提供绝对优先排队功能,减少了语音会话的抖动。LLQ相当于CBWFQ加上一个严格优先级队列,该队列优先级高于其他所有队列,非常适合时延敏感性应用。LLQ的严格优先级队列是一个有最小保证带宽的优先级队列,出现拥塞时,该队列的数据量不能超过所允许的带宽,否则会被丢弃。 LLQ具有CBWFQ的所有优点,包括自定义流量类别,为每种类别的流量提供带宽保证,并且可以在所有类别的队列上应用WRED。(严格优先级队列除外) 对于LLQ和CBWFQ来说,任何没有被显示分类的流量都被认为class-default流量,可以将class-default流量类别队列由FIFO改为WFQ,需要时也可以用WRED。 LLQ最大优势是可以为时延和抖动敏感型应用的流量提供一个或多个有带宽保证的严格优先级队列,LLQ并不局限于特定平台或传输介质。
嵌套容器:为什么我无法访问堆栈队列顶部的堆栈? C ++
所以我使用STL创建了一个堆栈队列,如下所示:
void main()
{
queue<stack<string>> qos;
stack<string> words;
words.push("hey");
qos.push(wors);
cout<< (qos.pop()).top()<<endl;
}
预期行为:
返回嘿这个词
实际结果:
错误:成员引用基类型'void'不是结构或联合
我的问题是为什么它不返回我期待的东西,我的意思是因为qos.pop()返回stack元素而stack具有成员函数top();
答案
你的变量words
和qos
没有任何关系。
main()
也必须有int
的返回类型。
你得到错误信息的原因是,queue<>::pop
没有返回值,可以调用top()
。
你可能想要
#include <iostream>
#include <queue>
#include <stack>
#include <string>
int main()
{
std::queue<std::stack<std::string>> qos;
std::stack<std::string> words;
words.push("hey");
qos.push(words);
std::cout << qos.front().top() << '
';
}
以上是关于QOS队列类型简介(CQ、PQ、WFQ、CBWFQ的主要内容,如果未能解决你的问题,请参考以下文章