Inside Cisco IOS Software Architecture(第八章,QoS)
這一章講QOS,其實QOS我是有打算通過另外一本書來說的.這本書最後一章也只講了出向排隊的幾種方式和一些命令,在此我們只講書上的東西,超綱的東西我們通過其他書再講.
QoS簡述
書中提到QoS的背景,本質還是由於鏈路帶寬不夠用,路由器要區別對待不同類型的包.最常見的就是在擁塞的時候,路由器轉發數據包選擇先發什麼後發什麼,這叫做擁塞管理,或者是用一種方法避免擁塞.
- 擁塞管理就是要再把數據包發送到出介面的時候,根據包的重要程度來選擇先發什麼,後發什麼,從而避免對網路的影響
- 擁塞避免就是限制排隊來降低發送速度
擁塞管理
擁塞管理本質就是如何在一個出向介面排隊,但是由於為了性能原因,有些排隊策略的實現也和設備本身有關.這裡我們主要討論幾種無關於硬體的排隊方式. 其實這更像是一個單純的數學問題,而非網路問題.這裡涉及的排隊策略有三種:
- Priority Queue(PQ)
- Custom Queue(CQ)
- Weighted Fair Queue(WFQ)
我們之前講過數據包是如何轉發的.出向排隊策略就是在transmit ring之前和排隊到這個介面的queue之間.由於trasmit ring是FIFO(先到先出)的,過了trasmit ring的數據包就到了物理介面,最後被轉發出去.所以數據包在轉發的時候都是要放到介面的output queue,然後根據排隊策略放到transmit ring的內存空間上面
Priority Queue
PQ策略很簡單,priority高的永遠優先.就好像是去銀行排隊,你如果是VIP客戶,下一個永遠叫的是VIP,VIP之間就是FIFO. 缺點當然也很明顯,如果優先順序比較高的很多的話,優先順序比較低的可能會永遠排不到. 就好像你去銀行排隊,你看著你前面有一個人,結果一會來一個VIP.你發現你可能一輩子都排不上.
我們用配置和例子來講述下,相關的查看命令需要的話就查查config guide.
這個圖可以看到這個在S0介面調用了PQ這個策略,PQ中然後分為high, medium, normal.
數據包根據ACL匹配把數據包分到3個不同的queue當中. 當實際轉發的過程中,就是會數據包2,4先發送,然後5,最後是1,3,6.只有當high空的時候才能發medium的數據包,當medium也為空的時候,才能發normal裡面的數據包
Custom Queue
CQ其實是對於PQ的一種優化.避免了優先順序比較低的數據包永遠發不出去的窘境.其實就是在轉發高優先順序的時候轉發到一定程度就不發了,然後去看次優先順序的包.這樣循環下去,從這個角度來看是個round robin.具體發到什麼程度,通過一個例子就可以說的很清楚了.
可以看到配置的時候設置不同的queue有不同的byte-count,這個參數其實有點像token一樣.實際轉發中,其實就是說你能轉發多少bytes.
圖中你也可以看到初始狀態下面不同queue中有不同的包,首先,queue1可以轉發1000bytes,這樣數據包2可以被轉發走.然後還可以轉發500,下個數據包是4.雖然token不夠了,依舊轉發走.其實就是這個queue當中當byte大於0的時候一直可以轉發,直到可轉發的bytes小於0.queue2可以轉發1000個,但是數據包5隻有200bytes,這樣轉發完數據包5就去queue3轉發數據包.到了queue3,數據包1,3,6都會被轉發走.這樣再回到queue1. 我們大體可以說queue1,2,3是按照1:1:2的比例轉發的.當然這也要看具體數據包當時的情況.但是可以肯定的是說CQ是保障了高優先順序的同時,也讓低級優先順序的也轉發走.
Weighted Fair Queuing
這樣其實又根據設備不同分了可以在線卡上面直接處理的和要在控制在CPU處理的.我們在這主要講述和平台無關的 Flow-based WFQ和Class based WFQ.
我們很經常聽到CBFWQ,很少再聽到Flow-based WFQ.其實就是因為Flow based WFQ就是CBFWQ的更簡陋版本.
Flow-based WFQ
這裡其實就是根據數據包的某些欄位(源目IP,TOS位元組,TCP/UDP埠號)來定義一個流,然後對於這個流進行WFQ排隊.既然是weighted,那自然要計算這個數據包的權重值.
權重值=4096/(IP precedence+1)
然後根據權重值算出來他們的序列號,最後根據序列號大小排隊.
序列號=當前序列號+(權重*包長),當實際排隊進入transmit queue的時候,就取最小的序列號.
此處比較繞的就是當前序列號,這個就要分情況看. 當一個數據包計算序列號的時候,先看自己流是不是空的,如果是空的.就用當前傳輸的序列號做當前序列號,如果不是空的.就用這個流隊列的序列號進行計算.
此處我們用一個例子說明.假如我們有3個流,ABC,有5個數據包
- A1,A2-都是500bytes IPP=0
- B1,B2-400butes IPP=0
- C1-40 bytes IPP=3
最開始A1先到,A1權重值是4095,序列號就是 4096*500+0(因為第一個包,當前序列號為0)=2048000,A1進入A隊列
A2在A1之後到,A2的序列就是4096*500+204800=4096000,因為A2也要進入A隊列,但是A隊列不為空,A2使用的當前序列號就是A1的序列號.
B1,B2在A2之後到要進入B隊列,假如這個時候A1要被發出去. B1計算序列號就不能是按0計算,而是按A1的序列號計算.B1=2048000+(4096+400)=3686400,B2類似於A2.B2=3686400+(4096*400)=5324800
這個時候假如A1發送出去了,那下一個要發送出去的就是B1而非A2. 這個時候C1數據包進來,同理由於C隊列是空的,C數據包的序號就是3686400+(1024*40).
你可以發現這個時候C1數據包在A2,B2之前就發出去了.
我們這樣做的根本目的是為了什麼呢?很明顯,我們是根據數據包的TOS和數據包的大小來排隊把數據發出去. TOS欄位很好理解,是因為這個區分了不同等級的服務.考慮數據包包長的原因是因為,一個介面傳送數據的速度是有限的.在相同情況下,能傳送更多小數據包,從而提高整個系統的效率.比如大家去銀行排隊,有些人就是去櫃檯弄個存款業務,很快就搞定了,如果讓這些人插隊.這樣雖然不公平,但是對於銀行來說整個效率是提高了,減少了所有人的平均等待時間.
在網路中,比如說你路由器同時處理一個telnet和一個FTP流量,telnet流量很小,但是對於延遲的容忍度就低一些.FTP一般數據量大的多,慢個一時半會也不會被發現.這樣的情況下,WFQ就自動幫telnet加速,你基本完全不用配置.
其餘的具體配置方法部分就不在這進入深入,有興趣可以查看config guide
Classed-Based WFQ
這個就是我們現在非常容易用到的CBWFQ,在這個書上說CBFWQ還是一個非常先進的技術.
這個就是大家現在日常使用的MQC配置方法了,先配置一個class,在這個class裡面定義你想匹配的流量類型,然後針對於這個class在policy-map當中進行處理,最後在介面調用這個policy-map就好了.
在這個裡面我們非常常用的兩個參數bandwidth和priority(其實就是LLQ)在這個地方需要單獨拿出來說一下.
舉個例子
圖上說的priority和bandwith這兩個命令就是CBWFQ我們常用的排隊命令. Cisco官方也有一個表專門解釋他們的區別,其實這也是一方面說明了很多時候這個玩意是疑惑到很多人的.
我個人覺得以這樣的理解方式會好很多.首先priority這個命令,其實就是在CBWFQ當中創建了一個CQ,這個CQ永遠會被優先處理,你配置的priority xx,xx就是相當於給這個PQ多少的token,類似於剛才CQ提到的傳輸多少個bytes一樣.當然如果這個CQ是空的話,token是可以被其他隊列使用的. 舉個例子,你去銀行排隊,一個小時銀行可以處理20個人,如果我們配置了priority 5,意思是說我優先處理5個VIP客戶,其他15個人正常處理.那如果一個小時先來了5個VIP,15個普通客戶,那銀行就先處理5個VIP.然後再處理15個人.當處理15個人的過程中,突然又來了5個VIP,這5個VIP就下個小時再處理了. 但是如果沒有VIP客戶來,或者來了20個VIP客戶.這些其實對於銀行來說都不算擁塞,在一個小時就處理完了.
對於bandwidth命令,我們是說這個class,我有多少的權重值來轉發數據包.比如你是一個10M的口,這個地方你配置百分之20,或者2M,都是要把百分之20的權重給這個class,不同於剛才提到的CQ,這個百分之20並非會被優先處理,而僅僅是有百分之20的權重.比如說10M的口,2M的帶寬.可能是每10個包處理的時候有2個包給了這個class,並非像是priority 命令一樣.完全是先把這2M處理掉. 關於更細節CBWFQ的內容,這本書沒有提及,我也不過多意淫.等到具體QoS書籍的時候,會有更詳細的內容.
Distributed Queue
如果你考慮下之前的轉發過程,會發現如果系統CPU介入QoS排隊,還是非常消耗系統資源的.Distributed Queue本質就是說讓線卡級別的CPU完成排隊,數據包也不需要在SRAM和DRAM之間複製來去.具體內容書上也沒有說的很清楚,我也不方便意淫太多.
Modified Deficit round robin
這個是12000系列路由器來管理排隊的一種方式,其實看上去是個CQ的或者說是CBWFQ的變種.他其中有一個非常特殊的queue,這個特殊的queue有兩個工作模式:
- strict priority queue,這個類似於PQ,不管怎麼樣,一定要先處理我的.後面的餓死也無所謂.
- alternate mode,這個類似於CQ指定傳輸多少bytes.不同的就是他再處理其他queue之後一定會返回這個特殊queue
舉個例子,我語言能力實在有限.
- queue 0 能傳輸1500bytes,是特殊queue,在alternate mode下.
- queue 1 能傳輸3000bytes
- queue 2 能傳輸1500bytes
1/250表示這是第一個包,有250bytes大小. 首先數據包1,可以被傳輸,然後還能傳輸1250bytes,繼續數據包2能被傳輸.這樣queue0就是-250.然後去queue1處理數據包,接下來數據包4,5被傳輸出去,queue1能傳輸的數據變為0.這個時候,特殊就在於接下來並非要處理queue2,而是回到queue0,繼續處理queue0中的數據.這個時候queue0能處理的數據是-250+150=1250.然後數據包3就傳輸出去了.這個時候queue就是空,可傳輸數據會被置為0.然後處理queue2,非queue1.這個時候數據包queue2可以傳輸1500bytes.這樣數據包7,8,9,10都能被傳輸走.這個時候queue2能傳送的數據包為0,回到queue1.然後就是傳輸數據包6,然後queue1空了,再傳輸queue2中的數據包11.
擁塞避免
RED
我們這裡主要通過random early detection(RED)從而把TCP連接降速來避免擁塞. TCP傳輸速度是通過一個滑動窗口來控制的.滑動窗口會根據現在的速度不停的增大,直到出現擁塞.如果我們是一個FIFO的隊列,結果就是導致了最後的包都被丟掉,由於丟掉的過多,然而會把窗口又搞的很小.
圖中可以如果只是FIFO的情況下,TCP的帶寬使用情況.為了避免出現這種情況,就出現了RED演算法,就是發現不行了,早點開始丟包.這樣讓窗口在更早的時候縮小,而不會出現那麼大的滑落.那RED演算法中就有2個值我們需要考慮,min,max.
- 當前速度低於min值,完全安全,不丟包
- 當前速度在min到max之間,開始丟,隨著現在實際速度增長開始越丟越多.
- 高於max值,全都丟.
Selective packet discard
當輸入的包queue開始處理不過來了,這個時候IOS就開始選擇性丟包,保證路由包或者是保持網路正常運行的包不會被丟棄.這個feature已經被IOS自己實現了,完全不需要你做任何配置.只要是被IOS識別出來重要的包.丟不會被丟棄的.
其他
這裡其實沒說很多QoS,比如說CAR,GTS,RSVP等等,因為畢竟這是一本講IOS的書,並非專門講QoS的書.我們會在其他的書中,把QoS這個單獨拉出來說.
summary
這就是這本書最後一章,也是博客完成的第一本書的讀書陪讀筆記. 希望有人喜歡,覺得有用.
推薦閱讀: