1. 程式人生 > >流水線式的TCP中繼代理是如何提高吞吐的

流水線式的TCP中繼代理是如何提高吞吐的

浙江溫州皮鞋溼,下雨進水不會胖!

寫這篇文章的動機來自於我很久以前的一個疑問,就是 CDN如何加速動態的內容? 如果答案是每次都回源站,那豈不是違背了 “CDN就是讓內容離使用者更近” 的承諾了嗎?

答案確實是每次都回源站。但是另一方面,CDN並非僅僅是讓內容離使用者更近,更高層面上,CDN代表了一種顛覆性的架構,除了資料離使用者的距離上的考量之外,更多地是打碎了TCP對IP路由網路的信任,IP做不好的事情,TCP自己來做。

非常具有諷刺意味,加入擁塞控制演算法以後的TCP從來都沒有優雅地應對過擁塞,相反在加入了越來越多的所謂 擁塞控制演算法 之後,TCP違背最初設計理念的地方越來越多,事實證明,TCP根本就做不好長距離的端到端的擁塞控制,是的,完全做不到!

既然做不好長距離的端到端控制,那就做短距離的唄。

更具諷刺意味的是,人們似乎只要聽到TCP代理,就會想到一個字,! 然而非也!


兩個TCP端節點之間如果架一個TCP中繼代理,整個的吞吐會提高。

你可能覺得有點不可思議,貌似這個論述違背了常識,但是確實如此。我不準備用理論去論述這個結論,只給出下面的圖示就能基本明白:

在這裡插入圖片描述

這就是一種流水線的工作方式,它在TCP傳輸中之所以能工作地如此有效,是因為TCP的RTT對傳輸吞吐影響遠遠大於多增加一箇中繼代理而增加的額外處理時間對效能的影響,也就是說在下面的公式中:

TCP時延 = 傳播時延 + 排隊時延 + 處理時延

和傳播時延相比,處理時延可以忽略!

因此在增加了TCP中繼代理之後,雖然增加了單個數據包的處理時延,但是由於流水線操作對傳播時延的優化,這樣做依然是值得的!上圖中僅僅以兩個流水線級作為例子,流水線級數,即TCP中繼代理越多,吞吐就會越高。

至於說為了流水線可以提高吞吐,我想了解CPU流水線處理的都應該明白吧。其本質就是 讓系統的不同組成部分可以同時處理一件事情的不同階段, 這樣整個系統便沒有空閒的部件,所有都在忙,當然效能最高!效能我們可以理解為吞吐。

值得強調的是,流水線並不會提高單程處理( 未使用流水線前 )的效能,相反由於增加了流水線邏輯,它會降低單程處理效能,流水線只是能提高吞吐而已,即可以讓系統的輸出按照流水線級數的頻率來進行,比如說如果有10級流水線,那麼系統吞吐理論上將會比不使用流水線時多出10倍。

當然,雖然理論上設計無窮級的流水線會讓系統吞吐無窮大,但是每增加一級的流水線都會平添 單程處理時延, 最終流水線帶來的好處不足以彌補平添的時延,就得不償失了,Intel的Pentium 4處理器就是這樣下課的。

【流水線級數越來越多時,吞吐率的增加是一個擠的過程,越來越慢越來越困難】
【流水線級數越來越多時,處理延時的增加是線性遞增的過程,越來越大】

現在說回TCP和流水線的關係。

TCP在設計的時候,就是一個流水線協議。

我們從最簡單的 停/等協議 說起。停等協議的時序圖是下面這樣的:

在這裡插入圖片描述

我們可以看到,這是一個典型的單程操作,在一個數據包的ACK未返回期間,鏈路是靜默的,顯然這在吞吐效率上是非常低的。整個RTT只能傳輸一個數據包,時間和空間均造成了巨大的浪費。TCP的設計者當然不會採用這種方式來設計協議。

不管是最初的端到端滑動視窗協議,還是後來引入的擁塞控制機制,均採用了一種流水線的思想來設計協議(參考一下GBN協議和SR協議,以及TCP和QUIC的類比)。

為了避免時間(資料包傳輸的時間)和空間(資料包在單位時間內通過的距離)的靜默浪費,可以把時間和空間切割成背靠背的小段,流水線的意思是說, 前面一秒發出一個數據包到達前面一個位置,那麼後面一秒就可以發出另一個數據包占據前面資料包後面的位置。 最終效果就是,在端到端資料傳輸路徑上,每一個位置都有資料包在向前傳輸,它們在時間軸上依次向前推進:

在這裡插入圖片描述

換句話說,在資料的接收端看來,資料包的到達是 源源不斷的

這個過程在經典的《TCP/IP詳解 卷1:協議》的 20.7 成塊資料的吞吐量 章節有非常詳細的描述!畫出其時序圖就是下面的樣子:

在這裡插入圖片描述

可見,不管端到端的距離多遠,只要管道達到這種滿載的狀態,假設全世界的網路資料包傳輸速率都一樣為光速且傳送資料包的間隔都一樣,即頻寬一致的情況下,那麼在接收端看來,資料包到達的頻率均是一樣的,這意味著,我們無法通過增加TCP中繼代理的方式來提高吞吐率。看樣子是否定我在本文最初給出的結論。怎麼辦?

這非常容易解釋,因為理論上看來,TCP本來就被設計成了流水線協議,既然它本來就是流水線的,再基於同樣的思想引入TCP中繼,造同樣效果的流水線,當然是無濟於事了。

真的是這樣嗎?

