认识队列技术中的硬件队列和软件队列及如何改变硬件队列长度

简介:

队列技术

     路由器或者交换机的数据发送,必须依赖于队列(queue),这是一个什么样的概念呢?首先从生活中打个比喻:有很多人在公交车站,排队等待乘坐公交车离开站台去往各自的目的地,这种排队有一个原则:排在前面的人会比排后面的先上车,如果客车满载了,不好意思排后面的人就只有等待下一班车,但是如果排在后面的人有急事怎么办?OK请将这个问题留在这里。事实上,路由器或者交换机也是一样,它首先是将数据存储在内存中,如果当前的发送接口不繁忙,那么它将转发数据包,如果当前的接口繁忙,那么网络设备会将数据包暂存于内存中,直到接口空闲,理发送数据包,为了更科学的管理和优先内存中的数据包,IOS建立了排队这个概念。最基本的原则就是先进先出(FIFO),既排前面的数据包会被优先转发,排后面的数据包将直到它前面的包被发送后才会被转发,而且队列是有长度限制的,所以当排队的数据达到队列长度的限制时,那么数据包将被丢弃(不允许你排队)。如下所示:

 

wKiom1RsojXgx5tWAADe9eE6U-k687.jpg

如果数据包都被送进队列排队,那么这个队列要多大的容量才能装载下海量的数据?

队列中存放的并不是真实的数据,所以每个数据包本身的大小并不影响队列的长度,换而言之,一个1500字节的数据包和一个10K的数据抱在队列里面的概念是一样的,因为队列中只保存着一个名为“数据指针”的概念,而真正的数据被存储在缓存区的“堆栈”中。数据指针就是申明该数据在“堆栈”中某个具体位置。

 

如果使用单一的先进先出队列(FIFO),那么FIFO队列将不支持任何QOS功能,不能获得优先调度哪些数据做转发的能力,也就是说FIFO队列是不可能影响延迟、抖动、丢弃。因为FIFO只有一种原则“先进来的先出去”,但是这个FIFO队列本身的大小(队列的深度),将影响延迟、抖动、丢弃等网络服务质量的因素。如果队列被充满,那么后面持续到来的数据包会被丢弃,而且这种丢弃是不区别数据包的重要及紧急程度的,也就是说只要该数据包是队列最大容量的后面一个包,就会被丢弃,一般管这种丢弃叫做尾部丢弃(本书后面简称为“尾弃”),如果希望数据不被“尾弃”的一个方案就是增加队列的长度,从表面上看增加队列的长度它可能会缓解“尾弃”,但是它会增大数据包传输的平均延迟。

 

下面列出关于队列长度的一些重要原则:

1较长的队列相较于较短的队列,数据被“尾弃”可能性降低,但是延迟和抖动会加大。

2较短的队列相较于较长的队列,数据的“尾弃”可能性会增加,但是延迟和抖动会下降

3如果产生了持续的拥塞,无论队列是长或者短,数据都会被丢弃。

 

在思科的路由器上将存在两种类型的队列(软件队列和硬件队列)

前面描述了队列这个概念,现在需要说明一个原则如所示:在输出队列(通常指示为软件队列)中的数据包并不是直接送到一个输出接口进行转发,而是将数据包从一个输出队列传送到另一个更小的输出队列(通常指示为硬件队列),然后再从这个更小的输出队列进行转发,思科管这种行为叫“Separate”。

wKioL1RsovXhBJZhAAD3nDdc_dI365.jpg

   通常,硬件队列没有被充满时或者为空时,这说明网络中没有发生拥塞,所以数据被直接传送入硬件队列,而不会再被放入软件队列排队,也就说此时不会使用软件队列,如果硬件队列被充满,那么后继到来的数据包将被放入软件队列排队,如所示的第4-9的包将被送入软件队列排队。硬件队列是不支持QOS工具的,而软件队列支持QOS工具。

 

为什么会存在软件队列和硬件队列的概念、各自的优势和特点是什么?

     硬件队列(叫TX Queue或者TX Ring),网络设备具体是选用TX Queue或者Transmit TX Ring这取决于路由器的硬件模块,但是在本书中将TX QueueTX Ring等同化,给它一个名称叫硬件队列。通常硬件队列的长度很小,这就意味着一件事,能快速的转发硬件队列中的数据,而且硬件队列的转发不依赖于通过处理器(General-Purpose Processor更通俗的名称叫CPU)而被关联到每一个物理接口上的ASICApplication-SpecificIntegrated Circuits)直接访问的队列。所以即便是路由器的CPU工作负荷很重,硬件队列也可以快速的发送数据,而不需要去等待CPU做中断处理的时间延迟。但是硬件队列永远都是遵守先进先出(FIFO)原则,它是不可以使用QOS的队列工具来进行管理的,每个物理接口上都有一个且仅有一个硬件队列。所以应该产生一种可能被用户管理的队列机制,特别是持续发送大量的数据时。 

