tc(traffic control)使用

流量控制(Traffic Control, tc)是Linux内核提供的流量限速、整形和策略控制机制。它以qdisc-class-filter的树形结构来实现对流量的分层控制 。

功能

限制

对流量进行限速,这样可以平滑突发流量数据,使网络更为稳定。只适用于向外的流量。

调度

通过调度数据包的传输,可以在带宽范围内按照优先级分配带宽。只适用于向外的流量。

策略(policing)

用于处理接收的数据。

丢弃

如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是向外。

基本组成

  • qdisc通过队列将数据包缓存起来,用来控制网络收发的速度
  • class用来表示控制策略
  • filter用来将数据包划分到具体的控制策略中

qdisc

qdisc通过队列将数据包缓存起来,用来控制网络收发的速度。实际上,每个网卡都有一个关联的qdisc。它包括以下几种:

  • 无分类qdisc(只能应用于root队列)
    • [p|b]fifo:简单先进先出
    • pfifo_fast:根据数据包的tos将队列划分到3个band,每个band内部先进先出
    • red:Random Early Detection,带带宽接近限制时随机丢包,适合高带宽应用
    • sfq:Stochastic Fairness Queueing,按照会话对流量排序并循环发送每个会话的数据包
    • tbf:Token Bucket Filter,只允许以不超过事先设定的速率到来的数据包通过 , 但可能允许短暂突发流量朝过设定值
  • 有分类qdisc(可以包括多个队列)
    • cbq:Class Based Queueing,借助EWMA(exponential weighted moving average, 指数加权移动均值 ) 算法确认链路的闲置时间足够长 , 以达到降低链路实际带宽的目的。如果发生越限 ,CBQ 就会禁止发包一段时间。
    • htb:Hierarchy Token Bucket,在tbf的基础上增加了分层
    • prio:分类优先算法并不进行整形 , 它仅仅根据你配置的过滤器把流量进一步细分。缺省会自动创建三个FIFO类。

注意,一般说到qdisc都是指egress qdisc。每块网卡实际上还可以添加一个ingress qdisc,不过它有诸多的限制

  • ingress qdisc不能包含子类,而只能作过滤
  • ingress qdisc只能用于简单的整形

如果相对ingress方向作流量控制的话,可以借助ifb( Intermediate Functional Block)内核模块。因为流入网络接口的流量是无法直接控制的,那么就需要把流入的包导入(通过 tc action)到一个中间的队列,该队列在 ifb 设备上,然后让这些包重走 tc 层,最后流入的包再重新入栈,流出的包重新出栈。

不可分类队列

sfq

Stochastic Fairness Queueing,按照会话对流量排序并循环发送每个会话的数据包。因为使用了散列算法,所以可能多个会话分配在同一个队列,从而共享发包的机会,也就是共享带宽,为了不让这种效应太明显,sfq会频繁地改变散列算法。
注意,只有当出口网卡确实已经挤满了的时候,sfq才会起作用,否则在你的linux机器中根本就不会有队列,sfq也就不会起作用。
参数:

  • perttum: 多少秒后重新配置一次散列算法,如果取消设置,散列算法将永远不会重新配置。10s比较合适。
  • quantum:一个流至少要传输多少字节后才切换到下一个队列。缺省值为一个最大包的长度。这个值不能小于MTU。

配置范例

tc qdisc add dev bond0 root sfq perturb 10
tbf

Token Bucket Filter,令牌桶过滤器,只允许以不超过事先设定的速率到来的数据包通过 , 但可能允许短暂突发流量不超过设定值。
一个缓冲器,不断地被一些叫做令牌的虚拟数据以特定速率填充。桶最重要的参数就是它的大小,也就是能存储令牌的数量。
每个到来的令牌从数据队列中手机一个数据包,然后从同种被删除。这个算法关联到连个流上:令牌流和数据流,于是我们得到3种情景:

  • 数据流=令牌流,这样,每个到来的数据都可以无延迟的通过队列。
  • 数据流<令牌流,数据传输只是用掉了一部分令牌,剩下的会在桶里积累下来直到满了,剩下的可以在需要以高于令牌流速率发送数据流的时候消耗掉,这种情况称为突发传输。
  • 数据流>令牌流,这意味着桶内的令牌很快就会被耗尽,导致中断,称为越限,如果数据包持续到来,将发生丢包。

参数:

  • limit/latency

limit确定最多有多少数据在队列中等待,latency参数确定了一个包在tbf中等待传输的最长等待时间,后者计算决定桶的大小,速率和峰值速率。

  • burst/buffer/maxburst

桶的大小,以字节计,这个参数制定了最多可以有多少个令牌能够即刻被使用。

  • mpu

决定了令牌的最低消耗。

  • rate

速度操控杆

  • perkrate

峰值速率可以用来指定令牌以多快的速度被删除。释放一个 数据包,之后等待足够的时间后再释放下一个。

  • mtu/minburst

要实现更高的峰值速率,可以在一个时钟周期内发送多个数据包。最有效的办法就是:再创建一个令牌桶。
示例:

tc qdisc add dev bond0 root tbf rate 220kbit latency 50ms burst 1540

filter

filter用来将数据包划分到具体的控制策略中,包括以下几种:

  • u32:根据协议、IP、端口等过滤数据包
  • fwmark:根据iptables MARK来过滤数据包
  • tos:根据tos字段过滤数据包

class

