linux 限制帶寬方案


linux 限制帶寬方案
20130325 Chenxin

1.ethtool (mii-tool工具只支持百兆網絡,千兆的網卡顯示為百兆,但實際兩台物理機間可達到千兆)
2.tc
3.iptables(iptables需要結合tc來做限速,單純使用iptables限速非常不可靠也不穩定)

0.大文件生成(測試用):
帶寬測試比較准確的是拷貝大文件,用dd命令生成大文件,再通過網絡內外網互相拷貝,觀察帶寬占用情況;
dd if=/dev/zero of=test.file bs=20M count=50
其中if參數是讀取的文件,of參數是寫入的文件,bs是每次讀取大小,count是讀取次數;
生成1GB大小的文件,測試內網網網速;

1.ethtool 對網卡工作模式限速方式(這種局限為只能將千兆網卡調到百兆的工作方式,比較可靠)
查看網卡當前工作模式:
查看命令:
ethtool em1

使用概要:
ethtool ethx //查詢ethx網口基本設置,其中 x 是對應網卡的編號,如eth0、eth1等等
ethtool –h //顯示ethtool的命令幫助(help)
ethtool –i ethX //查詢ethX網口的相關信息
ethtool –d ethX //查詢ethX網口注冊性信息
ethtool –r ethX //重置ethX網口到自適應模式
ethtool –S ethX //查詢ethX網口收發包統計
ethtool –s ethX [speed 10|100|1000] [duplex half|full] [autoneg on|off] //設置網口速率,設置網口半/全雙工,設置網口是否自協商

限速百兆:
ethtool -s em2 speed 100 autoneg off
然后再用ethtool em2檢查是否生效(autoneg:auto negotiation自動協商)

恢復千兆:
執行: ethtool -s em2 speed 1000 autoneg on ;

另外,mii-tool也可以限速100M (有些機器不生效,不知道為何)
mii-tool -F 100baseTx-FD em1
恢復千兆:
mii-tool -r em1

另外,wondershaper工具也可以限制,不過超過2Mbps的帶寬限制后(比如限制20Mbps的時候,實際可以達到400Mbps),就感覺幾乎沒有任何作用了.
wondershaper em1 20000 20000
清空策略:
wondershaper clear em1
Wondershaper queues have been cleared.(實際使用的也是tc的腳本做的)

開機自動:
設置為開機啟動就為100M/s的方式:

vi /etc/sysconfig/network-scripts/ifcfg-em2

添加一行
ETHTOOL_OPTS="speed 100 duplex full autoneg off"

測試后的結論:
如果對帶寬要求很低的,比如5M以下的,ethtool和mii-tool都可以滿足.
wondershaper只滿足配置為2000kpbs的情況,再往上,直接就到千兆了,沒意義了.
tc控制比較靈活,但語法和坑太多.
trickle可以針對進程進行限速,但效果有限,也是小流量可以.
iptabbles大家都懂,就不說了.

延伸:
有什么辦法可以把網卡的帶寬限制為200Mbps呢? 可以采用集群的方式增加100M

2.tc (可以自定義總限制帶寬,所有IP地址平均分配帶寬)
限制所有客戶端的下載帶寬(所有IP的下載總帶寬,不是單個IP的下載帶寬)(天啟上線可以考慮采用此方案):
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 2000kbit burst 100k #總限制為2Mbps,100k
tc qdisc add dev eth0 parent 1:1 handle 10: sfq perturb 10 #讓client盡量平均分配帶寬,防止1個獨占
tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 0.0.0.0/0 flowid 1:1#所有ip,u32是一個標記位

查看過濾器情況:
tc filter list dev eth0
filter parent 1: protocol ip pref 16 u32
filter parent 1: protocol ip pref 16 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 16 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
match 00000000/00000000 at 16

刪除順序:
先刪除過濾器,再刪除qdisc,將add改成del就可以了.

dst:
之后可以是單獨的IP地址192.168.80.121,或者是地址段192.168.80.0/24,或者是所有地址 0.0.0.0/0

