关于socket buffer size的调优

简介: 为了达到最大网络吞吐,socket send buffer size(SO_SNDBUF)不应该小于带宽和延迟的乘积。 之前我遇到2个性能问题,都和SO_SNDBUF设置得太小有关。 但是,写程序的时候可能并不知道把SO_SNDBUF设多大合适,而且SO_SNDBUF也不宜设得太大,浪费内存啊。
为了达到最大网络吞吐,socket send buffer size(SO_SNDBUF)不应该小于带宽和延迟的乘积。
之前我遇到2个性能问题,都和SO_SNDBUF设置得太小有关。
但是,写程序的时候可能并不知道把SO_SNDBUF设多大合适,而且SO_SNDBUF也不宜设得太大,浪费内存啊。
于是,有OS提供了动态调整缓冲大小的功能,这样应用程序就不用再对SO_SNDBUF调优了。
(接受缓冲SO_RCVBUF也是类似的问题, 不应该小于带宽和延迟的乘积)

On Linux:
Linux从2.4开始支持接收 缓冲和发送缓冲的动态调整。
http://www.man7.org/linux/man-pages/man7/tcp.7.html
------------------------------------------------------------
       tcp_rmem (since Linux 2.4)
              This is a vector of 3 integers: [min, default, max].  These
              parameters are used by TCP to regulate receive buffer sizes.
              TCP dynamically adjusts the size of the receive buffer from
              the defaults listed below, in the range of these values,
              depending on memory available in the system.
...
       tcp_wmem (since Linux 2.4)
              This is a vector of 3 integers: [min, default, max].  These
              parameters are used by TCP to regulate send buffer sizes.  TCP
              dynamically adjusts the size of the send buffer from the
              default values listed below, in the range of these values,
              depending on memory available.
------------------------------------------------------------

  1. [root@node2 ~]# cat /proc/sys/net/ipv4/tcp_rmem
  2. 4096 87380 4194304
  3. [root@node2 ~]# cat /proc/sys/net/ipv4/tcp_wmem
  4. 4096 16384 4194304


On  Windows:
Windows上其实有类似的机能,但是Windows的文档太糟糕了,我废了不少劲才找到一些旁证。
从Vista开始Windows引入接受窗口的自动调整
http://blogs.msdn.com/b/wndp/archive/2007/07/05/receive-window-auto-tuning-on-vista.aspx


从Win7和Win2008R2开始 Windows 引入送信缓冲的自动调整
https://technet.microsoft.com/zh-cn/subscriptions/ms740642.aspx
------------------------------------------------------------
Updated for Windows 7 and Windows Server 2008 R2
...
Dynamic send buffering for TCP was added on Windows 7 and Windows Server 2008 R2. As a result, the use of the  SIO_IDEAL_SEND_BACKLOG_CHANGE  and SIO_IDEAL_SEND_BACKLOG_QUERY  IOCTLs are needed only in special circumstances. For more information, see  SIO_IDEAL_SEND_BACKLOG_QUERY .
------------------------------------------------------------

需要注意的是,如果应用设置了SO_SNDBUF,Dynamic send buffering会失效  
https://msdn.microsoft.com/en-us/library/windows/desktop/bb736549(v=vs.85).aspx
------------------------------------------------------------
Dynamic send buffering for TCP was added on Windows 7 and Windows Server 2008 R2. By default, dynamic send buffering for TCP is enabled unless an application sets the  SO_SNDBUF  socket option on the stream socket.
------------------------------------------------------------

我在 MSDN上没有找到正式介绍这个功能的页面(也许就没有这样的页面),所以也不知道它的自动调整是怎么个调法,范围是多少。而且,通过对Win7和Windows Server 2008 R2的测试我也没看到 送信缓冲自动调整的效果,这个效果我只在Windows 2012上看到了。

测试:
下面是我的测试,主要针对 送信缓冲的。
以下是各OS中送信缓冲的缺省值
OS                       送信缓冲的缺省值(通过getsockopt(SO_SNDBUF)获取)
Window7:            8k
Windows2003:     8k
Windows2008:     8k
Windows8:          64k
Windows2012:     64k

测试方法:
1)机器A( Windows)通过TCP  socket向机器B发送100MB数据
2) 机器A 每次send()向socket写入8K字节。
3) 机器A的程序设置不同的 SO_SNDBUF,查看总送信时间的变化。

测试环境1:
Host A: Windows 2012(x64)
Host B: RHEL6(x64)
Network:1Gbit LAN

Result(execute time):
default(64K),                  1.118s(送信缓冲的自动调整生效)
set SO_SNDBUF to 32K,   3.295s
set SO_SNDBUF to 64K,   2.048s
set SO_SNDBUF to 128K, 1.404s
set SO_SNDBUF to 256K, 1.290s

从上面可以看出,  Windows 2012中 送信缓冲的自动调整还是很有效果的。
注)如果使用Windows而不是Linux作为客户端,效果也是一样的


测试环境 2:
Host A: Windows 2008 R2(x64)
Host B: RHEL6(x64)
Network:1Gbit LAN

Result(execute time):
default(8K),                   7.370s
set SO_SNDBUF to 32K,  4.159s
set SO_SNDBUF to 64K,  2.875s
set SO_SNDBUF to 128K, 1.593s
set SO_SNDBUF to 256K, 1.324s

Windows 2008 R2,不知道 送信缓冲的 自动调整没有生效( " netsh winsock show autotuning "是生效了的),还是8K初始值的起点太低,反正性能不如人意。


结论:
较新的OS都支持socket buffer的自动调整,不需要应用程序去调优。但对Windows 2012(和Win8)以前的Windows,为了达到最大网络吞吐,还是要应用程序操心一下 SO_SNDBUF的设置。

相关文章
|
负载均衡 网络协议 调度
socket-详细分析No buffer space available(转)
新年上班第一天,突然遇到一个socket连接No buffer space available的问题,导致接口大面积调用(webservice,httpclient)失败的问题,重启服务器后又恢复了正常。
2933 0
|
5月前
|
Java
Java Socket编程与多线程:提升客户端-服务器通信的并发性能
【6月更文挑战第21天】Java网络编程中,Socket结合多线程提升并发性能,服务器对每个客户端连接启动新线程处理,如示例所示,实现每个客户端的独立操作。多线程利用多核处理器能力,避免串行等待,提升响应速度。防止死锁需减少共享资源,统一锁定顺序,使用超时和重试策略。使用synchronized、ReentrantLock等维持数据一致性。多线程带来性能提升的同时,也伴随复杂性和挑战。
97 0
|
1月前
|
网络协议 测试技术 网络安全
Python编程-Socket网络编程
Python编程-Socket网络编程
|
4月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
50 4
|
4月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
63 2
|
4月前
|
网络协议 程序员 视频直播
|
4月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
32 3
|
4月前
|
消息中间件 网络协议 网络安全
Python Socket编程:打造你的专属网络通道,基础篇与进阶篇一网打尽!
【7月更文挑战第26天】在网络编程领域,Python以简洁语法和强大库支持成为构建应用的首选。Socket编程为核心,实现计算机间的数据交换。
64 1
|
4月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解

热门文章

最新文章