Linux内核TC工具链路带宽设计--无类队列规定

      Linux 内核的 TC(traffic control)工具能够用来对网络带宽作必定的设计和管理,这里将对这一工具的使用作必定的介绍,在正式开始介绍TC 以前,先对一些基本的单位作一个说明。为了不概念混乱,TC 采用以下规定来描述带宽:算法

mbps = 1024 kpbs = 1024 * 1024 bps => byte/s
mbit = 1024 kbit => kilo bit/s
mb = 1024 kb = 1024 * 1024 b => byte
mbit = 1024 kbit => kilo bit
内定:数字以 bps 和 b 方式存储,但当 tc 输出速率时,使用以下表示:
1Mbit = 1024 Kbit = 1024 * 1024 bps => byte/s

 

1.1 解释队列和队列规定网络

      利用队列,咱们决定了数据被发送的方式。必须认识到,咱们只能对发送数据进行整形。工具

      根据Internet 的工做方式,咱们没法直接控制别人向咱们发送什么数据。就像咱们家里的信报箱,你不可能控制全世界,联系每个人,修改别人对你发送邮件的数量。然而,Internet 主要依靠TCP/IP,它的一些特性颇有用。由于TCP/IP 没办法知道两个主机之间的网络容量,因此它会试图愈来愈快地发送数据(所谓的“慢起技术”) ,当由于网络容量不够而开始丢失数据时,再放慢速度。spa

      若是你有一个路由器,而且但愿可以防止某些主机下载速度太快,你须要在你路由器的内网卡——也就是向你的网内主机发送数据包的网卡——上进行流量整形。还要保证正在控制的是瓶颈环节。若是有一个100M 以太网卡,而路由器的链路速度是 256k,则必须保证发送的数据量没有超过路由器的处理能力。不然,就是路由器在控制链路和对带宽进行整形,而不是你。能够说,咱们须要拥有的队列必须是一系列链路中最慢的环节。设计

 

1.2 简单的无类队列规定code

      如前所述,利用队列,咱们决定了数据被发送的方式。无类队列规定就是那样,可以接受数据和从新编排、延迟或丢弃数据包。这能够用做对于整个网卡的流量进行整形,而不细分各类状况。最普遍应用的规定是pfifo_fast 队列规定,由于它是缺省配置。blog

 

1.2.1 pfifo_fast队列

      这个队列的特色是先进先出(FIFO),也就是说没有任何数据包被特殊对待。这个队列有 3 个“频道”。FIFO 规则应用于每个频道。而且若是在 0 频道有数据包等待发送,1 频道的包就不会被处理,1 频道和 2 频道之间的关系也是如此。内核遵守数据包的 TOS(Type Of Service)标记,把带有“最小延迟”标记的包放进 0 频道。进程

      不要把这个无类的简单队列规定与分类的 PRIO 相混淆。虽然它们的行为有些相似,但对于无类的 pfifo_fast 而言,不能使用 tc 命令向其中添加其它的队列规定。ip

 

1.2.1 参数与使用

      pfifo_fast 队列规定做为硬性的缺省设置,不能对它进行配置。它缺省是这样配置的: 

priomap: 

      内核规定,根据数据包的优先权状况,对应相应的频道。这个对应是根据数据包的 TOS 字节进行的。TOS 看上去是这样的: 

      TOS 字段的 4 个 bit 是以下定义的: 

二进制 十进制 意义

-----------------------------------------

1000     8    最小延迟(md)

0100     4    最大throughput(mt)

0010     2    最大可靠性(mr)

0001     1    最小成本(mmc)

0000     0    正常服务

-----------------------------------------

      队列的长度来自网卡的配置,能够用 ifconfig 和 ip 命令修改。如设置队列长度为 10,执行:ifconfig eth0 txqueuelen 10。不能用 tc 命令来设置它。

 

1.2.2 令牌桶过滤器(TBF) 

      令牌桶过滤器(TBF)是一个简单的队列规定:只容许以不超过事先设定速率到来的数据包经过,但可能容许短暂突发流量超过设定值。

      TBF 的实如今于一个缓冲器(桶),不断地被一些叫作“令牌”的虚拟数据以特定速率填充着。桶最重要的参数就是它的大小,也就是它可以存储令牌的数量。每一个到来的令牌从数据队列中收集一个数据包,而后从桶中被删除。这个算法关联到两个流——令牌流和数据流,因而咱们获得3 种情景:

      (1)数据流以等于令牌流的速率到达 TBF。这种状况下,每一个到来的数据包都能对应一个令牌,而后无延迟地经过队列。

      (2)数据流以小于令牌流的速度到达 TBF。经过队列的数据包只消耗了一部分令牌,剩下的令牌会在桶里面积累下来,直到桶被装满。剩下的令牌能够在须要以高于令牌流速率发送数据包的时候被消耗掉,这种状况下会发生突发传输。

      (3)数据流以大于令牌流的速率到达 TBF。这意味着桶里的令牌很快就会被耗尽。致使 TBF 中断一段时间,称为“越限”。若是数据包持续到来,将会发生丢包。

      最后一种状况很是重要,由于它能够用来对数据经过过滤器的速率进行整形。令牌的积累能够致使越限的数据包进行短期的突发传输而没必要丢包,可是持续越限会致使传输延迟直至丢包。须要注意的是,实际的实现是针对数据的字节数进行的,而不是针对数据包进行。

 

1.2.2.1 参数与使用

      TBF 提供了一些可调控的参数,第一个参数永远可用:

limit/latency

      limit 肯定最多有多少数据(字节数)在队列中等待可用令牌,也能够经过设置 latency 参数来指定这个参数。latency 参数肯定了一个包在 TBF 中等待传输的最长等待时间。后者计算决定桶的大小、速率和峰值速率。

burst/buffer/maxburst

      桶的大小,以字节计。这个参数指定了最多能够有多少个令牌可以即刻被使用。一般状况下,管理的带宽越大,须要的缓冲器就越大。若是缓冲区过小,就会致使到达的令牌没有地方放(桶满了),这会致使潜在的丢包。

mpu

      一个零长度的包并非不耗费带宽。好比以太网,数据帧不会小于 64 字节。mpu(Minimum Packet Unit,最小分组单位)决定了令牌的最低消耗。

rate

      速度操纵杆。

      若是桶存在令牌并且运行没有令牌,这至关于不限制速率。若是不但愿这样,能够调整如下参数:

peakrate

      峰值速率能够用来指定令牌以多快的速度被删除。用书面语言来讲,就是:释放一个数据包,而后等待足够的时间后再释放下一个。经过计算等待时间来控制峰值速率。然而,因为 UNIX 定时器的分辨率是 10 毫秒,若是平均包长为 10kbit,峰值速率则被限制在 1Mbps。

mtu/minburst 

      若是常规速率比较高,1Mbps 的峰值速率就没有什么价值。要实现更高的峰值速率,能够在一个时钟周期内发送多个数据包。最有效的办法就是再建立一个令牌桶。这第二个令牌桶缺省状况下为一个单个的数据包,并不是一个真正的桶。要计算峰值速率,用 mtu 乘以 100 就好了。

 

1.2.2.2 配置范例

      这是一个很是简单而实用的例子:

# sudo tc qdisc add dev enp0s5 root tbf rate 220kbit latency 50ms burst 1540 

      为何它很实用呢?若是你有一个队列较长的网络设备,好比 DSL modem 或者 cable modem 什么的,并经过一个快速设备(如以太网卡)与之相连,你会发现上载数据绝对会破坏交互性。这是由于上载数据会充满modem 的队列,而这个队列为了改善上载数据的吞吐量而设置的特别大。但这并非你所须要的,你可能为了提升交互性而须要一个不太大的队列。也就是说你但愿在发送数据的时候干点别的事情。

      上面的一行命令并不是直接影响了 modem 中的队列,而是经过控制 Linux 中的队列而放慢了发送数据的速度。把 220kbit 修改成你实际的上载速度再减去几个百分点。若是你的 modem 确实很快,就把“burst”值提升一点。

 

1.2.3 随机公平队列(SFQ)

      SFQ(Stochastic Fairness Queueing,随机公平队列)是公平队列算法家族中的一个简单实现。它的精确性不如其它的方法,可是它在实现高度公平的同时,须要的计算量却不多。

      SFQ 的关键词是“会话”(或称做“流”) ,主要针对一个 TCP 会话或者 UDP 流。流量被分红至关多数量的 FIFO 队列中,每一个队列对应一个会话。数据按照简单轮转的方式发送, 每一个会话都按顺序获得发送机会。这种方式很是公平,保证了每个会话都不会被其它会话所淹没。SFQ 之因此被称为“随机”,是由于它并非真的为每个会话建立一个队列,而是使用一个散列算法,把全部的会话映射到有限的几个队列中去。

      由于使用了散列,因此可能多个会话分配在同一个队列里,从而须要共享发包的机会,也就是共享带宽。为了避免让这种效应太明显,SFQ 会频繁地改变散列算法,以便把这种效应控制在几秒钟以内。

      有很重要的一点须要声明:只有当你的出口网卡确实已经挤满了的时候,SFQ 才会起做用。不然在你的 Linux 机器中根本就不会有队列,SFQ 也就不会起做用。特别地,在你使用 DSL modem 或者 cable modem 的以太网卡上设置 SFQ 是没有意义的,无需进一步整形。

 

1.2.3.1 参数与使用

      SFQ 基本上不须要手工调整:

perturb 

      多少秒后从新配置一次散列算法。若是取消设置,散列算法将永远不会从新配置(不建议这样作)。10 秒应该是一个合适的值。

