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

      Linux 內核的 TC(traffic control)工具能夠用來對網絡帶寬作必定的設計和管理,這裏將對這一工具的使用作必定的介紹,在正式開始介紹TC 以前,先對一些基本的單位作一個說明。爲了不概念混亂,TC 採用以下規定來描述帶寬:算法

mbps = 1024 kpbs = 1024 * 1024 bps => byte/s
mbit = 1024 kbit => kilo bit/s
mb = 1024 kb = 1024 * 1024 b => byte
mbit = 1024 kbit => kilo bit
內定:數字以 bps 和 b 方式存儲,但當 tc 輸出速率時,使用以下表示:
1Mbit = 1024 Kbit = 1024 * 1024 bps => byte/s

 

1.1 解釋隊列和隊列規定網絡

      利用隊列,咱們決定了數據被髮送的方式。必須認識到,咱們只能對發送數據進行整形。工具

      根據Internet 的工做方式,咱們沒法直接控制別人向咱們發送什麼數據。就像咱們家裏的信報箱,你不可能控制全世界,聯繫每個人,修改別人對你發送郵件的數量。然而,Internet 主要依靠TCP/IP,它的一些特性頗有用。由於TCP/IP 沒辦法知道兩個主機之間的網絡容量,因此它會試圖愈來愈快地發送數據(所謂的「慢起技術」) ,當由於網絡容量不夠而開始丟失數據時,再放慢速度。spa

      若是你有一個路由器,而且但願可以防止某些主機下載速度太快,你須要在你路由器的內網卡——也就是向你的網內主機發送數據包的網卡——上進行流量整形。還要保證正在控制的是瓶頸環節。若是有一個100M 以太網卡,而路由器的鏈路速度是 256k,則必須保證發送的數據量沒有超過路由器的處理能力。不然,就是路由器在控制鏈路和對帶寬進行整形,而不是你。能夠說,咱們須要擁有的隊列必須是一系列鏈路中最慢的環節。設計

 

1.2 簡單的無類隊列規定code

      如前所述,利用隊列,咱們決定了數據被髮送的方式。無類隊列規定就是那樣,可以接受數據和從新編排、延遲或丟棄數據包。這能夠用做對於整個網卡的流量進行整形,而不細分各類狀況。最普遍應用的規定是pfifo_fast 隊列規定,由於它是缺省配置。blog

 

1.2.1 pfifo_fast隊列

      這個隊列的特色是先進先出(FIFO),也就是說沒有任何數據包被特殊對待。這個隊列有 3 個「頻道」。FIFO 規則應用於每個頻道。而且若是在 0 頻道有數據包等待發送,1 頻道的包就不會被處理,1 頻道和 2 頻道之間的關係也是如此。內核遵守數據包的 TOS(Type Of Service)標記,把帶有「最小延遲」標記的包放進 0 頻道。進程

      不要把這個無類的簡單隊列規定與分類的 PRIO 相混淆。雖然它們的行爲有些相似,但對於無類的 pfifo_fast 而言,不能使用 tc 命令向其中添加其它的隊列規定。ip

 

1.2.1 參數與使用

      pfifo_fast 隊列規定做爲硬性的缺省設置,不能對它進行配置。它缺省是這樣配置的: 

priomap: 

      內核規定,根據數據包的優先權狀況,對應相應的頻道。這個對應是根據數據包的 TOS 字節進行的。TOS 看上去是這樣的: 

      TOS 字段的 4 個 bit 是以下定義的: 

二進制 十進制 意義

-----------------------------------------

1000     8    最小延遲(md)

0100     4    最大throughput(mt)

0010     2    最大可靠性(mr)

0001     1    最小成本(mmc)

0000     0    正常服務

-----------------------------------------

      隊列的長度來自網卡的配置,能夠用 ifconfig 和 ip 命令修改。如設置隊列長度爲 10,執行:ifconfig eth0 txqueuelen 10。不能用 tc 命令來設置它。

 

1.2.2 令牌桶過濾器(TBF) 

      令牌桶過濾器(TBF)是一個簡單的隊列規定:只容許以不超過事先設定速率到來的數據包經過,但可能容許短暫突發流量超過設定值。

      TBF 的實如今於一個緩衝器(桶),不斷地被一些叫作「令牌」的虛擬數據以特定速率填充着。桶最重要的參數就是它的大小,也就是它可以存儲令牌的數量。每一個到來的令牌從數據隊列中收集一個數據包,而後從桶中被刪除。這個算法關聯到兩個流——令牌流和數據流,因而咱們獲得3 種情景:

      (1)數據流以等於令牌流的速率到達 TBF。這種狀況下,每一個到來的數據包都能對應一個令牌,而後無延遲地經過隊列。

      (2)數據流以小於令牌流的速度到達 TBF。經過隊列的數據包只消耗了一部分令牌,剩下的令牌會在桶裏面積累下來,直到桶被裝滿。剩下的令牌能夠在須要以高於令牌流速率發送數據包的時候被消耗掉,這種狀況下會發生突發傳輸。

      (3)數據流以大於令牌流的速率到達 TBF。這意味着桶裏的令牌很快就會被耗盡。致使 TBF 中斷一段時間,稱爲「越限」。若是數據包持續到來,將會發生丟包。

      最後一種狀況很是重要,由於它能夠用來對數據經過過濾器的速率進行整形。令牌的積累能夠致使越限的數據包進行短期的突發傳輸而沒必要丟包,可是持續越限會致使傳輸延遲直至丟包。須要注意的是,實際的實現是針對數據的字節數進行的,而不是針對數據包進行。

 