tc參數解析與實例分析

翻閱了很多 TC流量管理的文章,發現講解案例的文章很多,但是針對 TC參數的講解就寥寥無幾,甚至連 TC的 Howto文件也未能詳細的介紹參數的使用區 別。結果使初步接觸者看的頭暈腦脹,不知道那些參數究竟要用在哪些位置。結果實際操作起來還是糊里糊塗。當然,本人當初也經歷這個過程。
下面我將通過一個案例來盡可能詳細的講解一下 linux TC命令的參數應用,希望能對大家有所幫助。
tc介紹
  在linux中, TC有二種控制方法 CBQ和 HTB。而 HTB是設計用來替換 CBQ的。它是一個層次式的過濾框架。設置起來比較直觀簡單。
  TC包括三個基本的構成塊: 隊列規定 qdisc(queueing discipline ) 、類(class) 和分類器(Classifilters).
隊列(queueing discipline) :
用來實現控制網絡的收發速度。 通過隊列,linux可以將網絡數據包緩存起來,然后根據用戶的設置,在盡量不中斷連接 (如 TCP)的前提下來平滑網絡流量 。需要注意的是, linux對接收隊列的控制不夠好,所以我們一般只用發送隊列,即 “控發不控收 ”。它封裝了其他兩個主要 TC組件 (類和分類器 )。內核如果需要通過某個網絡接口發送數據包,它都需要按照為這個接口配置的 qdisc(排隊規則 )把數據包加入隊列。然后,內核會盡可能多地從 qdisc里面取出數據包,把它們交給網絡適配器驅動模塊。
  最簡單的 QDisc是 pfifo它不對進入的數據包做任何的處理,數據包采用先入先出的方式通過隊列。不過,它會保存網絡接口一時無法處理的數據包。
  隊列規則包括: FIFO(先進先出 ), RED(隨機早期探測 ), SFQ(隨機公平隊列 )和令牌桶 (Token Bucket),類基基礎隊列 (CBQ), CBQ 是一種超級隊列,這好比一棵樹, CBQ是樹干,而且可以嫁接其他新的樹枝或樹干,當然也可以直接生長出樹葉(最終的規則)來。而 FIFO只能充當樹葉的較色,在它下面不能再添加分類了。
  class用來表示控制策略 。很顯然,很多時候,我們很可能要對不同的 IP實行不同的流量控制策略,這時候我們就得用不同的 class來表示不同的控制策略了。
  filter用來將用戶划入到具體的控制策略中 (即不同的 class中) 。比如,現在,我們想對 192.168.1.33, 192.168.1.34 兩個 IP實行不同的控制策略 (A, B),這時,我們可用 filter將 33划入到控制策略 A,將 44划入到控制策略 B, filter划分的標志位可用u32打標功能 或IPtables 的 set-mark 功能來實現。(大多使用 iptables來做標記,因為比較有效,這在以后你會慢慢體會到,呵呵 )
  目前, TC可以使用的過濾器有: fwmark分類器, u32分類器,基於路由的分類器和 RSVP分類器 (分別用於 IPV6、 IPV4)等 ;其中, fwmark分類器允許我們使用 Linux netfilter 代碼選擇流量,而 u32分類器允許我們選擇基於 ANY 頭的流量 .需要注意的是, filter(過濾器 )是在 QDisc內部,它們不能作為主體。
數據包 ->iptables(在通過iptables 時,iptables根據不同的 ip來設置不同的 mark)->TC root qdisc->
TC(class)->TC(queue)

tc應用
假設eth0 位是服務器的外網網絡接口。
首先設置eth0的qdiscA.qdiscA控制通過本機到外網的速度,因此是用來控制服務器流出速度的.

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

tc 隊列 添加 設置接口 root最上層 句柄(做標記用):標記類型 默認使用1的class

