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

Linux 高级流控-1

Linux 高级流控-1

Linux 高级流量控制本篇主要讲用 TC 对 Linux 进行高级流量控制
通过大量实践结合 TC 流控 HOWTO 文档整理而得
如果你对 Linux 流控感兴趣,如果你需要搭建高性能的 Linux 网关 , 本文将会使你受益颇多。
注:至少具备 Linux OS 的中级水平知识,熟悉 TCP/IP, Linux 网卡工作原理,以及配置 Linux 网关的经验,将有助于对本文的理解。
本文参考文档:
Tc 流控 HOWTO 文档 http://www.tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/
Linux TC 流量控制工具 http://wenku.baidu.com/view/f02078db50e2524de5187e45.html
一 . Linux 流控简介Linux 流控的意义 :
有效的控制 Linux 网卡进出流量 , 了解网卡工作原理 , 搭建高性能的 Linux 网关 , 对 Linux 高级系统流控有进一步的认识。
Linux 流量控制方法 :
控发不控收 , 所以只能对产生瓶颈网卡处的发包速率进行控制 , 而网络瓶颈分析亦为 Linux 网络流控的第一步 .
Linux 流量控制过程分二种:
  • 队列控制  即 QOS, 瓶颈处的发送队列的规则控制,常见的有 SFQ  PRIO
  • 流量控制  即带宽控制 ,  队列的排队整形, 一般为 TBF HTB                       Linux 流量控制算法分二种:
  • 无类算法  用于树叶级无分支的队列,例如:SFQ
  • 分类算法  用于多分支的队列,例如:PRIO TBF HTB
Linux 流控实现工具 TC:
Linux 下流量控制工具 , 从 Linux2.2 版开始已并入内核,功能非常强大, 详见参考文档。
二 . 以下文章将以二种算法的不同流控分别介绍:1. 无类算法 SFQa. 队列控制的无类算法 SFQ
SFQ(Stochastic Fairness Queueing 随机公平队列 ) 是公平队列算法家族中的一个简单实现 . 它的精确性不如其它的方法 , 但实现了高度的公平 , 需要的计算量亦很少 .
SFQ 算法主要针对一个 TCP 会话或者 UDP 流 . 流量被分成相当多数量的 FIFO 队列中 , 每个队列对应一个会话 . 数据按照简单轮转的方式发送 , 每个会话都按顺序得到发送机会 . 这种方式非常公平 , 保证了每一个会话都不会没其它会话所淹没 .
SFQ 之所以被称为"随机", 是因为它并不是真的为每一个会话创建一个队列 , 而是使用一个散列算法 , 把所有的会话映射到有限的几个队列中去 . 因为使用了散列 , 所以可能多个会话分配在同一个队列里 , 从而需要共享发包的机会 , 也就是共享带宽 . 为了不让这种效应太明显 ,SFQ 会频繁地改变散列算法 , 以便把这种效应控制在几秒钟之内 ( 时间由参数设定 ).
注 :SFQ 只会发生在数据发生拥堵 , 产生等待队列的网卡上 .. 出口网卡若无等待队列 ,SFQ 亦不起作用 ...
清单 1. 在网卡上建立 SFQ
1
2
3
4
5
#tc qdisc add dev eth0 root handle 1: sfq
SFQ 参数有 perturb( 重新调整算法间隔 ) quantum  基本上不需要手工调整 :
handle 1: 规定算法编号 .. 可以不用设置由系统指定 ..
#tc qdisc sh dev eth0 显示算法
#tc qd del dev eth0 root 删除  注 : 默认 eht0 支持 TOS




SFQ 队列一般用在树叶级 , 配合其它流量整形算法一并使用……
b. 流量控制的无类算法 TBF
令牌桶过滤器 (TBF) 是一个简单的队列规定 : 只允许以不超过事先设定的速率到来的数据包通过 , 但可能允许短暂突发流量朝过设定值 .
TBF 很精确 , 对于网络和处理器的影响都很小 , 实现是针对数据的字节数进行的 , 而不是针对数据包进行 , 常用于网关限速 .
TBF 的实现在于一个缓冲器 ( 桶 ), 不断地被一些叫做"令牌"的虚拟数据以特定速率填充着 . (token rate). 桶最重要的参数就是它的大小 , 也就是它能够存储令牌的数量 . 每个到来的令牌从数据队列中收集一个数据包 , 然后从桶中被删除 . 这个算法关联到两个流上——令牌流和数据流 , 于是我们得到 3 种情景 :
A. 数据流以等于令牌流的速率到达 TBF. 这种情况下 , 每个到来的数据包都能对应一个令牌 , 然后无延迟地通过队列 .
B. 数据流以小于令牌流的速度到达 TBF. 通过队列的数据包只消耗了一部分令牌 , 剩下的令牌会在桶里积累下来 , 直到桶被装满 . 剩下的令牌可以在需要以高于令牌流速率发送数据流的时候消耗掉 , 这种情况下会发生突发传输 .
C. 数据流以大于令牌流的速率到达 TBF. 这意味着桶里的令牌很快就会被耗尽 . 导致 TBF 中断一段时间 , 称为"越限". 如果数据包持续到来 , 将发生丢包 . 此种情况最重要 , 因为它可以用来对数据通过过滤器的速率进行整形 . 令牌的积累可以导致越限的数据进行短时间的突发传输而不必丢包 , 但是持续越限的话会导致传输延迟直至丢包 .
清单 2. 在网卡建立 TBF
1
2
3
4
#tc qd add dev eth1 root handle 1: tbf rate 256kbit burst 10000 latency 50ms
         速率 256kbit  突发传输 10k  最大延迟 50ms
#tc -s qd sh dev eth1 统计
#tc qd del dev eth1 root 删除




rate 限制的传输速率 用位来计算
latency 确定了一个包在 TBF 中等待传输的最长等待时间 .
burst 桶的大小 , 以字节计 . 指定了最多可以有多少个令牌能够即刻被使用 .
注 : 管理的带宽越大 , 需要的缓冲器就越大 . 在 Intel 体系上 ,10 兆 bit/s 的速率需要至少 10k 字节的缓冲区
才能达到期望的速率 . 缓冲区太小导致潜在的丢包 .
c. 无类算法除这二种队列以外 , 另有 pfifo_fast( 网卡出口默认根队列规定 )
经常使用的也就是 SFQ/TBF ……
这二种用法如下:
单纯地降低出口速率 , 使用令牌桶过滤器 . 调整桶的配置后可用于控制很高的带宽 .
链路已经塞满 , 保证不会有某一个会话独占出口带宽 , 使用随机公平队列 .
当然最要的还是工作中得来的经验 , 就其应用方面只要能满足需求即可 .. 要做到灵活应用还得大量的实践 ..
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:.



返回列表