class用来表示控制策略,只用于有分类的qdisc上。每个class要么包含多个子类,要么只包含一个子qdisc。当然,每个class还包括一些列的filter,控制数据包流向不同的子类,或者是直接丢掉。

使用

步骤

  • 为网卡配置一个队列;
  • 在该队列上建立分类;
  • 根据需要建立子队列和子分类;
  • 为每个分类建立过滤器。

队列

查看

tc [-s | -d] qdisc show [dev DEV]

设置

tc qdisc [add|change|replace|link] dev DEV [parent qdisk-id|root][handle qdisc-id] qdisc[qdisc specific parameters]

示例如下:

tc qdisc add dev eth0 root handle 1:htb default 11

这里,命令中的”add 表示要添加,”dev eth0 表示要操作的网卡为eth0。”root 表示为网卡eth0添加的是一个根队列。”handle 1: 表示队列的句柄为1:。”htb 表示要添加的队列为HTB队列。命令最后的”default 11 是htb特有的队列参数,意思是所有未分类的流量都将分配给类别1:11。
不可分类QDisc只能附属于设备的根。它们的用法如下:

tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

要删除一个不可分类QDisc,需要使用如下命令:

tc qdisc del dev DEV root

查看

tc [-s | -d]  class show [dev DEV]

配置

#tc class [add|change|replace] dev DEV parent qdisc-id [classid class-id] qdisc [qdisc specific parameters]

示例

#tc class add dev eth0 parent 1: classid 1:1 htb rate 40mbit ceil 40mbit

#tc class add dev eth0 parent 1: classid 1:12 htb rate 40mbit ceil 40mbit

#tc class add dev eth0 parent 1: cllassid 1:13 htb rate 20mbit ceil 20mbit

命令中,”parent 1:”表示类别的父亲为根队列1:。”classid1:11″表示创建一个标识为1:11的类别,”rate 40mbit”表示系统将为该类别确保带宽40mbit,”ceil 40mbit”,表示该类别的最高可占用带宽为40mbit。

过滤器

查看

tc filter [-s | -d] show [dev DEV]
tc filter [add|change|replace] dev DEV [parent qdisc-id|root] protocol protocol prio priority filtertype [filtertype specific parameters] flowid flow-id

示例

#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:11
#tc filter add dev eth0 prtocol ip parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:12
#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 23 oxffff flowid 1:13

这里,”protocol ip”表示该过滤器应该检查报文分组的协议字段。”prio 1″ 表示它们对报文处理的优先级是相同的,对于不同优先级的过滤器, 系统将按照从小到大的优先级。
顺序来执行过滤器, 对于相同的优先级,系统将按照命令的先后顺序执行。这几个过滤器还用到了u32选择器(命令中u32后面的部分)来匹配不同的数据流。以第一个命令为例,判断的是dport字段,如果该字段与Oxffff进行与操作的结果是8O,则”flowid 1:11″ 表示将把该数据流分配给类别1:1 1。

命名规则

所有的QDisc、类和过滤器都有ID。ID可以手工设置,也可以有内核自动分配。ID由一个主序列号和一个从序列号组成,两个数字用一个冒号分开。

  • QDISC: 一个QDisc会被分配一个主序列号,叫做句柄(handle),然后把从序列号作为类的命名空间。句柄采用象10:一样的表达方式。习惯上,需要为有子类的QDisc显式地分配一个句柄。
  • class: 在同一个QDisc里面的类分享这个QDisc的主序列号,但是每个类都有自己的从序列号,叫做类识别符(classid)。类识别符只与父QDisc有关,和父类无关。类的命名习惯和QDisc的相同。
  • filter: 过滤器的ID有三部分,只有在对过滤器进行散列组织才会用到。

在TC 中, 使用”major:minor”这样的句柄来标识队列和类别,其中major和minor都是数字。
对于队列来说,minor总是为0,即”major:0″这样的形式,也可以简写为”major: 比如,队列1:0可以简写为1:。需要注意的是,major在一个网卡的所有队列中必须是惟一的。对于类别来说,其major必须和它的父类别或父队列的major相同,而minor在一个队列内部则必须是惟一的(因为类别肯定是包含在某个队列中的)。

参数

tc可以使用以下命令对QDisc、类和过滤器进行操作:

  • add: 在一个节点里加入一个QDisc、类或者过滤器。添加时,需要传递一个祖先作为参数,传递参数时既可以使用ID也可以直接传递设备的根。如果要建立一个QDisc或者过滤器,可以使用句柄(handle)来命名;如果要建立一个类,可以使用类识别符(classid)来命名。
  • remove: 删除有某个句柄(handle)指定的QDisc,根QDisc(root)也可以删除。被删除QDisc上的所有子类以及附属于各个类的过滤器都会被自动删除。
  • change: 以替代的方式修改某些条目。除了句柄(handle)和祖先不能修改以外,change命令的语法和add命令相同。换句话说,change命令不能一定节点的位置。
  • replace: 对一个现有节点进行近于原子操作的删除/添加。如果节点不存在,这个命令就会建立节点。
  • link: 只适用于DQisc,替代一个现有的节点。

单位说明

Kbps kiIobytes per second, 即”千字节每秒 ;
Mbps megabytes per second, 即”兆字节每秒 ,
Kbit kilobits per second,即”千比特每秒 ;
Mbit megabits per second, 即”兆比特每秒 。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值