解釋如下:
無論是隊列,還是class和filter都有ID之類的標志符,一般都有parent(父,上層的).注意ID具有接口本地性,不同的網絡接口可以有相同的ID.對於這里因為qdisc在頂部,所以沒有parent,用 ‘root’ 字樣來標識,ID用"1:"來標記.
default 1表示當某個ip流不滿足任何已設定的filter規則時,將自動歸入class 1中(這里叫class 1?)。
handle暫且翻譯為"叫做"吧.

然后在qdisc下建立兩個class,來指定eth0控制通過本機到外網的速度.

tc class add dev eth0 parent 1:0 classid 1:30 htb rate 2mbit ceil 4mbit prio 2

注:以上就是我們控制輸出的規則:
在eth0上,添加的這個class的parent隊列是1:0 (指定父是1:0).
添加的分類命名為1:30 .
類型為 htb .速度為 2M.最大可以到 4M.優先級為 2.
rate: 是一個類保證得到的帶寬值。如果有不只一個類,請保證所有子類總和是小於或等於父類。
prio:用來指示借用帶寬時的競爭力, prio越小,優先級越高,競爭力越強。
ceil: ceil 是一個類最大能得到的帶寬值。

接着針對不同的應用在各 root class下設置不同的類 ,如下。

tc class add dev eth0 parent 1:30 classid 1:31 htb rate 0.5mbit ceil 2mbit prio 3

在1:30分類下面創建更細的分類1:31,類型為htb,規定速度0.5mbit,最高2mbit,優先級為3.

為了不使一個大的數據包傳遞過程 (會話 )永占帶寬, 在1:31下面添加隨即公平隊列sfq.平均分配帶寬.

tc qdisc add dev eth0 parent 1:31 handle 31: sfq perturb 10

以上是在子分類 1:30(應是 1:31吧 ?)下面繼續添加名稱為 "31:" 的隊列。模式為sfq,這是一個循環均衡排隊數據包的隊列,它不偏向任何數據隊列,循環抓取各個隊列的數據包。這個循環的時間間隔是 10秒鍾一次,我們可以任意調節這個時間參數,比如 2、 4、 5、 6、 8秒 ......只要不過與頻繁與遲鈍就好

接着添加過濾器

tc filter add dev eth0 parent 1: protocol ip prio 31 handle 31 fw flowid 1:31

添加“ 過濾分類規則”到root qdisc處(也就是 1:0),協議類型為ip,優先級為31。給這個隊列起名31采用的是 fw(防火牆篩選)規則,一旦符合篩選,則進入1:31分類。(還記得 1:31分類么?就是剛剛在上面添加的,限速 0.5M的那個)

用iptable打標,也可以使用 u32之類

iptables -t mangle -I FORWARD -i !eth1 -p tcp –sport 80 -s 192.168.80.33 –j MARK –set-mark 31(使用iptables命令,對於傳遞過程中不是來自eth1的ip且來源地址為192.168.80.33來源ip端口為80的數據全部做上31標記。用以實現此數據經過以上過濾器時被分配到1:31這個0.5m的限速中)

tc對最對高速度的控制

ceil 限速
指定了一個類可以用的最大帶寬, 用來限制類可以借用多少帶寬。缺省的 ceil是和速率一樣
  這個特性對於 ISP是很有用的, 因為他們一般限制被服務的用戶的總量即使其他用戶沒有請求服務。 (ISPS 很想用戶付更多的錢得到更好的服務 ) ,注根類是不允許被借用的, 所以沒有指定 ceil。 ceil的數值應該至少和它所在的類的速率一樣高, 也就是說 ceil應該至少和它的任何一個子類一樣高
Burst 突發
  網絡硬件只能在一個時間發送一個包這僅僅取決於一個硬件的速率。鏈路共享軟件可以利用這個能力動態產生多個連接運行在不同的速度。所以速率和 ceil 不是一個即時度量只是一個在一個時間里發送包的平均值。實際的情況是怎樣使一個流量很小的類在某個時間類以最大的速率提供給其他類。 burst 和 cburst 參數控制多少數據可以以硬件最大的速度不費力的發送給需要的其他類。
  如果cburst 小於一個理論上的數據包 1514b,他形成的突發不會超過 ceil 速率, 同樣的方法 TBF的最高速率也是這樣。
  你可能會問, 為什么需要 burst . 因為它可以很容易的提高響應速度在一個很擁擠的鏈路上。 比如 WWW 流量是突發的。你訪問主頁。 突發的獲得並閱讀。 在空閑的時間 burst將再 "charge"一次。
  注: burst 和 cburst至少要和其子類的值一樣大。

