而当前的环境,或者说当前主流的环境,是什么呢?是高带宽环境!虽然在中国这可能名不副实...可毕竟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