linux下QOS:應用篇

發表於2015-09-14

上一篇我們講了QOS的理論知識,瞭解了它是做什麼用的,以及設計模式,下面就以tc的應用的更深入的理解qos.

Linux採用了基於物件的實現方法,qos還能保證對不同介面採用不同的策略,TC QOS有很多擁塞控制的機制預設的是FIFo還有其他PQ、CQ、WFQ等.

策略類 用結構體:Qdisc_ops表示。每個裝置可以採用不同的策略物件,在裝置和物件的關聯需要到Qdisc結構體


通過上面的描述,整個TC的架構也就出來了,傳送資料包的流程應該是這樣的:
(1) 上層協議開始傳送資料包
(2) 獲得當前裝置所採用的策略物件
(3) 呼叫此物件的enqueue方法把資料包壓入佇列
(4) 呼叫此物件的dequeue方法從佇列中取出資料包
(5) 呼叫網路卡驅動的傳送函式傳送

並且在上一節我們已經講了tc的三級樹型組織.這裡不再貼圖. 還有一點注意的就是tc控發不空收.

下面就從tc的命令說起:

命令格式:

具體的配置流程如下:

Linux流量控制主要分為建立佇列、建立分類和建立過濾器三個方面。

基本實現步驟
(1) 針對網路物理裝置(如乙太網卡eth0)繫結一個佇列QDisc;
(2) 在該佇列上建立分類class;
(3) 為每一分類建立一個基於路由的過濾器filter;
(4) 最後與過濾器相配合,建立特定的路由表等

1. tc 命令的基本用法

檢視tc help 或者man tc

2. 針對不同演算法的不同配置 (為什麼這說,不同的策略演算法,它的引數不一樣需要根據實際情況實際分析)

3. 無分類qdisc 和分類qdisc

(1) 無分類:

[p|b]fifo

使用最簡單的qdisc,純粹的先進先出。只有一個引數:limit,用來設定佇列的長度,pfifo是以資料包的個數為單位;bfifo是以位元組數為單位。

pfifo_fast

在 編譯核心時,如果開啟了高階路由器(AdvancedRouter)編譯選項,pfifo_fast就是系統的標準QDISC。它的佇列包括三個波段(band)。在每個波段裡面,使用先進先出規則。而三個波段(band)的優先順序也不相同,band 0的優先順序最高,band 2的最低。如果band裡面有資料包,系統就不會處理band1裡面的資料包,band 1和band 2之間也是一樣。資料包是按照服務型別(Type ofService,TOS)被分配多三個波段(band)裡面的

red

red是Random Early Detection(隨機早期探測)的簡寫。如果使用這種QDISC,當頻寬的佔用接近於規定的頻寬時,系統會隨機地丟棄一些資料包。它非常適合高頻寬應用。

sfq

sfq是Stochastic Fairness Queueing的簡寫。它按照會話(session–對應於每個TCP連線或者UDP流)為流量進行排序,然後迴圈傳送每個會話的資料包

tbf

tbf是Token Bucket Filter的簡寫,適合於把流速降低到某個值 。
如果沒有可分類QDisc,不可分類QDisc只能附屬於裝置的根。它們的用法如下:

tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

要刪除一個不可分類QDisc,需要使用如下命令:

tc qdisc del dev DEV root

一個網路介面上如果沒有設定QDisc,pfifo_fast就作為預設的QDisc。

(2) 分類:

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的操作原理:

類(Class)組成一個樹,每個類都只有一個父類,而一個類可以有多個子類。某些QDisc(例如:CBQ和HTB)允許在執行時動態新增類,而其它的QDisc(例如:PRIO)不允許動態建立類。

允許動態新增類的QDisc可以有零個或者多個子類,由它們為資料包排隊。

此外,每個類都有一個葉子QDisc,預設情況下,這個葉子QDisc使用pfifo的方式排隊,我們也可以使用其它型別的QDisc代

替這個預設的QDisc。而且,這個葉子葉子QDisc有可以分類,不過每個子類只能有一個葉子QDisc。
當一個資料包進入一個分類QDisc,它會被歸入某個子類。我們可以使用以下三種方式為資料包歸類,不過不是所有的QDisc都能夠使用這三種方式。

其他:

顯示佇列情況 :
Tc qdisc ls dev eth0

顯示分類狀況
Tc class ls dev eth0更詳細的可以加 –s引數

顯示過濾器的狀況
Tc –s filter ls dev eth0