實例
下載限制單個 IP
  tc qdisc add dev eth0 root handle 1: htb r2q 1 (r2q ,是指沒有default的 root,使整個網絡的帶寬沒有限制)
  tc class add dev eth0 parent 1: classid 1:1 htb rate 30mbit ceil 60mbit
  tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 192.168.1.2 flowid 1:1
  就可以限制 192.168.1.2的下載速度為 30Mbit最高可以 60Mbit

限制整段IP
  tc qdisc add dev eth0 root handle 1: htb r2q 1
  tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil 1000mbit
  tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 192.168.8.0/24 flowid 1:1
  就可以限制 192.168.8.0 到 255 的帶寬為 3000k了,實際下載速度為 200k左右。
  這種情況下,這個網段所有機器共享這 200k的帶寬。
  還可以加入一個 sfq(隨機公平隊列)
  tc qdisc add dev eth0 root handle 1: htb r2q 1
  tc class add dev eth0 parent 1: classid 1:1 htb rate 3000kbit burst 10k
  tc qdisc add dev eth0 parent 1:1 handle 10: sfq perturb 10
  tc filter add dev eth0 parent 1:1 protocol ip prio 16 u32 match ip dst 192.168.8.168 flowid 1:1
  sfq ,他可以防止一個段內的一個 ip占用整個帶寬。

(完)

以下為備注:
tc參數說明(man手冊)

http://apps.hi.baidu.com/share/detail/375252

名稱:tc - 顯示/維護流量控制設置
命令格式:
tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]
tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]
tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id
tc [-s | -d ] qdisc show [ dev DEV ]
tc [-s | -d ] class show dev DEV tc filter show dev DEV

TC用途簡介:
Tc用於Linux內核的流量控制。
流量控制包括以下幾種方式:

SHAPING(限制)
當流量被限制,它的傳輸速率就被控制在某個值以下。限制值可以大大小於有效帶寬,這樣可以平滑突發數據流量,使網絡更為穩定。shaping(限制)只適用於向外的流量。

SCHEDULING(調度)
通過調度數據包的傳輸,可以在帶寬范圍內,按照優先級分配帶寬。SCHEDULING(調度)也只適於向外的流量。

POLICING(策略)
SHAPING用於處理向外的流量,而POLICIING(策略)用於處理接收到的數據。

DROPPING(丟棄)
如果流量超過某個設定的帶寬,就丟棄數據包,不管是向內還是向外。

流量的處理由三種對象控制 ,它們是:
qdisc(排隊規則)、class(類別)和filter(過濾器)。

QDISC(排隊規則)
QDisc(排隊規則)是queueing discipline(隊列規定)的簡寫,它是理解流量控制(traffic control)的基礎。
無論何時,內核如果需要通過某個網絡接口發送數據包,它都需要按照為這個接口配置的qdisc(排隊規則)把數據包加入隊列。
然后,內核會盡可能多地從qdisc里面取出數據包,把它們交給網絡適配器驅動模塊。
最簡單的QDisc是pfifo它不對進入的數據包做任何的處理,數據包采用先入先出的方式通過隊列。不過,它會保存網絡接口一時無法處理的數據包。

CLASS(類)
某些QDisc(排隊規則)可以包含一些類別,不同的類別中可以包含更深入的QDisc(排隊規則),通過這些細分的QDisc還可以為進入的隊列的數據包排隊。通過設置各種類別數據包的離隊次序,QDisc可以為設置網絡數據流量的優先級。

FILTER(過濾器)
filter(過濾器)用於為數據包分類,決定它們按照何種QDisc進入隊列。
無論何時數據包進入一個划分子類的類別中,都需要進行分類。
分類的方法可以有多種,使用fileter(過濾器)就是其中之一。
使用filter(過濾器)分類時,內核會調用附屬於這個類(class)的所有過濾器,直到返回一個判決。
如果沒有判決返回,就作進一步的處理,而處理方式和QDISC有關。
需要注意的是,filter(過濾器)是在QDisc內部,它們不能作為主體。

CLASSLESS QDisc(不可分類QDisc)
無類別QDISC包括:
[p|b]fifo
使用最簡單的qdisc,純粹的先進先出。
只有一個參數: limit,用來設置隊列的長度,pfifo是以數據包的個數為單位;bfifo是以字節數為單位。
pfifo_fast
在編譯內核時,如果打開了高級路由器(Advanced Router)編譯選項,pfifo_fast就是系統的標准QDISC。
它的隊列包括三個波段(band)。在每個波段里面,使用先進先出規則。
而三個波段(band)的優先級也不相同,band 0的優先級最高,band 2的最低。
如果band里面有數據包,系統就不會處理band 1里面的數據包,band 1和band 2之間也是一樣。
數據包是按照服務類型(Type of Service,TOS)被分配多三個波段(band)里面的。
red
red是Random Early Detection(隨機早期探測)的簡寫。
如果使用這種QDISC,當帶寬的占用接近於規定的帶寬時,系統會隨機地丟棄一些數據包。
它非常適合高帶寬應用。
sfq
sfq是Stochastic Fairness Queueing(隨機公平隊列)的簡寫。
是公平隊列算法家族中的一個簡單實現.
它的精確性不如其它的方法,但是它在實現高度公平的同時,需要的計算量卻很少.
它按照會話(session--對應於每個TCP連接或者UDP流)為流量進行排序,然后循環發送每個會話的數據包。
SFQ的關鍵詞是"會話"(或稱作"流") ,主要針對一個TCP會話或者UDP流.流量被分成相當多數量的FIFO隊列中,每個隊列對應一個會話.數據按照簡單輪轉的方式發送, 每個會話都按順序得到發送機會.
這種方式非常公平,保證了每一個會話都不會沒其它會話所淹沒.
SFQ之所以被稱為"隨機",是因為它並不是真的為每一個會話創建一個隊列,而是使用一個散列算法,把所有的會話映射到有限的幾個隊列中去.
因為使用了散列,所以可能多個會話分配在同一個隊列里,從而需要共享發包的機會,也就是共享帶寬.
為了不讓這種效應太明顯,SFQ會頻繁地改變散列算法,以便把這種效應控制在幾秒鍾之內.
有很重要的一點需要聲明:只有當你的出口網卡確實已經擠滿了的時候,SFQ才會起作用!否則在你的Linux機器中根本就不會有隊列,SFQ也就不會起作用.
稍后我們會描述如何把SFQ與其它的隊列規定結合在一起,以保證兩種情況下都比較好的結果.
特別地,在你使用DSL modem或者cable modem的以太網卡上設置SFQ而不進行任何進一步地流量整形是無謀的!
sfq參數與使用
SFQ基本上不需要手工調整:
perturb
多少秒后重新配置一次散列算法.
如果取消設置,散列算法將永遠不會重新配置(不建議這樣做).10秒應該是一個合適的值.
quantum
一個流至少要傳輸多少字節后才切換到下一個隊列.
默認設置為一個最大包的長度(MTU的大小).不要設置這個數值低於MTU!
sfq配置范例
如果你有一個網卡,它的鏈路速度與實際可用速率一致——比如一個電話MODEM——如下配置可以提高公平性:

tc qdisc add dev ppp0 root sfq perturb 10

tc -s -d qdisc ls

qdisc sfq 800c: dev ppp0 quantum 1514b limit 128p flows 128/1024 perturb 10sec
Sent 4812 bytes 62 pkts (dropped 0, overlimits 0)
"800c:"這個號碼是系統自動分配的一個句柄號,"limit"意思是這個隊列中可以有128個數據包排隊等待.一共可以有1024個散列目標可以用於速率審計,而其中128個可以同時激活.(no more packets fit in the queue!)每隔10秒種散列算法更換一次.

