1.1 分類的隊列規定網絡
1.1.1 分類的隊列規定及其類中的數據流向工具
一旦數據包進入一個分類的隊列規定,它就得被送到某一個類中——也就是須要分類。對數據包進行分類的工具是過濾器。須要注意的是:「分類器」是從隊列規定內部調用的,而不是從別處。spa
過濾器會返回一個決定,隊列規定就根據這個決定把數據包送入相應的類進行排隊。每一個子類均可以再次使用它們的過濾器進行進一步的分類。直到不須要進一步分類時,數據包才進入該類包含的隊列規定排隊。code
除了可以包含其它隊列規定以外,絕大多數分類的隊列規定還可以流量整形。這對於須要同時進行調度(如使用 SFQ)和流量控制的場合很是有用。若是用一個高速網卡(好比以太網卡)鏈接一個低速設備(好比 cable modem 或者 ADSL modem) 時,也能夠應用。若是僅僅使用 SFQ,那什麼用也沒有。由於數據包進、出路由器時沒有任何延遲。雖然輸出網卡遠遠快於實際鏈接速率,但路由器中卻沒有隊列能夠調度。blog
1.1.2 隊列規定家族:根、句柄、兄弟和父輩 隊列
每塊網卡都有一個出口「根隊列規定」,缺省狀況下是 pfifo_fast 隊列規定。每一個隊列規定都指定一個句柄,以便之後的配置語句可以引用這個隊列規定。除了出口隊列規定以外,每塊網卡還有一個入口,以便 policies 進入的數據流。ci
隊列規定的句柄有兩個部分:一個主號碼和一個次號碼。習慣上把根隊列規定稱爲「1:」,等價於「1:0」。隊列規定的次號碼永遠是0。類的主號碼必須與它們父輩的主號碼一致,類的此號碼必定非零。路由
1.1.2.1 如何用過濾器進行分類it
下圖給出一個典型的分層關係:io
不要誤解這張圖,千萬不要想象內核處在樹的頂點而下面部分是網絡。數據包是在根隊列規定處入隊和出隊的,而內核只同根打交道。一個數據包多是按照下面這個鏈狀流程進行分類的:
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 不一樣,沒有數據通過最低優先級的隊列規定。