那么这种可能被用户执行管理的队列就是软件队列,其实无论是从理论还是从实践的角度来讲路由器可以存在多个软件队列,它的工作机制如所示,假设现在硬件队列已经被充满,那么待转发的数据包将被分类,然后将不同的分类送入不同的软件队列,当然此时还要考虑软队队列是否被充满,如果定义的软件队列已经被充满,那么数据将被丢弃,根据不同软件队列的特点可以配置不同的丢弃方式。如果软件队列未充满,那么数据包将会被送入软件队列排队,软件队列会存在多种类型(多种机制)和多个数量的队列,这也是本章后继要讨论的内容。然后调度器将决定先将那个软件队列的数据调度进入硬件队列,比如软件队列3的数据是最重要且紧急的,那么可以优先调度软件队列3的数据进入硬件队列,然后硬件队列将数据直接交给接口转发,其实通过这个逻辑不难看出:软件队列是可以被管理的,调度器就是管理软件队列的核心组件,同时也可以看出软件队列、硬件队列、接口三者之间的关系。

wKiom1RsorqzQ8gEAAFB1bCmzTE057.jpg


注意:每一个接口都有一个且仅有一个硬件队列,硬件队列永远是使用FIFO机制,不可以被队列工具所管理;软件队列可以是FIFOPQCQWFQCBWFQWRR等,通常网络工程技术人员对队列技术的学习是仅针对软件队列技术的学习!只有硬件队列被充满时才使用软件队列,软件队列是可被队列工具所管理的。

 

关于硬件队列的长度问题:

在前面的描述了,笔者提到过一种描述“硬件队列没有没充满时,就不会使用软件队列,因为硬件队列没有被充满时这意味着网络暂时没有发生拥塞,至少设备所处的网络节点暂时没有发生拥塞。”那么有朋友可能会误解这个描述,如果这样的话,那么把硬件队列通过手工配置得很长,长到数据永远都无法塞满硬件队列,那么不就成功的解决拥塞了吗?在这里笔者说明一下,硬件队列没有被充满时,就不会使用软件队列,因为硬件队列没有被充满时这意味着网络暂时没有发生拥塞,这里有一个前提条件,就是硬件队列的长度要配置得合理,通常让路由器自己去决定,而它会被路由器配置得较短,因为硬件队列是一个永远使用先进先出原则的队列,如果你把硬件队列设置得太长,那么在该队列中的所有数据全部遵守先进先出,用户重要的数据就无法得到优先调度。就直接导致软件队列一直不生效,为什么呢?因为只有硬件队列被塞满时,数据才会进入软件队列,用户才能使用调度器来决定,哪个软件队列的数据优先被放入硬件队列,然后转发。

硬件队列的最佳长度是随时保证有数据进入该队列,同时能随时快速释放队列中的数据,然后再让后继数据快速进入的状态为最佳状态,其实这关于这一点IOS系统会给设备自动做调整,那么怎么才能知道硬件队列的长度及IOS的调整状态呢?

 

理解硬件队列的关键点如下:

路由器决定硬件队列的长度时和具体接口上的带宽有关。

在路由器的接口上可以使用tx-ring-limit命令来手工配置,但不建议这样做。

减小硬件队列的尺寸,能减小在先进先出硬件队列中数据被传输前等待的时间,能够加速使用基于IOS软件的QOS工具,事实上就是让软件队列得以快速生效。

4相反如果一个硬件队列太长,它将严重影响软件队列的使用或者让软件队列的能效降低。

5如果将一个硬件队列设置得太短,会发出大量中断,制成CPU占用率过高,而链路的使用率过低。

 

IOS排队工具将自动调整对硬件队列的最小化影响。这是为了让硬件队列总是有数据。当任意的一种队列工具(软件队列)在一个接口上被启用时,IOS将减小硬件队列的尺寸到一个非常小的值(典型的是2,一般产生在中低端的路由器上),因为这个很小的值,将最小化的影响硬件队列的排队方式。换而言之,能够让硬件队列中的数据得到快速转发。

 