tbf(令牌桶過濾器)
tbf是Token Bucket Filter(令牌桶過濾器 )的簡寫,適合於把流速降低到某個值。令牌桶過濾器(TBF)是一個簡單的隊列規定:只允許以不超過事先設定的速率到來的數據包通過,但可能允許短暫突發流量朝過設定值.
TBF很精確,對於網絡和處理器的影響都很小.所以如果您想對一個網卡限速,它應該成為您的第一選擇!
TBF的實現在於一個緩沖器(桶),不斷地被一些叫做"令牌"的虛擬數據以特定速率填充着. (token rate).桶最重要的參數就是它的大小,也就是它能夠存儲令牌的數量.

每個到來的令牌從數據隊列中收集一個數據包,然后從桶中被刪除.這個算法關聯到兩個流上——令牌流和數據流.
於是我們得到3種情景:
數據流以等於令牌流的速率到達TBF.這種情況下,每個到來的數據包都能對應一個令牌,然后無延遲地通過隊列.
數據流以小於令牌流的速度到達TBF.通過隊列的數據包只消耗了一部分令牌,剩下的令牌會在桶里積累下來,直到桶被裝滿.剩下的令牌可以在需要以高於令牌流速率發送數據流的時候消耗掉,這種情況下會發生突發傳輸.
數據流以大於令牌流的速率到達TBF.這意味着桶里的令牌很快就會被耗盡.導致TBF中斷一段時間,稱為"越限".如果數據包持續到來,將發生丟包.

最后一種情景非常重要,因為它可以用來對數據通過過濾器的速率進行整形. 令牌的積累可以導致越限的數據進行短時間的突發傳輸而不必丟包,但是持續越限的話會導致傳輸延遲直至丟包.(這種情形應該是最常見的吧!)

請注意,實際的實現是針對數據的字節數進行的,而不是針對數據包進行的.

tc qdisc add dev em2 root tbf latency 5000ms burst 120k rate 120mbit

參數與使用
即使如此,你還是可能需要進行修改,TBF提供了一些可調控的參數.第一個參數一般都需要:
limit/latency(這兩個參數設置一個就可以了)
limit確定最多有多少數據(字節數)在隊列中等待可用令牌.你也可以通過設置latency參數來指定這個參數,latency參數確定了一個包在TBF中等待傳輸的最長等待時間.后者計算決定桶的大小,速率和峰值速率.

burst/buffer/maxburst
桶的大小,以字節計.這個參數指定了最多可以有多少個令牌能夠即刻被使用.
通常,管理的帶寬越大,需要的緩沖器就越大.在Intel體系上,10兆bit/s的速率需要至少10k字節的緩沖區才能達到期望的速率.
如果你的緩沖區太小,就會導致到達的令牌沒有地方放(桶滿了),這會(緩沖區太小)導致潛在的丟包.

mpu
一個零長度的包並不是不耗費帶寬.比如以太網,數據幀不會小於64字節.
Mpu(Minimum Packet Unit,最小分組單位)決定了令牌的最低消耗.

