首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux不同流控算法(2)分类算法 —— PRIO/CBQ/HTB

linux不同流控算法(2)分类算法 —— PRIO/CBQ/HTB

分类算法主要作用是可以对多种数据流区别对待 . 一旦数据包进入一个分类的队列规定 , 它就得被送到某一个类中分类 , 对数据包进行分类的工具是过滤器 . 过滤器会返回一个决定 , 队列规定就根据这个决定把数据包送入相应的类进行排队 . 每个子类都可以再次使用它们的过滤器进行进一步的分类 . 直到不需要进一步分类时 , 数据包才进入该类包含的队列规定排队 . 除了能够包含其它队列规定之外 , 绝大多数分类的队列规定能够流量整形
注 : 过滤器对数据包进行分类的工具 , 是从队列规定内部调用的 , 而不是从别处 .( 用在分叉的分支上 )
列规定家族 : 根 , 句柄 , 兄弟和父辈
每块网卡都有一个出口"根队列规定", 缺省情况下是前面提到的 pfifo_fast 队列规定 . 每个队列规定都指定一个句柄 , 以便以后的配置语句能够引用这个队列规定 . 除了出口队列规定之外 , 每块网卡还有一个入口 , 以便 policies 进入的数据流 .
队列规定的句柄有两个部分 : 一个主号码和一个次号码 . 习惯上把根队列规定称为"1:", 等价于"1:0". 队列规定的次号码永远是 0. 类的主号码必须与它们父辈的主号码一致 .
数据包如何出队并交给硬件
当内核决定把一个数据包发给网卡的时候 , 根队列规定 1: 会得到一个出队请求 , 然后把它传给 1:1, 然后依次传给 10:,12: 和 13 子类自定义 ), 然后试图从它们中进行 dequeue() 操作 . 也就是说 , 内核需要遍历整颗树 , 换句话说 , 类及其兄弟仅仅与其"父队列规定"进行交谈 , 而不会与网卡进行交谈 . 只有根队列规定才能由内核进行出队操作 ! 更进一步 , 任何类的出队操作都不会比它们的父类更快 . 我们可以把 SFQ 作为一个子类 , 放到一个可以进行流量整形的父类中 , 从而能够同时得到 SFQ 的调度功能和其父类的流量整形功能 .
a. 队列控制的分类算法 PRIO
PRIO 分类优先算法 ( 从左至右优先发包 ), 队列规定并不进行整形 , 它仅仅根据你配置的过滤器把流量进一步细分 . 你可以认为 PRIO 队列规定是 pfifo_fast 的一种衍生物 , 区别在每个频道都是一个单独的类 , 而非简单的 FIFO.
当数据包进入 PRIO 队列规定后 , 将根据你给定的过滤器设置选择一个类 . 缺省情况下有三个类 , 这些类仅包含纯 FIFO 队列规定而没有更多的内部结构 . 你可以把它们替换成你需要的任何队列规定 . 每当有一个数据包需要出队时 , 首先处理 :1 类 . 只有当标号更小的类中没有需要处理的包时 , 才会标号大的类 .
PRIO 配置范例示意图:大批量数据使用 30:, 交互数据使用 20: 或 10:.
清单 3. 在网卡建立 PRIO
1
2
3
4
5
6
#tc qdisc add dev eth0 root handle 1: prio
# 此命令立即创建了类 : 1:1, 1:2, 1:3 ( 缺省三个子类 )
#tc qdisc add dev eth0 parent 1:1 handle 10: sfq
#tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000
   注 : 此为 TBF 限速的另一写法 , 前文有讲解 .
#tc qdisc add dev eth0 parent 1:3 handle 30: sfq




主要参数有 后续有实例 )
   bands 创建频道的数目 . 每个频道实际上就是一个类 跟 priomap 参数配合使用
     注 : 频道是类 , 缺省情况下命名为主标号 :1 到主标号 :3. 如果你的 PRIO 队列规定是 12:, 把数据包过滤到
       12:1 将得到最高优先级 . 0 频道的次标号是 1!1 频道的次标号是 2, 以此类推 .
   priomap 给 tc 提供过滤器 , 如不提供 PRIO 队列规定将参考 TC_PRIO 的优先级来决定如何给数据包入队 .