理論上是一回事,現狀是另一回事。我們還得回到TCP實現的現狀來看問題。事實上,直到現在,在現實中,TCP從來沒有按照理想中的流水線方式工作過。也就是說,TCP真正跑起來時其行為並不像理論上的推論所描述的那般。因此,流水線當然不能好好的工作了。

我們看看到底是哪裡出了問題。

首先,我們從《TCP/IP詳解 卷1:協議》的20.7小節裡看到,TCP資料包是以相同的時間間隔傳送的,即它是Pacing傳送的,然而現實中,在BBR之前,大多數的TCP實現均是以主機延時在一個while迴圈中把一視窗的資料包突發出去的。我們將其歸為:

  • Burst行為

其次,由於上述第1點的Burst行為,中間節點的排隊將會加劇,於是產生了大量AQM演算法,產生了TCP傳送端和AQM之間的博弈。此後的TCP傳輸的難題就是 能傳送多少資料 的難題,即計算擁塞控制視窗cwnd的難題。網路傳輸行為是一個動態的行為,這意味著cwnd是無法準確預估的,我們歸納為:

  • cwnd測不準

最終,TCP傳輸的流水線特徵就不可能呈現了。我們知道,在TCP中,由於頻寬的無法預估,初始cwnd不得不從一個非常小的值開始試探,而慢啟動期間cwnd增長的速度和RTT是相關的,所以就為增加TCP中繼代理提供了優化的空間。

另外,我們知道TCP大多數的擁塞控制演算法對丟包是非常敏感的,丟包會造成cwnd的急劇降低,而長距離的TCP端點之間丟包更容易發生,所以增加TCP中繼代理可以縮短每一段子鏈路的RTT進而減少丟包的影響。

關於以上的這些,參見下面兩篇文章:
從TCP長肥管道的視窗開啟慢的問題看TCP中繼的意義https://blog.csdn.net/dog250/article/details/81295639
提高頻寬利用率!為什麼要Pacing?https://blog.csdn.net/dog250/article/details/83116575

通過以上的篇幅,我想下面的疑問應該是解開了:

即便是TCP的cwnd從1開始慢啟動,它的cwnd早晚增長到資料包會填滿整個BDP的,RTT越大,cwnd就越大,cwnd的值就是BDP,所以為什麼增加TCP中繼代理依然是可以提高吞吐率呢???

答案似乎很明顯:

  1. TCP理論上的流水線行為依賴於固定的Pacing傳送,然而現實中的實現多數是Burst傳送;
  2. 複雜且動態的鏈路資料包收斂匯聚行為使得TCP傳輸並不穩定,排隊,丟包造成巨大的影響。

以下是實際中TCP傳輸的時序圖的樣子:

在這裡插入圖片描述

所以說,既然TCP的流水線模型工作的並不好,那麼我們就有必要去顯式地通過增加中間代理節點讓資料包流水線化,這就是本文最開始說明的。


說了這麼多流水線以及TCP的歷史上的一些的事情,其實這是在為TCP中繼代理為什麼能提高系統吞吐率作一個理論上的保證。有了這個理論上的保證或者說依據,我們就可以採用多級代理的方式來重構TCP連線了。這其中有很多值得深思的好玩的東西。

  • 採用中繼會減少排隊和丟包
    我們知道TCP是端到端協議,其對中間鏈路是無感知的,擁塞控制機制中的cwnd如何能相對精確預知,一直是一個世界級難題。可以肯定的是,TCP兩端相距越遠,RTT越大,鏈路狀況越是難以獲取,誤判越是會增多,而誤判的後果就是排隊或者丟包。
    採用TCP中繼代理後,原本長距離的鏈路被切分成了多個段, 每一個小段的可控性會更高些,且RTT的減少本身就會提高吞吐。我們關注下面兩點即可:
    1. 越短的鏈路越不容易丟包,越不容易擁塞,RTT越小超時帶來的cwnd陡降的影響越容易恢復。
    2. 可以針對每一個小段進行定向優化,比如提高初始cwnd等。
  • 採用中繼可以讓選路策略更加靈活
    這個無需多說,TCP/IP協議棧越往上層走,可以利用的策略就越豐富,見下圖:
    在這裡插入圖片描述

可以說,在TCP連線之間加中繼TCP代理,好處多多,使得TCP更加可控,更不容易跑飛(TCP在長RTT情況下,是非常不可控的一個協議),然而這也許違背了TCP最初設計者的初衷,不過這又能怎樣呢?難道設計者就一定是正確的嗎?當初的範.雅格布森的TCP pacing管道不是從來都沒有踐行過嗎?人類理解不了上帝,不然人不就成了上帝了嗎?

TCP中繼代理是一個非常非常通用的架構,事實上當我寫完這篇文章後,我發現其實CDN靜態加速,CDN動態加速,SDWAN等當代網際網路傳輸技術中,大量採用了這種方式,不管你把它們叫什麼,它的本質永遠都是這個,即 TCP中繼代理技術可以為TCP引入良好的短距離端到端傳輸控制!換句話說,多級TCP中繼代理為CDN提供了可以優化內容傳輸的依據!

  • 對於靜態內容,良好的短距離傳輸控制 側重在最後一公里這最後一段;
  • 對於動態內容,良好的短距離傳輸控制 側重在從第一段到最後一段的所有環節的流水線配合。

如果我們把TCP設計之初的流水線理念看作是一種烏托邦式的流水線(竟然相信毫無傳輸保證的IP網路!)的話,那麼TCP中繼代理流水線就是一個真實的流水線。


流水線是一個創舉,和集裝箱一樣。

zhejiang wenzhou skinshoe wet, rain flooding water will not fat.