rate
速度操縱桿.參見上面的limits!
如果桶里存在令牌而且允許沒有令牌,相當於不限制速率(缺省情況).
If the bucket contains tokens and is allowed to empty, by default it does so at infinite speed.
如果不希望這樣,可以調整入下參數:
peakrate
如果有可用的令牌,數據包一旦到來就會立刻被發送出去,就象光速一樣.那可能並不是你希望的,特別是你有一個比較大的桶的時候.
峰值速率可以用來指定令牌以多快的速度被刪除.用書面語言來說,就是:釋放一個數據包,但后等待足夠的時間后再釋放下一個.我們通過計算等待時間來控制峰值速率然而,由於UNIX定時器的分辨率是10毫秒,如果平均包長10k bit,我們的峰值速率被限制在了1Mbps.
mtu/minburst
但是如果你的常規速率比較高,1Mbps的峰值速率對我們就沒有什么價值.要實現更高的峰值速率,可以在一個時鍾周期內發送多個數據包.最有效的辦法就是:再創建一個令牌桶!
這第二個令牌桶缺省情況下為一個單個的數據包,並非一個真正的桶.要計算峰值速率,用mtu乘以100就行了. (應該說是乘以HZ數,Intel體系上是100,Alpha體系上是1024)
配置范例
這是一個非常簡單而實用的例子:
tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540
為什么它很實用呢?如果你有一個隊列較長的網絡設備(網速較快),比如DSL modem或者cable modem什么的,並通過一個快速設備(如以太網卡)與之相連,你會發現上載數據絕對會破壞交互性.
這是因為上載數據會充滿modem的隊列,而這個隊列為了改善上載數據的吞吐量而設置的特別大.但這並不是你需要的,你可能為了提高交互性而需要一個不太大的隊列.也就是說你希望在發送數據的時候干點別的事情.
上面的一行命令並非直接影響了modem中的隊列,而是通過控制Linux中的隊列而放慢了發送數據的速度.
把220kbit修改為你實際的上載速度再減去幾個百分點.如果你的modem確實很快,就把"burst"值提高一點.

關於什么時候用哪種隊列的建議
總之,我們有幾種簡單的隊列,分別使用排序,限速和丟包等手段來進行流量整形.
下列提示可以幫你決定使用哪一種隊列.涉及到了第14章 所描述的的一些隊列規定:
如果想單純地降低出口速率,使用令牌桶過濾器.調整桶的配置后可用於控制很高的帶寬.
如果你的鏈路已經塞滿了,而你想保證不會有某一個會話獨占出口帶寬,使用隨機公平隊列.
如果你有一個很大的骨干帶寬,並且了解了相關技術后,可以考慮前向隨機丟包(參見"高級"那一章).
如果希望對入口流量進行"整形"(不是轉發流量),可使用入口流量策略,注意,這不是真正的"整形".
如果你正在轉發數據包,在數據流出的網卡上應用TBF.除非你希望讓數據包從多個網卡流出,也就是說入口網卡起決定性作用的時候,還是使用入口策略.
如果你並不希望進行流量整形,只是想看看你的網卡是否有比較高的負載而需要使用隊列,使用pfifo隊列(不是pfifo_fast).它缺乏內部頻道但是可以統計backlog.
最后,你可以進行所謂的"社交整形".你不能通過技術手段解決一切問題.用戶的經驗技巧永遠是不友善的.正確而友好的措辭可能幫助你的正確地分配帶寬!

不可分類QDisc的配置
如果沒有可分類QDisc,不可分類QDisc只能附屬於設備的根。它們的用法如下:
tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

要刪除一個不可分類QDisc,需要使用如下命令:
tc qdisc del dev DEV root

一個網絡接口上如果沒有設置QDisc,pfifo_fast就作為缺省的QDisc。

CLASSFUL QDISC(分類QDisc)
可分類的QDisc包括:

CBQ
CBQ是Class Based Queueing(基於類別排隊)的縮寫。它實現了一個豐富的連接共享類別結構,既有限制(shaping)帶寬的能力,也具有帶寬優先級管理的能力。帶寬限制是通過計算連接的空閑時間完成的。空閑時間的計算標准是數據包離隊事件的頻率和下層連接(數據鏈路層)的帶寬。

HTB
HTB是Hierarchy Token Bucket的縮寫。通過在實踐基礎上的改進,它實現了一個豐富的連接共享類別體系。使用HTB可以很容易地保證每個類別的帶寬,雖然它也允許特定的類可以突破帶寬上限,占用別的類的帶寬。HTB可以通過TBF(Token Bucket Filter)實現帶寬限制,也能夠划分類別的優先級。