b. 流量整形的分类算法 CBQ
CBQ 的工作机制是确认链路的闲置时间足够长 , 以达到降低链路实际带宽的目的 . 为此 , 它要计算两个数据包的平均发送间隔 . 操作期间 , 有效闲置时间的测量使用 EWMA(exponential weighted moving average, 指数加权移动均值 ) 算法 , 也就是说最近处理的数据包的权值比以前的数据包按指数增加 .UNIX 的平均负载也是这样算出来的 . 计算出来的平均时间值减去 EWMA 测量值 , 得出的结果叫做"avgidle". 最佳的链路负载情况下 , 这个值应当是 0: 数据包严格按照计算出来的时间间隔到来 . 在一个过载的链路上 ,avgidle 值应当是负的 . 如果这个负值太严重 ,CBQ 就会暂时禁止发包 , 称为"overlimit"( 越限 ). 相反地 , 一个闲置的链路应该有很大 avgidle 值 , 这样闲置几个小时后 , 会造成链路允许非常大的带宽通过 . 为了避免这种局面 , 我们用 maxidle 来限 avgidle
的值不能太大 .
理论上讲 , 如果发生越限 ,CBQ 就会禁止发包一段时间 ( 长度就是事先计算出来的传输数据包之间的时间间隔 ), 然后通过一个数据包后再次禁止发包 .
清单 4. WEB 服务器的流量控制为 5Mbps,SMTP 流量控制在 3Mbps 上 . 而且二者一共不得超过 6Mbps, 互相之间允许借用带宽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 cell 8
#tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 6Mbit weight  
   0.6Mbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded
   这部分按惯例设置了根为 1:0, 并且绑定了类 1:1. 也就是说整个带宽不能超过 6Mbps.
#tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit rate 5Mbit weight
   0.5Mbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000
#tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit rate 3Mbit weight
   0.3Mbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000
   建立了 2 个类 . 注意我们如何根据带宽来调整 weight 参数的 . 两个类都没有配置成"bounded", 但它们都连
接到了类 1:1 上 , 而 1:1 设置了"bounded". 所以两个类的总带宽不会超过 6Mbps. 别忘了 , 同一个 CBQ 下面的子
类的主号码都必须与 CBQ 自己的号码相一致 !
#tc qdisc add dev eth0 parent 1:3 handle 30: sfq
#tc qdisc add dev eth0 parent 1:4 handle 40: sfq
   缺省情况下 , 两个类都有一个 FIFO 队列规定 . 但是我们把它换成 SFQ 队列 , 以保证每个数据流都公平对待 .
#tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip sport 80 0xffff flowid
   1:3
#tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip sport 25 0xffff flowid
   1:4




CBQ 流量整形算法相对比较复杂 , 工作中还常用 ... 示例中的各参数请参阅 :HOWTO 中文文档 ..Linux 流量控制 II--- 分类算法 PRIO/CBQ/HTB
c. 流量整形的分类算法 HTB
HTB(Hierarchical Token Bucket) 分层的令牌桶一个分类的令牌桶过滤器 , 工作原理和相关配置同于 TBF.. 拥有 TBF 的各项性能 , 可参阅 TBF 的工作细节 ...
清单 5. 环境与要求同上述 CBQ 的例子
1
2
3
4
5
6
7
8
9
10
11
12
#tc qdisc add dev eth0 root handle 1: htb default 30
  #tc class add dev eth0 parent 1: classid 1:1 htb rate 6mbit burst 15k
  #tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k
  #tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k
  #tc class add dev eth0 parent 1:1 classid 1:30 htb rate 1kbit ceil 6mbit burst 15k
  #tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
  #tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
  #tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10
  # 添加过滤器 , 直接把流量导向相应的类 :
  #U32="tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32"
  #$U32 match ip dport 80 0xffff flowid 1:10
  #$U32 match ip sport 25 0xffff flowid 1:20

返回列表