查看和变更路由器上的硬件队列长度

    可以通过在路由器上执行Showcontrollers s1/0指令来查看某个物理接口上硬件队列的大小,显来的结果如所示Tx_limited1(2)就是当前硬件队列的情况,“1表示当前的接口上应用了队列工具,这是因为默认在E1速率以下的链路,默认都启动了WFQ队列,关于这一点可以通过show interface s1/0来查看当前的队列工具,如所示。什么是WFQ(加权公平队列,关于WFQ的更多信息将在后面作描述,目前请记住:只要接口上使用队列工具那么Tx_limitedx(y)中的x就是1,如果当前接口没有应用任何队列工具那么x就是0.y则是指当前硬件队列的深度是多少,如果(2),表示当前硬件队列的深度为2个数据包。

wKioL1Rso33Bdr2oAANF0pfsbxY469.jpg

wKiom1Rsoyzw7z8CAAOOaEVIWnI586.jpg

如果希望接口不使用任何队列工具,当然这并不是一项推荐的行为。那么请在当前的S1/0的接口模式下接入如下所示的配置:

R1(config)#intes1/0

R1(config-if)#nofair-queue  * 关闭WFQ队列工具


当关闭S1/0接口上默认的队列工具后,再次使用show interface s1/0查看接口如所示,显示该接口目前没有使用任何队列工具,而是使用先进先出(FIFO)原则。然后再使用Show controllers s1/0指令来查看某个物理接口上硬件队列的情况如所示, Tx_limited0(2)就是当前硬件队列的情况,0表示当前接口上没有任何队列工具。当前硬件队列的深度为2.

 

注意:请不要去关闭E1速率以下接口的默认队列工具,这样可能会导致你网络的数据无法公平的获得接口上的有效带宽,从而让小体积的数据转输被大体积的数据传输所强占,得不到相应的服务!所以请在低于E1速率以下的接口配置fair-queue(当然默认它会被启动),除非你有更好,更科学的队列工具将要应用到该接口上,关于这一点将在取证FIFOWFQ队列工具实施的效果部分给出理由。


wKioL1Rso_GCGSmWAALyZqY5270948.jpg

wKioL1Rso_Wjgsg-AANuKQByrBs425.jpg

   如果希望通过手工改变硬件队列的长度,比如将S1/0的硬件队列从默认的长度2改为3,请在S1/0接口模式下执行tx-ring-limit3指令,此时再次通过执行Showcontrollers s1/0,可以看到当前硬件队列的长度变为了3

wKiom1Rso8SAtZBuAALFJi_pKjY644.jpg





本文转自 kingsir827 51CTO博客,原文链接:http://blog.51cto.com/7658423/1579813,如需转载请自行联系原作者

相关文章
|
4月前
|
算法 Java 程序员
【算法训练-队列 一】【结构特性】用两个栈实现队列
【算法训练-队列 一】【结构特性】用两个栈实现队列
30 0
|
23天前
|
算法 数据安全/隐私保护 C++
【C/C++ 编程题 03】用两个栈实现一个队列的功能
【C/C++ 编程题 03】用两个栈实现一个队列的功能
16 0
|
23天前
|
算法 编译器 C语言
【C/C++ 编程题 02】用两个栈实现一个队列的功能
【C/C++ 编程题 02】用两个栈实现一个队列的功能
19 0
|
10月前
|
缓存 应用服务中间件 nginx
数据结构— —队列企业级web服务器队列的应用
数据结构— —队列企业级web服务器队列的应用
|
11月前
|
数据库
每日一博 - 使用环形队列实现高效的延时消息
每日一博 - 使用环形队列实现高效的延时消息
56 0
|
存储
什么是队列,如何实现?
什么是队列,如何实现?
83 0
什么是队列,如何实现?
|
安全 算法 Java
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
98 0
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
|
存储 算法 前端开发
队列的典型题:栈实现队列、双端队列
队列的典型题:栈实现队列、双端队列
78 0
|
存储 Java 索引
不可上位!数据结构队列,老实排队,Java实现数组模拟队列及可复用环形队列
不可上位!数据结构队列,老实排队,Java实现数组模拟队列及可复用环形队列
115 0
不可上位!数据结构队列,老实排队,Java实现数组模拟队列及可复用环形队列