談談網絡通信中的流量整形

前面的兩篇文章《談談網絡通信中的 ACK、NACK 和 REX》《談談網絡通信中的 FEC 基礎》介紹了網絡通信中的丟包重傳和 FEC 的相關理論和方法,他們都是在網絡發生丟包的情況下的補救措施,本文則往前進一步,介紹下如何通過流量整形技術,儘可能地避免網絡發生丟包。

從堵車說起

v2-dbd54149c8a9baf674a0237ea5623f5d_hd.png

堵車的原因有很多種,我們先聊聊圖中的這種:假設某公路是 3 股道,也就是說,每時刻能同時進入該公路的車輛並行是 3 輛,那麼,如果某一時間段,同時試圖進入該公路的車輛超過 3 輛,則必然會出現由於公路的承載能力不夠帶來的 “堵車”。


v2-e3fd9186c204581fb255c15e64838d65_hd.png

網絡傳輸也類似,假設網絡帶寬是 2Mbps,如果在每秒硬塞給網絡的數據包 > 2Mbps,網絡通道也會受不了。不過它的表現形式與公路不一樣的地方在於:超出網絡承載能力的數據包,可能會被網卡/路由器/交換機給丟掉,即我們常說的丟包(loss)。


對於網絡傳輸而言,丟包帶來的成本是很高的,因爲一些重要的數據包丟失後,是需要 “重傳” 的,而 “重傳” 太多,來回反覆會增加了數據傳輸的延時,也會進一步惡化網絡負荷,最終極大地降低了傳輸的效率。


因此,我們需要從根本上儘可能地減少 “丟包” 的產生,簡單來說,就是控制單位時間內送入網絡傳輸的數據量,儘量平滑且不要超過網絡帶寬承載能力。

控制對象

既然要控制送入網絡傳輸的數據量,就得先找到數據是怎麼產生的,又是在通過哪個環節送入到網絡的。

v2-189f08aa04249095d2b2e66e089ec583_hd.png

如圖,音視頻傳輸的數據 “源頭” ,無外乎就是本地的音視頻文件、麥克風採集的音頻流、攝像頭採集的視頻流、桌面採集到的屏幕流等,它們經過編碼壓縮和封包處理,然後經過 “發送模塊” 送入到網絡中。

設置和修改採集的配置(如:分辨率、幀率)、編碼器的配置(如:GOP 間隔、碼率)等,是可以減少實時產生的總數據量的,但是數據的產生並不是 “平滑” 的,特別是視頻流/屏幕流,畫面的突變,會帶來數據量的突變,因此,送入到 “發送模塊” 的數據量,也並不會總是 “平滑” 的。


從上面的 “堵車” 理論,爲了避免丟包,我們需要儘可能地將數據 “平滑” 地送入網絡中,因此,“流量整形” 在此派上了用場,它作用於 “發送模塊”,目標是調整數據傳輸的平均速率,防止突發性的流量暴增導致網絡擁塞和丟包。

流量整形

如何平輸入和輸出,一個最容易想到方法,就是增加 “緩衝”,讓輸入的數據先進入 “緩衝區” ,然後用恆定的 “速率” 從緩衝區取數據輸出。這種方法稱之爲 “漏桶算法”。

漏桶算法(Leaky Bucket)

v2-da28afda819a75f0cd11aa4c5e05512b_hd.png

如圖,使用一個 packet buffer(漏桶),把所有輸入的 packet 緩存起來。


設置一個目標的輸出碼率(比如:3Mbps),固定的時間間隔(比如:10ms),讀取 packet buffer(漏桶)中固定數量的 packet(如:3Mbit * 10ms / 1000 = 0.03Mbit)進行網絡發送。注:如果某時刻緩衝區沒有數據,則不用發送了。


漏桶算法的缺點

漏桶算法有一個明顯的缺點,因爲非常精準的網絡帶寬無法預判,那麼假設你設置了一個比較小的目標碼率(如 3Mbps),可能小於真實的網絡帶寬(如 10Mbps),這時,如果業務上產生了一些突發的流量,真實的網絡帶寬本可以允許更快地完成發送,但經過了漏桶算法後,依然會以恆定的目標碼率慢慢地發送。所以說,漏桶算法無法充分用滿網絡資源來降低傳輸延時。


解決方案有 2 個:

  1. 先慢啓動,然後將漏桶的目標碼率持續上探,直到出現網絡惡化(如:丟包增多)後再降下來,如此反覆,維持一個動態平衡,使得漏桶算法的目標碼率持續無限逼近網絡的承載能力

  2. 改進漏桶算法,允許其在執行過程中,偶爾出現一些超過預設平均值的突發傳輸能力,用於應對業務上的流量突發,即:令牌桶算法


令牌桶算法(Token Bucket)

v2-c4cda3c67c50d6e4f01f6179dafe3991_hd.png

令牌桶算法在漏桶算法基礎上,提出一個改進,就是新增了 “令牌” 和 “令牌桶”。


“令牌” 代表着允許傳輸的字節數量,我們以固定的時間間隔(比如:10ms)產生並送入 “令牌” 到  “令牌桶”,“令牌桶” 設置一個  “令牌” 數量上限(滿了沒有消耗就丟掉新增的令牌),因此,一次傳輸最大的允許突增的字節數 = M x B


發送模塊,以固定 t ms 的時間間隔去讀取 packet buffer,讀取的字節數 X 必須接近但小於等於當前 “令牌桶” 中允許傳輸的字節數(即:“令牌桶” 裏剩餘的  “令牌個數” x B)。並且,傳輸完了多少字節,則刪除掉 “令牌桶” 裏對應個數的 “令牌”。


這種方法解決突發流量的關鍵點在哪呢 ?


在於 “令牌” 是可以積累的,可能緩衝區在前 N ms 都沒有突發的數據,這時,“令牌” 依然在產生,並且被積累在了 “令牌桶”,一旦緩衝區突增了大量的數據,則可以在短時間內快速消費掉。當然,爲了防止突破網絡承載能力導致丟包,“令牌桶” 的最大 “令牌數量” 也相應做了一些限制。

小結

關於網絡通信中的流量整形就簡單介紹到這裏了,“漏桶算法” 和 “令牌桶算法” 其實在很多的地方都有使用,比如服務端的限流降級,比如音視頻的平滑丟幀等等,當然,也還有一些基於這些算法的各種改進策略,這裏就不一一介紹了,歡迎大家來信 [email protected] 交流,另外,也歡迎大家關注我的新浪微博 @盧_俊 或者 微信公衆號 @Jhuster 獲取最新的文章和資訊。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章