Linux內核TC工具鏈路帶寬設計--PRIO隊列規定


1.1 分類的隊列規定

1.1.1 分類的隊列規定及其類中的數據流向

      一旦數據包進入一個分類的隊列規定,它就得被送到某一個類中——也就是需要分類。對數據包進行分類的工具是過濾器。需要注意的是:“分類器”是從隊列規定內部調用的,而不是從別處。

      過濾器會返回一個決定,隊列規定就根據這個決定把數據包送入相應的類進行排隊。每個子類都可以再次使用它們的過濾器進行進一步的分類。直到不需要進一步分類時,數據包才進入該類包含的隊列規定排隊。

      除了能夠包含其它隊列規定之外,絕大多數分類的隊列規定還能夠流量整形。這對於需要同時進行調度(如使用 SFQ)和流量控制的場合非常有用。如果用一個高速網卡(比如以太網卡)連接一個低速設備(比如 cable modem 或者 ADSL modem) 時,也可以應用。如果僅僅使用 SFQ,那什么用也沒有。因為數據包進、出路由器時沒有任何延遲。雖然輸出網卡遠遠快於實際連接速率,但路由器中卻沒有隊列可以調度。

 

1.1.2 隊列規定家族:根、句柄、兄弟和父輩 

      每塊網卡都有一個出口“根隊列規定”,缺省情況下是 pfifo_fast 隊列規定。每個隊列規定都指定一個句柄,以便以后的配置語句能夠引用這個隊列規定。除了出口隊列規定之外,每塊網卡還有一個入口,以便 policies 進入的數據流。

      隊列規定的句柄有兩個部分:一個主號碼和一個次號碼。習慣上把根隊列規定稱為“1:”,等價於“1:0”。隊列規定的次號碼永遠是0。類的主號碼必須與它們父輩的主號碼一致,類的此號碼一定非零。

 

1.1.2.1 如何用過濾器進行分類

      下圖給出一個典型的分層關系:

      不要誤解這張圖,千萬不要想象內核處在樹的頂點而下面部分是網絡。數據包是在根隊列規定處入隊和出隊的,而內核只同根打交道。一個數據包可能是按照下面這個鏈狀流程進行分類的:

1: -> 1:1 -> 12: -> 12:2 

      數據包現在應該處於 12:2 下屬的某個隊列規定中的某個隊列中。在這個例子中,樹的每個節點都附帶着一個過濾器,用來選擇下一步進入哪個分支。這樣比較直觀。然而,這樣也是允許的: 

1: -> 12:2 

   也就是說,根所附帶的一個過濾器要求把數據包直接交給12:2。 

 

1.1.2.2 數據包如何出隊並交給硬件

      當內核決定把一個數據包發給網卡的時候,根隊列規定 1: 會得到一個出隊請求,然后把它傳給 1:1,然后依次傳給 10:、11: 和 12:,然后試圖從它們中進行出隊操作。也就是說,內核需要遍歷整顆樹,因為只有 12:2 中才有這個數據包。 換句話說,類及其兄弟僅僅與其“父隊列規定”進行交談,而不會與網卡進行交談。只有根隊列規定才能由內核進行出隊操作。

      任何類的出隊操作都不會比它們的父類更快。我們可以把 SFQ 作為一個子類,放到一個可以進行流量整形的父類中,從而能夠同時得到 SFQ 的調度功能和其父類的流量整形功能。

 

1.1.3 PRIO 隊列規定 

      PRIO 隊列規定並不進行整形,它僅僅根據所配置的過濾器把流量進一步細分。可以認為 PRIO 隊列規定是 pfifo_fast 的一種衍生物,區別在每個頻道都是一個單獨的類,而非簡單的 FIFO。 

      當數據包進入 PRIO 隊列規定后,將根據所給定的過濾器設置選擇一個類。缺省情況下有三個類,這些類僅包含純 FIFO 隊列規定而沒有更多的內部結構。可以把它們替換成需要的任何隊列規定。 

      每當有一個數據包需要出隊時,首先處理 :1 類。只有當標號更小的類中沒有需要處理的包時,才會處理標號大的類。當希望不僅僅依靠包的 TOS,而是想使用 tc 所提供的更強大的功能來進行數據包的優先權划分時,可以使用這個隊列規定。它也可以包含更多的隊列規定,而 pfifo_fast 卻只能包含簡單的 fifo 隊列規定。 

      因為它不進行整形,所以使用時與 SFQ 有相同的考慮:要么確保這個網卡的帶寬確實已經占滿,要么把它包含在一個能夠整形的分類的隊列規定的內部。嚴格地說,PRIO 隊列規定是一種 Work-Conserving 調度。

 

