1. 程式人生 > >長瘦管道的MSS對TCP性能的影響

長瘦管道的MSS對TCP性能的影響

sig div 分享 基本 代碼 不存在 滑動 直觀 發送

TCP的性能優化有個原則,那就是帶寬越高的環境,優化主機性能相比優化擁塞算法而言收益越大!
而當前的環境,或者說當前主流的環境,是什麽呢?是高帶寬環境!雖然在中國這可能名不副實...可畢竟TCP/IP的標準以及協議棧實現的主流主導都是外國人依照外國的環境搞的,所以網絡方面的優化,可能並不存在通用的原則,我們要做“具有中國特色的...”
然而正因為這是在中國,所以我們可以反著想,帶寬低,延遲大,這才是我們的環境。事實上,業內已經有了根據地區定制化的方案,這裏有兩個例子,一個是TCP-Africa,一個是TCP-China...鏈接我都給出了,自行查閱。
本文給出的是一個“反優化”原則,即放棄主機的優化,這個優化在高帶寬低延遲環境是得不償失的,因此請酌情采納,不要走火入魔。
既然要放棄主機的優化,我們要知道主機的瓶頸是什麽。典型就是內存訪問,Cache命中率的影響,缺頁,調度,IO,中斷...當網絡帶寬足夠大,延遲足夠低的時候,主機的瓶頸可能會成為性能的關鍵,因為主機延遲在總延遲中的比重會加大,因此TSO,分散/聚集IO等技術就是旨在讓主機延遲盡可能減少。最基本的,要盡量避免不連續內存的訪問,避免內存拷貝,避免幾乎任何的內存操作總是有收益的。
Linux在TCP發包時一直是基於長度為MSS字節的數據段為單位的,而不是直接使用字節來計數。然而對端的通告窗口的計數單位卻是字節,而這兩者並不能保證一個嚴格的倍數關系,一般而言,MSS受制於MTU,而MTU是與通告窗口無關的。矛盾在以下的圖示中體現:

技術分享圖片

目前Linux采用的是方案2,其考慮的是,拆分一個整MSS帶來的收益太小了,同時付出的代價卻比較大,會在窗口邊界打亂數據的規整性,事實上,如果網絡時延(指的是RTT)足夠短,預期中Seg3的ACK會很快返回推動窗口向右邊滑動,那麽做這個拆分是不劃算的。但是,我們考慮另一個極端,時延特別長的時候。在描述長管道時,我們希望的效果是這個管道中時刻存在數據,也就說說發送端要保持持續發送,由於光速的極限,任何發送過程中的間隔都是不可彌補的,而最終落實到的時間和主機時間相比,不在一個數量級,如果時延達到了百毫秒級,可以認為,主機端的任何操作時延都可以忽略不計!為了保持長管道的滿載,發送端必須時刻保持有數據發送,忽略掉為了發送允許的數據而拆分整包帶來的時間開銷!

在此,我們要有意區分一下“長肥管道”和“長瘦管道”,對於長肥管道而言,一次ACK可以帶來大量的發送空間,因此拆分後的小包(圖中的Seg4-1)在這巨大的發送空間中的比重十分小,因此我不建議在高帶寬時按照通告窗口將數據包拆解滿窗發送,然而對於長瘦管道,一次ACK帶來的發送空間很小,類似圖中Seg4-1這樣的拆解發送聚集起來在總的發送空間中將占據很高的比重,我們將獲得比較可觀的收益!
最後給出一個直觀的趨勢圖:

技術分享圖片

那麽,還是那句話,代碼呢?很簡單!我曾經花了一個周六的時間手工拆包,然後不小心觸動引線...skb引用的結構體太多了,比如dst_entry什麽的,這就涉及到很多引用計數的問題,經歷了一天的panic後放棄!然而上周在公司跟同事們又一次討論了這個問題,散會後在回家的班車上,突然就覺得根本不需要手工拆包,動態調整MSS即可!同時,會議在5點55結束,立馬收拾東西陪同事抽根煙後奔樓下趕6點10分的班車,這種緊湊正好描述了本文的這個算法!頂著時間前行,而不是被時間拖著!
我的代碼有BUG,是在關閉TSO後測試的,而且模擬的是從T1-1.54Mbps到T3-45Mbps再到100Mbps以太網的帶寬,加上tc延時200ms,這屬於長瘦管道了...效果非常不錯!代碼比較簡單,不支持TSO(話說低劣網絡質量下,TSO無卵用!),只是修改了tcp_write_xmit:
while ((skb = tcp_send_head(sk))) {
        unsigned int limit;

        tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
        BUG_ON(!tso_segs);
        cwnd_quota = tcp_cwnd_test(tp, skb);
        if (!cwnd_quota)
            break;
#if 1
        if (tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq != 0 && mss_now != 0 && (tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq <= mss_now) && (TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq >= mss_now)) {
            mss_now = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
        }
#endif

        if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
            break;

哪裏來的長時延?除了我國領土遼闊以及光速極限帶來的物理限制之外,認為引入的時延在我國也不乏見,比如運營商的整形限速,或者說往光纜裏摻廉價元素影響波導以及折射率,更常見的是銅網線質量低劣...

另外,請註意上面的那個解析Wireshark的tcptrace的圖,這個從右上往左下釋放的能量真的可以解釋臺風生成後沿著副熱帶高壓移動的路徑,同樣的思路可以幫你預測這條路徑,記住,TCP和天氣系統有個共同的特征,就是不同元素之間的糾纏影響!

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

長瘦管道的MSS對TCP性能的影響