1.2.2.1 參數與使用

      TBF 提供了一些可調控的參數,第一個參數永遠可用:

limit/latency

      limit 肯定最多有多少數據(字節數)在隊列中等待可用令牌,也能夠經過設置 latency 參數來指定這個參數。latency 參數肯定了一個包在 TBF 中等待傳輸的最長等待時間。後者計算決定桶的大小、速率和峯值速率。

burst/buffer/maxburst

      桶的大小,以字節計。這個參數指定了最多能夠有多少個令牌可以即刻被使用。一般狀況下,管理的帶寬越大,須要的緩衝器就越大。若是緩衝區過小,就會致使到達的令牌沒有地方放(桶滿了),這會致使潛在的丟包。

mpu

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

rate

      速度操縱桿。

      若是桶存在令牌並且運行沒有令牌,這至關於不限制速率。若是不但願這樣,能夠調整如下參數:

peakrate

      峯值速率能夠用來指定令牌以多快的速度被刪除。用書面語言來講,就是:釋放一個數據包,而後等待足夠的時間後再釋放下一個。經過計算等待時間來控制峯值速率。然而,因爲 UNIX 定時器的分辨率是 10 毫秒,若是平均包長爲 10kbit,峯值速率則被限制在 1Mbps。

mtu/minburst 

      若是常規速率比較高,1Mbps 的峯值速率就沒有什麼價值。要實現更高的峯值速率,能夠在一個時鐘週期內發送多個數據包。最有效的辦法就是再建立一個令牌桶。這第二個令牌桶缺省狀況下爲一個單個的數據包,並不是一個真正的桶。要計算峯值速率,用 mtu 乘以 100 就好了。

 

1.2.2.2 配置範例

      這是一個很是簡單而實用的例子:

# sudo tc qdisc add dev enp0s5 root tbf rate 220kbit latency 50ms burst 1540 

      爲何它很實用呢?若是你有一個隊列較長的網絡設備,好比 DSL modem 或者 cable modem 什麼的,並經過一個快速設備(如以太網卡)與之相連,你會發現上載數據絕對會破壞交互性。這是由於上載數據會充滿modem 的隊列,而這個隊列爲了改善上載數據的吞吐量而設置的特別大。但這並非你所須要的,你可能爲了提升交互性而須要一個不太大的隊列。也就是說你但願在發送數據的時候乾點別的事情。

      上面的一行命令並不是直接影響了 modem 中的隊列,而是經過控制 Linux 中的隊列而放慢了發送數據的速度。把 220kbit 修改成你實際的上載速度再減去幾個百分點。若是你的 modem 確實很快,就把「burst」值提升一點。

 

1.2.3 隨機公平隊列(SFQ)

      SFQ(Stochastic Fairness Queueing,隨機公平隊列)是公平隊列算法家族中的一個簡單實現。它的精確性不如其它的方法,可是它在實現高度公平的同時,須要的計算量卻不多。

      SFQ 的關鍵詞是「會話」(或稱做「流」) ,主要針對一個 TCP 會話或者 UDP 流。流量被分紅至關多數量的 FIFO 隊列中,每一個隊列對應一個會話。數據按照簡單輪轉的方式發送, 每一個會話都按順序獲得發送機會。這種方式很是公平,保證了每個會話都不會被其它會話所淹沒。SFQ 之因此被稱爲「隨機」,是由於它並非真的爲每個會話建立一個隊列,而是使用一個散列算法,把全部的會話映射到有限的幾個隊列中去。

      由於使用了散列,因此可能多個會話分配在同一個隊列裏,從而須要共享發包的機會,也就是共享帶寬。爲了避免讓這種效應太明顯,SFQ 會頻繁地改變散列算法,以便把這種效應控制在幾秒鐘以內。

      有很重要的一點須要聲明:只有當你的出口網卡確實已經擠滿了的時候,SFQ 纔會起做用。不然在你的 Linux 機器中根本就不會有隊列,SFQ 也就不會起做用。特別地,在你使用 DSL modem 或者 cable modem 的以太網卡上設置 SFQ 是沒有意義的,無需進一步整形。

 

1.2.3.1 參數與使用

      SFQ 基本上不須要手工調整:

perturb 

      多少秒後從新配置一次散列算法。若是取消設置,散列算法將永遠不會從新配置(不建議這樣作)。10 秒應該是一個合適的值。

quantum 

      一個流至少要傳輸多少字節後才切換到下一個隊列。缺省設置爲一個最大包的長度(MTU 的大小)。不要設置這個數值低於 MTU。

 

1.2.3.2 配置範例

      若是有一塊網卡,它的鏈路速度與實際可用速率一致,以下配置能夠提升公平性:

# sudo tc qdisc add dev enp0s5 root sfq perturb 10


# sudo tc -s -d qdisc ls
 dev enp0s5

qdisc sfq 8001: root refcnt 2 limit 127p quantum 1514b depth 127 flows 128/1024 divisor 1024 perturb 10sec 

 Sent 1863 bytes 22 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0

      「8001:」這個號碼是系統自動分配的一個句柄號,「limit」意思是這個隊列中能夠有 127 個數據包排隊等待。一共能夠有 1024 個散列目標能夠用於速率審計, 而其中 128 個能夠同時激活。每隔 10 秒散列算法更換一次。

 

1.3 關於何時用哪一種隊列的建議

      (1)若是想單純地下降出口速率,使用令牌桶過濾器。調整桶的配置後可用於控制很高的帶寬。

      (2)若是鏈路已經塞滿了,且想保證不會有某一個會話獨佔出口帶寬,使用隨機公平隊列。

      (3)若是有一個很大的骨幹帶寬,而且瞭解了相關技術後,能夠考慮前向隨機丟包。

      (4)若是但願對入口流量進行「整形」(不是轉發流量),可以使用入口流量策略,注意,這不是真正的「整形」。

      (5)若是正在轉發數據包,在數據流出的網卡上應用 TBF。除非但願讓數據包從多個網卡流出,也就是說入口網卡起決定性做用的時候,仍是使用入口策略。

      (6)若是不但願進行流量整形,只是想看看網卡是否有比較高的負載而須要使用隊列,使用 pfifo 隊列(不是pfifo_fast)。它缺少內部頻道可是能夠統計 backlog。

 

1.4 術語

      爲了正確地理解後面所提到的名詞和配置,先對要用到的一些術語名詞作必定的說明:

隊列規定

      管理設備輸入(ingress)或輸出(egress)的一個算法。

無類的隊列規定

      一個內部不包含可配置子類的隊列規定。

分類的隊列規定

      一個分類的隊列規定內能夠包含更多的類。其中每一個類又進一步地包含一個隊列規定,這個隊列規定能夠是分類的,也能夠是無類的。根據這個定義,嚴格地說 pfifo_fast 算是分類的,由於它實際上包含 3 個頻道(實際上能夠認爲是子類)。然而從用戶的角度來看它是無類的,由於其內部的子類沒法用 tc 工具進行配置。

      一個分類的隊列規定能夠擁有不少類,類內包含隊列規定。

分類器

      每一個分類的隊列規定都須要決定什麼樣的包使用什麼類進行發送。分類器就是作這個用的。

過濾器

      分類是經過過濾器完成的。一個過濾器包含若干的匹配條件,若是符合匹配條件,就按此過濾器分類。

調度

      在分類器的幫助下,一個隊列規定能夠裁定某些數據包能夠排在其餘數據包以前發送,這種處理叫作「調度」。好比前面提到的 pfifo_fast 就是這樣的。

整形

      在一個數據包發送以前進行適當的延遲,以避免超過事先規定好的最大速率。整形在 egress 處進行。習慣上,經過丟包來降速也常常被稱爲整形。

策略

      經過延遲或是丟棄數據包來保證流量不超過事先規定的帶寬。在 Linux 中,策略老是規定丟棄數據包而不是延遲,即不存在 ingress 隊列。

Work-Conserving

      對於一個 work-conserving 隊列規定,若是獲得一個數據包,它老是當即對它進行分發。換句話說,只要網卡(egress隊列規定)運行,它就不會延遲數據包的發送。

non- Work-Conserving

      有些隊列(好比令牌桶過濾器)可能須要暫時中止發包以實現限制帶寬。也就是說它們有時候即便有數據包須要處理,也可能拒絕發送。

      如今咱們簡單瞭解了一些術語,下面看看它們的位置:

      整個大方框表示內核,最左邊的箭頭表示從網絡上進入機器的數據包。它們進入 ingress 隊列規定,並可有能被某些過濾器丟棄,即所謂的策略。數據包順利經過後,若是它是發往本地進程的,就會進入 IP 協議棧處理並提交給該進程。若是它須要轉發而不是進入本地進程,就會發往 egress。本地進程也能夠發送數據,交給 egress 分類器。而後通過審查,並放入若干隊列規定中的一個進行排隊,這個過程叫作「入隊」。在不進行如何配置的狀況下,只有一個 egress 隊列規定--pfifo_fast 接收數據包。數據包進入隊列後,就等待內核處理並經過某網卡發送,這個過程叫作「出隊」。

      這張圖僅僅表示機器只有一塊網卡的狀況,圖中的箭頭不能表明全部的狀況。每塊網卡都有本身的 ingress 和 egress。

相關文章
相關標籤/搜索