https://jvns.ca/blog/2018/07/12/netdev-day-2–moving-away-from–as-fast-as-possible/
作者 | Julia Evans
譯者 | Chang Liu (FSSlc) ?????共計翻譯:67 篇 貢獻時間:1298 天
嗨!今天是 netdev 會議的第 2 天,我只參加了早上的會議,但它非常有趣。今早會議的主角是 Van Jacobson[1] 給出的一場名為 “從盡可能快中變化:教網絡卡以時間”的演講,它的主題是關於網際網路中擁塞控制的未來!!!
下麵我將嘗試著對我從這次演講中學到的東西做總結,我幾乎肯定下麵的內容有些錯誤,但不管怎樣,讓我們開始吧!
這次演講是關於網際網路是如何從 1988 開始改變的,為什麼現在我們需要新的演演算法,以及我們可以怎樣改變 Linux 的網路棧來更容易地實現這些演演算法。
什麼是擁塞控制?
在網路上的任何成員總是無時無刻地傳送資訊包,而在網際網路上的連線之間有著極其不同的速度(某些相比其他極其緩慢),而有時候它們將被塞滿!當網際網路的一個裝置以超過它能處理的速率接收資訊包時,它將丟棄某些資訊包。
你所能想象的最天真的傳送資訊包方式是:
結果表明假如你按照上面的思路來實現 TCP,網際網路將會崩潰並停止運轉。我們知道它會崩潰是因為在 1986 年確實發生了崩潰的現象。為瞭解決這個問題,專家發明瞭擁塞控制演演算法 —— 描述如何避免網際網路的崩潰的原始論文是 Van Jacobson 於 1988 年發表的 擁塞避免與控制[2](30 年前!)。
從 1988 年後網際網路發生了什麼改變?
在演講中,Van Jacobson 說網際網路的這些已經發生了改變:在以前的網際網路上,交換機可能總是擁有比伺服器更快的網絡卡,所以這些位於網際網路中間層的伺服器也可能比客戶端更快,並且並不能對客戶端傳送資訊包的速率有多大影響。
很顯然今天已經不是這樣的了!眾所周知,今天的計算機相比於 5 年前的計算機在速度上並沒有多大的提升(我們遇到了某些有關光速的問題)。所以我想路由器上的大型交換機並不會在速度上大幅領先於資料中心裡伺服器上的網絡卡。
這聽起來有些糟糕,因為這意味著客戶端更容易在中間層的連線中達到飽和,而這將導致網際網路變慢(而且 緩衝膨脹[3] 將帶來更高的延遲)。
所以為了提高網際網路的效能且不讓每個路由上的任務佇列都達到飽和,客戶端需要表現得更好並且在傳送資訊包的時候慢一點。
以更慢的速率傳送更多的資訊包以達到更好的效能
下麵的結論真的讓我非常意外 —— 以更慢的速率傳送資訊包實際上可能會帶來更好的效能(即便你是在整個傳輸過程中,這樣做的唯一的人),下麵是原因:
假設你打算傳送 10MB 的資料,在你和你需要連線的客戶端之間有一個中間層,並且它的傳輸速率非常低,例如 1MB/s。假設你可以辨別這個慢連線(或者更多的後續中間層)的速度,那麼你有 2 個選擇:
現在,無論你選擇何種方式,你可能都會發生丟包的現象。所以這樣看起來,你可能需要選擇一次性傳送所有的資訊包這種方式,對吧?不!!實際上在你的資料流的中間環節丟包要比在你的資料流的最後丟包要好得多。假如在中間環節有些包被丟棄了,你需要送往的那個客戶端可以察覺到這個事情,然後再告訴你,這樣你就可以再次傳送那些被丟棄的包,這樣便沒有多大的損失。但假如資訊包在最末端被丟棄,那麼客戶端將完全沒有辦法知道你一次性發送了所有的資訊包!所以基本上在某個時刻被丟棄的包沒有讓你收到 ACK 訊號時,你需要啟用超時機制,並且還得重新傳送它們。而超時往往意味著需要花費很長時間!
所以為什麼以更慢的速率傳送資料會更好呢?假如你傳送資料的速率快於連線中的瓶頸,這時所有的資訊包將會在某個地方堆積成一個佇列,這個佇列將會被塞滿,然後在你的資料流的最末端的資訊包將會被丟棄。並且像我們剛才解釋的那樣,處於資料流最後面的資訊包很有可能丟棄!所以相比於最初以合適的速率傳送資訊包,一次性傳送它們將會觸發超時機制,傳送 10MB 的資料將會花費更長的時間。
我認為這非常酷,因為這個過程並不需要與網際網路中的其他人合作 —— 即便其他的所有人都已非常快的速率傳送他們的資訊包,對你來說以合適的速率(中間層的瓶頸速率)傳送你自己的資訊包仍然更有優勢。
如何辨別傳送資料的合適速率:BBR!
在上面我說過:“假設你可以辨別出位於你的終端和伺服器之間慢連線的速率……”,那麼如何做到呢?來自 Google(Jacobson 工作的地方)的某些專家已經提出了一個演演算法來估計瓶頸的速率!它叫做 BBR,由於本次的分享已經很長了,所以這裡不做具體介紹,但你可以參考 BBR:基於擁塞的擁塞控制[4] 和 來自晨讀論文的總結[5] 這兩處連結。
(另外,https://blog.acolyer.org 的每日“晨讀論文”總結基本上是我學習和理解電腦科學論文的唯一方式,它有可能是整個網際網路上最好的部落格之一!)
網路程式碼被設計為執行得“盡可能快“
所以,假設我們相信我們想以一個更慢的速率(例如以我們連線中的瓶頸速率)來傳輸資料。這很好,但網路軟體並不是被設計為以一個可控速率來傳輸資料的!下麵是我所理解的大多數網路軟體怎麼做的:
這個過程非常獃板 —— 假設我以一個非常快的速率傳送資訊包,而另一端的連線卻非常慢。假如我所擁有的就是一個放置所有資訊包的佇列,當我實際要傳送資料時,我並沒有辦法來控制這個傳送過程,所以我便不能減慢這個佇列傳輸的速率。
一個更好的方式:給每個資訊包一個“最早的出發時間”
BBR 協議將會修改 Linux 核心中 skb 的資料結構(這個資料結構被用來表達網路資訊包),使得它有一個時間戳,這個時間戳代表著這個資訊包應該被髮送出去的最早時間。
對於 Linux 網路棧我不知道更多的詳情了,但對於我來說,這個協議最有趣的地方是這個改動並不是一個非常大的改動!它只是添加了一個額外的時間戳而已。
用時間輪盤替換佇列!!!
一旦我們將時間戳打到這些資訊包上,我們怎樣在合適的時間將它們發送出去呢?使用時間輪盤!
在前不久的“我們喜愛的論文”活動中(這是關於這次聚會描述的某些好的連結[7]),有一個演講談論了關於時間輪盤的話題。時間輪盤是一類用來指導 Linux 的行程排程器決定何時執行行程的演演算法。
Van Jacobson 說道:時間輪盤實際上比佇列排程工作得更好 —— 它們都提供常數時間的操作,但因為某些快取機制,時間輪盤的常數要更小一些。我真的沒有太明白這裡他說的關於效能的解釋。
他說道:關於時間輪盤的一個關鍵點是你可以很輕鬆地用時間輪盤實現一個佇列(但反之不能!)—— 假如每次你增加一個新的資訊包,在最開始你說我想讓它現在就被髮送走,很顯然這樣你就可以得到一個佇列了。而這個時間輪盤方法是向後相容的,它使得你可以更容易地實現某些更加複雜的對流量非常敏感的演演算法,例如讓你針對不同的資訊包以不同的速率去傳送它們。
或許我們可以透過改善 Linux 來修複網際網路!
對於任何影響到整個網際網路規模的問題,最為棘手的問題是當你要做出改善時,例如改變網際網路協議的實現,你需要面對各種不同的裝置。你要面對 Linux 的機器、BSD 的機器、Windows 的機器、各種各樣的手機、瞻博或者思科的路由器以及數量繁多的其他裝置!
但是在網路環境中 Linux 處於某種有趣的位置上!
所以在任何給定的網路連線中,實際上很有可能在兩端都有一臺 Linux 機器(例如一個 Linux 伺服器、或者一個 Linux 路由器、一臺 Android 裝置)。
所以重點是假如你想大幅改善網際網路上的擁塞狀況,只需要改變 Linux 網路棧就會大所不同(或許 iOS 網路棧也是類似的)。這也就是為什麼在本次的 Linux 網路會議上有這樣的一個演講!
網際網路仍在改變!酷!
通常我以為 TCP/IP 仍然是上世紀 80 年代的東西,所以當從這些專家口中聽說這些我們正在設計的網路協議仍然有許多嚴重的問題時,真的是非常有趣,並且聽說現在有不同的方式來設計它們。
當然也確實是這樣 —— 網路硬體以及和速度相關的任何裝置,以及人們使用網路來乾的各種事情(例如觀看 Netflix 的節目)等等,一直都在隨著時間發生著改變,所以正因為這樣,我們需要為 2018 年的網際網路而不是為 1988 年的網際網路設計我們不同的演演算法。
via: https://jvns.ca/blog/2018/07/12/netdev-day-2–moving-away-from–as-fast-as-possible/
作者:Julia Evans[9] 譯者:FSSlc 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出