1.1.3.1 PRIO 的參數與使用

      tc 識別下列參數: 

bands 

      創建頻道的數目。每個頻道實際上就是一個類,如果修改了這個數值,必須同時修改:

priomap


      如果不給 tc 提供任何過濾器,PRIO 隊列規定將參考 TC_PRIO 的優先級來決定如何給數據包入隊。它的行為就像 pfifo_fast 隊列規定。

      頻道是類,缺省情況下命名為主標號 :1 到主標號 :3。如果你的 PRIO 隊列規定是 12:,把數據包過濾到 12:1 將得到最高優先級。注意:0 頻道的次標號是 1,1 頻道的次標號是 2,以此類推。

 

1.1.3.2 配置范例

      我們想創建這個樹:  

      大批量數據使用 30:,交互數據使用 20:或 10:。命令如下: 

# sudo tc qdisc add dev enp0s5 root handle 1: prio
## 這個命令立即創建了類: 1:1, 1:2, 1:3
# sudo tc qdisc add dev enp0s5 parent 1:1 handle 10: sfq

# sudo tc qdisc add dev enp0s5 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000 
# sudo tc qdisc add dev enp0s5 parent 1:3 handle 30: sfq 

      現在,我們看看結果如何:

# sudo tc -s qdisc ls dev enp0s5
qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
 Sent 7834 bytes 56 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 30: parent 1:3 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 10: parent 1:1 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 570 bytes 5 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc tbf 20: parent 1:2 rate 20Kbit burst 1600b lat 560.0ms 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

      如上結果所示,0 頻道已經有了一些流量,運行這個命令之后發送了一個包。現在我們來點大批量數據傳輸(使用能夠正確設置 TOS 標記的工具):

# sudo scp dist/flanneld-amd64 chen@10.211.55.21:/usr/local/bin/flanneld
# sudo tc -s qdisc ls dev enp0s5
qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
 Sent 37460942 bytes 29222 pkt (dropped 29, overlimits 0 requeues 0) 
 backlog 3028b 0p requeues 0 
qdisc sfq 30: parent 1:3 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 37011116 bytes 25548 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 10: parent 1:1 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 840 bytes 8 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc tbf 20: parent 1:2 rate 20Kbit burst 1600b lat 560.0ms 
 Sent 441722 bytes 3615 pkt (dropped 31, overlimits 542 requeues 0) 
 backlog 0b 0p requeues 0 

      如上可得,所有的流量都是經過 30:處理的,優先權最低。現在我們驗證一下交互數據傳輸經過更高優先級的頻道,我們生成一些交互數據傳輸: 

# sudo tc -s qdisc ls dev enp0s5
 qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
 Sent 37487185 bytes 29445 pkt (dropped 29, overlimits 0 requeues 0) 
 backlog 3028b 0p requeues 0 
qdisc sfq 30: parent 1:3 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 37011116 bytes 25548 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 10: parent 1:1 limit 127p quantum 1514b depth 127 divisor 1024 
 Sent 840 bytes 8 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc tbf 20: parent 1:2 rate 20Kbit burst 1600b lat 560.0ms 
 Sent 467965 bytes 3838 pkt (dropped 31, overlimits 546 requeues 0) 
 backlog 0b 0p requeues 0 

      正常情況下所有額外的流量都是經 10: 這個更高優先級的隊列規定處理的。與先前的整個 scp 不同,沒有數據經過最低優先級的隊列規定。

 


免責聲明!

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



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