quantum 

      一个流至少要传输多少字节后才切换到下一个队列。缺省设置为一个最大包的长度(MTU 的大小)。不要设置这个数值低于 MTU。

 

1.2.3.2 配置范例

      若是有一块网卡,它的链路速度与实际可用速率一致,以下配置能够提升公平性:

# sudo tc qdisc add dev enp0s5 root sfq perturb 10


# sudo tc -s -d qdisc ls
 dev enp0s5

qdisc sfq 8001: root refcnt 2 limit 127p quantum 1514b depth 127 flows 128/1024 divisor 1024 perturb 10sec 

 Sent 1863 bytes 22 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0

      “8001:”这个号码是系统自动分配的一个句柄号,“limit”意思是这个队列中能够有 127 个数据包排队等待。一共能够有 1024 个散列目标能够用于速率审计, 而其中 128 个能够同时激活。每隔 10 秒散列算法更换一次。

 

1.3 关于何时用哪一种队列的建议

      (1)若是想单纯地下降出口速率,使用令牌桶过滤器。调整桶的配置后可用于控制很高的带宽。

      (2)若是链路已经塞满了,且想保证不会有某一个会话独占出口带宽,使用随机公平队列。

      (3)若是有一个很大的骨干带宽,而且了解了相关技术后,能够考虑前向随机丢包。

      (4)若是但愿对入口流量进行“整形”(不是转发流量),可以使用入口流量策略,注意,这不是真正的“整形”。

      (5)若是正在转发数据包,在数据流出的网卡上应用 TBF。除非但愿让数据包从多个网卡流出,也就是说入口网卡起决定性做用的时候,仍是使用入口策略。

      (6)若是不但愿进行流量整形,只是想看看网卡是否有比较高的负载而须要使用队列,使用 pfifo 队列(不是pfifo_fast)。它缺少内部频道可是能够统计 backlog。

 

1.4 术语

      为了正确地理解后面所提到的名词和配置,先对要用到的一些术语名词作必定的说明:

队列规定

      管理设备输入(ingress)或输出(egress)的一个算法。

无类的队列规定

      一个内部不包含可配置子类的队列规定。

分类的队列规定

      一个分类的队列规定内能够包含更多的类。其中每一个类又进一步地包含一个队列规定,这个队列规定能够是分类的,也能够是无类的。根据这个定义,严格地说 pfifo_fast 算是分类的,由于它实际上包含 3 个频道(实际上能够认为是子类)。然而从用户的角度来看它是无类的,由于其内部的子类没法用 tc 工具进行配置。

      一个分类的队列规定能够拥有不少类,类内包含队列规定。

分类器

      每一个分类的队列规定都须要决定什么样的包使用什么类进行发送。分类器就是作这个用的。

过滤器

      分类是经过过滤器完成的。一个过滤器包含若干的匹配条件,若是符合匹配条件,就按此过滤器分类。

调度

      在分类器的帮助下,一个队列规定能够裁定某些数据包能够排在其余数据包以前发送,这种处理叫作“调度”。好比前面提到的 pfifo_fast 就是这样的。

整形

      在一个数据包发送以前进行适当的延迟,以避免超过事先规定好的最大速率。整形在 egress 处进行。习惯上,经过丢包来降速也常常被称为整形。

策略

      经过延迟或是丢弃数据包来保证流量不超过事先规定的带宽。在 Linux 中,策略老是规定丢弃数据包而不是延迟,即不存在 ingress 队列。

Work-Conserving

      对于一个 work-conserving 队列规定,若是获得一个数据包,它老是当即对它进行分发。换句话说,只要网卡(egress队列规定)运行,它就不会延迟数据包的发送。

non- Work-Conserving

      有些队列(好比令牌桶过滤器)可能须要暂时中止发包以实现限制带宽。也就是说它们有时候即便有数据包须要处理,也可能拒绝发送。

      如今咱们简单了解了一些术语,下面看看它们的位置:

      整个大方框表示内核,最左边的箭头表示从网络上进入机器的数据包。它们进入 ingress 队列规定,并可有能被某些过滤器丢弃,即所谓的策略。数据包顺利经过后,若是它是发往本地进程的,就会进入 IP 协议栈处理并提交给该进程。若是它须要转发而不是进入本地进程,就会发往 egress。本地进程也能够发送数据,交给 egress 分类器。而后通过审查,并放入若干队列规定中的一个进行排队,这个过程叫作“入队”。在不进行如何配置的状况下,只有一个 egress 队列规定--pfifo_fast 接收数据包。数据包进入队列后,就等待内核处理并经过某网卡发送,这个过程叫作“出队”。

      这张图仅仅表示机器只有一块网卡的状况,图中的箭头不能表明全部的状况。每块网卡都有本身的 ingress 和 egress。

相关文章
相关标签/搜索