顯示路由的情況
Ip route

Qdisc的引數:
parent major:minor 或者 root。 一個qdisc是根節點就是root,否則其他的情況指定parent。其中major:minor是class的handle id,每個class都要指定一個id用於標識。
handle major: ,這個語法有點奇怪,是可選的,如果qdisc下面還要分類(多個class),則需要指定這個hanlde。對於root,通常是”1:”。

注意:對於tc命令中的qdiscs和classes,標識handle(classid)的語法都是x:y,其中x是一個整數用來標識一個 qdisc,y是一個整數,用來標識屬於該qdisc的class。qdisc的handle的y值必須是0,class的handle的y值必須是非 0。通常”1:0″簡寫為”1:”,也就是上面看到的寫法。

default minor-id,未分類(不能和filter匹配)的流量(預設的)會被送到這個minor所指定的類(class id為major:minor-id)。

tc class … dev dev parent major:[minor] [ classid major:minor ] htb rate rate [ ceil rate ] burst bytes [ cburst bytes ] [ prio priority ]

Class的引數:
parent major:minor,指定這個類的父節點,父節點可以是Qdisc,也可以是Class,如果是Qdisc,那麼就不用指定minor,這個是必須的引數。

classid major:minor,classid作為class的標識,這個是可選的。如果這個class沒有子節點,就可以不指定。major是父qdisc的handle。

引數說明:
rate: 是一個類保證得到的頻寬值.如果有不只一個類,請保證所有子類總和是小於或等於父類.

prio:用來指示借用頻寬時的競爭力,prio越小,優先順序越高,競爭力越強. 低優先順序的class會優先匹配

ceil: ceil是一個類最大能得到的頻寬值。即可以借用的頻寬(預設ceil=rate),根類是不允許被借用的. 這個借用在什麼時候生效呢?如果父類有空餘頻寬,最高可以分配給當前class的值,預設是和rate一樣。

Burst 突發,突發的流量,即大於限制頻寬的時候 > rate < ceil ;允許以ceil的速率傳送的位元組數,應該至少和子類的burst最大值一樣。

cburst 允許以網口的最高速率傳送的位元組數,應該至少和子類的cburst最大值一樣。功能類似tbf中的peakrate,當這個值限制很小時,可以避免突發的流量,以避免瞬間速率超過ceil。

quantum 每輪當前的class能傳送的位元組數,預設的計算quantum = rate / r2q. Quantum必須大於1500 小於 60000。

quantum只在class的流量超過了rate但是沒超過ceil時使用。quantum越小,頻寬共享的效果就越好。 r2q 用來計算quantum,r2q預設是10。

我們先看一個實際class的分類圖:

下面我們就實際看幾個應用的例子:

1. 多使用者ip頻寬平均分配問題
實際應用場景為小區裡,共享一根頻寬上網問題。假如實際頻寬為20m ;使用者數量為100,都在一個vlan裡;
限制使用者下載頻寬200kbps ;gw;先看實際環境的佈局:

我們把小區的部分放大:

 

關於filter匹配策略,也可以用iptables的MARK,在tc裡為fw,用法如下:

有時候對於子分類裡資源有可能被某一個會話一直佔有而其他得不到分配,所以需要新增子佇列來實現資源公平分配:

假如有兩個子網呢?平均分配這20M頻寬:

2. 單獨限制某一個應用的速率問題

這個問題主要在於filter上,是匹配埠還是什麼,可以通過iptables來實現.這裡不詳細列舉配置了.

3.多應用優先順序問題 (voip 視訊 vpn、其他)

同樣我們還使用htb 演算法

上面我們簡單介紹了實際應用的三個例子。至少我們明白了tc應用的基本流程和簡單配置,更復雜的用法需要自己去深入學習.
我們需要注意的是上傳與下載雖然相對獨立,但是他們也會相互影響,比如tcp的效能問題,每傳輸一個報文同時都需要得到一個響應報文.還有關於報文大小的問題,
也需要注意,有時候配置tc的時候,需要我們把mtu的值調大,不然就會造成丟包.例:

在我們具體配置佇列的時候,會被一大堆引數繞暈,其實我們只需要針對具體的策略演算法,檢視幫助即可,本身命令的幫助已經很清晰,然後我們再針對具體演算法查詢資料即可

這裡講的也僅僅是linux系統自帶的功能,對於更復雜的則需要我們自己去實現一些特殊的功能,比如cos和dscp等.

相關文章