这两天阅读《Wireshark网络分析就这么简单》一书,作者在"Patrick故事"一节中提到一个问题分析的细节,于是决定记下:
有一台文件服务器的读性能只有10MB/s,远低于客户的期望。我尝试过很多调优方式,性能却只降不升。徒劳三天之后,我对自己彻底失去了信心。这时候我又想起了Patrick,于是上传了一个网络包请他帮忙分析。一小时后收到了他的回信:
1. TCP超时重传的间隔时间太长,设置一个较小的时间可以减少重传对性能的影响。
2. 该网络频繁拥塞,拥塞点大多在32KB以上。如果把发送窗口限制在32KB,就可以避免触碰拥塞点。
这个案例中其实涉及以下几个概念:
1. TCP慢启动策略
2. TCP拥塞避免策略
3. TCP超时重传策略
4. TCP快速重传策略
5. TCP快速恢复策略
需要回答以下两个问题:
1. 如何测量拥塞点?
2. 为什么设定较少的重传时间间隔可以减少对性能的影响?
要测量拥塞点,可以采用主次增加发送量的方法,直到发生网络拥塞。但由于网络状况可能存在一定不确定性,有时可能很堵,有时可能很空,因此拥塞点具有不确定性,也就是说,是动态变化的。
超时重传,对传输性能存在严重影响。为了不给已经发送拥塞的网络继续添堵,一旦发生超时重传,拥塞窗口将会自动降低到1个MSS,并再次开始慢启动过程。并且,这次从慢启动过度到拥塞窗口的临界窗口值,也就有参考依据了,《TCP/IP Illustrated》将该临界值定义为上次发生拥塞时的发送窗口大小的一半。可见,拥塞窗口会因为拥塞发生而急剧减小,会降低接下去网络传输速度。
另外,超时重传时间间隔(RTO)如果设置过大,会导致超时等待的时间过长。
在Google关于GFS的论文,以及Facebook关于McRoute设计的论文中,均提到了针对TCP拥塞(Incast)的处理策略。
《Wireshark网络分析就这么简单》之“重传的讲究”一节,作者根据自身实践,得出了以下结论:
1. 没有拥塞,发送窗口越大,性能越好。所以在带宽没有限制的条件下,应该尽量增大接收窗口,比如启动Scale Option选项。
2. 如果经常发生拥塞,那限制发送窗口反而能提高性能,因为即便万分之一的重传对性能影响都很大。
3. 超时重传对性能影响最大,因为它有一段时间(RTO)没有传输任何数据,而且拥塞窗口会被设置成1个MSS,所以要尽量避免超时重传。
4. 快速重传对性能影响小一些,因为它没有等待时间,而且拥塞窗口减小幅度没有那么大。
5. SACK和NewReno有利于提高重传效率,提高传输性能。
6. 丢包对极小文件的影响比打文件严重。因为读写一个小文件需要的包数很少,所以丢包时往往凑不满3个Dup Ack,只能等待超时重传。而大文件有较大可能触发快速重传。
其他注意点:
1. 在使用Wireshark抓包时,每个包的TCP层包含的window size实际是向对方声明自己的接收窗口的大小。
2. 发送窗口决定一口气能发送多少字节,而MSS(Max Segment Size)决定这些字节要分多少个包发送。
3. TCP Window Scale,在TCP头之外的Option中,表示当前Window Size需要乘以多少倍。