PRIO
PRIO QDisc不能限制帶寬,因為屬於不同類別的數據包是順序離隊的。使用PRIO QDisc可以很容易對流量進行優先級管理,只有屬於高優先級類別的數據包全部發送完畢,才會發送屬於低優先級類別的數據包。為了方便管理,需要使用iptables或者ipchains處理數據包的服務類型(Type Of Service,ToS)。
操作原理
類(Class)組成一個樹,每個類都只有一個父類,而一個類可以有多個子類。某些QDisc(例如:CBQ和HTB)允許在運行時動態添加類,而其它的QDisc(例如:PRIO)不允許動態建立類。
允許動態添加類的QDisc可以有零個或者多個子類,由它們為數據包排隊。

此外,每個類都有一個葉子QDisc,默認情況下,這個葉子QDisc使用pfifo的方式排隊,我們也可以使用其它類型的QDisc代替這個默認的QDisc。而且,這個葉子葉子QDisc有可以分類,不過每個子類只能有一個葉子QDisc。

當一個數據包進入一個分類QDisc,它會被歸入某個子類。我們可以使用以下三種方式為數據包歸類,不過不是所有的QDisc都能夠使用這三種方式。

tc過濾器(tc filter)
如果過濾器附屬於一個類,相關的指令就會對它們進行查詢。過濾器能夠匹配數據包頭所有的域,也可以匹配由ipchains或者iptables做的標記。
服務類型(Type of Service)
某些QDisc有基於服務類型(Type of Service,ToS)的內置的規則為數據包分類。
skb->priority
用戶空間的應用程序可以使用SO_PRIORITY選項在skb->priority域設置一個類的ID。
樹的每個節點都可以有自己的過濾器,但是高層的過濾器也可以直接用於其子類。
如果數據包沒有被成功歸類,就會被排到這個類的葉子QDisc的隊中。相關細節在各個QDisc的手冊頁中。

命名規則
所有的QDisc、類和過濾器都有ID。ID可以手工設置,也可以有內核自動分配。
ID由一個主序列號和一個從序列號組成,兩個數字用一個冒號分開。

QDISC
一個QDisc會被分配一個主序列號,叫做句柄(handle),然后把從序列號作為類的命名空間。句柄采用象10:一樣的表達方式。習慣上,需要為有子類的QDisc顯式地分配一個句柄。

類(CLASS)
在同一個QDisc里面的類分享這個QDisc的主序列號,但是每個類都有自己的從序列號,叫做類識別符(classid)。類識別符只與父QDisc有關,和父類無關。類的命名習慣和QDisc的相同。

過濾器(FILTER)
過濾器的ID有三部分,只有在對過濾器進行散列組織才會用到。詳情請參考tc-filters手冊頁。
單位
tc命令的所有參數都可以使用浮點數,可能會涉及到以下計數單位。

帶寬或者流速單位:
kbps 千字節/秒
mbps 兆字節/秒
kbit KBits/秒
mbit MBits/秒
bps或者一個無單位數字 字節數/秒

數據的數量單位:
kb或者k 千字節
mb或者m 兆字節
mbit 兆bit
kbit 千bit
b或者一個無單位數字 字節數

時間的計量單位:
s、sec或者secs 秒
ms、msec或者msecs 分鍾
us、usec、usecs或者一個無單位數字 微秒

TC命令
tc可以使用以下命令對QDisc、類和過濾器進行操作:
add
在一個節點里加入一個QDisc、類或者過濾器。添加時,需要傳遞一個祖先作為參數,傳遞參數時既可以使用ID也可以直接傳遞設備的根。如果要建立一個QDisc或者過濾器,可以使用句柄(handle)來命名;如果要建立一個類,可以使用類識別符(classid)來命名。

remove
刪除有某個句柄(handle)指定的QDisc,根QDisc(root)也可以刪除。被刪除QDisc上的所有子類以及附屬於各個類的過濾器都會被自動刪除。

change
以替代的方式修改某些條目。除了句柄(handle)和祖先不能修改以外,change命令的語法和add命令相同。換句話說,change命令不能一定節點的位置。

replace
對一個現有節點進行近於原子操作的刪除/添加。如果節點不存在,這個命令就會建立節點。

link
只適用於DQisc,替代一個現有的節點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM