`
des40des
  • 浏览: 15508 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

socket性能优化(上)

 
阅读更多

socket性能优化(上)
2012年01月01日
  socket性能优化
  M. Tim Jones (), 资深软件工程师, Emulex
  使用 Sockets API,我们可以开发客户机和服务器应用程序,它们可以在本地网络上进行通信,也可以通过 Internet 在全球范围内进行通信。与其他 API 一样,您可以通过一些方法使用 Sockets API,从而提高 Socket 的性能,或者限制 Socket 的性能。本文探索了 4 种使用 Sockets API 来获取应用程序的最大性能并对 GNU/Linux? 环境进行优化从而达到最好结果的方法。
  在开发 socket 应用程序时,首要任务通常是确保可靠性并满足一些特定的需求。利用本文中给出的 4 个提示,您就可以从头开始为实现最佳性能来设计并开发 socket 程序。本文内容包括对于 Sockets API 的使用、两个可以提高性能的 socket 选项以及 GNU/Linux 优化。
  为了能够开发性能卓越的应用程序,请遵循以下技巧:
  最小化报文传输的延时。 最小化系统调用的负载。 为 Bandwidth Delay Product 调节 TCP 窗口。 动态优化 GNU/Linux TCP/IP 栈。
  技巧 1. 最小化报文传输的延时
  在通过 TCP socket 进行通信时,数据都拆分成了数据块,这样它们就可以封装到给定连接的 TCP payload(指 TCP 数据包中的有效负荷)中了。TCP payload 的大小取决于几个因素(例如最大报文长度和路径),但是这些因素在连接发起时都是已知的。为了达到最好的性能,我们的目标是使用尽可能多的可用数据来填充每个报文。当没有足够的数据来填充 payload 时(也称为最大报文段长度(maximum segment size) 或 MSS),TCP 就会采用 Nagle 算法自动将一些小的缓冲区连接到一个报文段中。这样可以通过最小化所发送的报文的数量来提高应用程序的效率,并减轻整体的网络拥塞问题。
  尽管 John Nagle 的算法可以通过将这些数据连接成更大的报文来最小化所发送的报文的数量,但是有时您可能希望只发送一些较小的报文。一个简单的例子是 telnet 程序,它让用户可以与远程系统进行交互,这通常都是通过一个 shell 来进行的。如果用户被要求用发送报文之前输入的字符来填充某个报文段,那么这种方法就绝对不能满足我们的需要。
  另外一个例子是 HTTP 协议。通常,客户机浏览器会产生一个小请求(一条 HTTP 请求消息),然后 Web 服务器就会返回一个更大的响应(Web 页面)。
  解决方案
  您应该考虑的第一件事情是 Nagle 算法满足一种需求。由于这种算法对数据进行合并,试图构成一个完整的 TCP 报文段,因此它会引入一些延时。但是这种算法可以最小化在线路上发送的报文的数量,因此可以最小化网络拥塞的问题。
  但是在需要最小化传输延时的情况中,Sockets API 可以提供一种解决方案。要禁用 Nagle 算法,您可以设置 TCP_NODELAY socket 选项,如清单 1 所示。
  清单 1. 为 TCP socket 禁用 Nagle 算法
  int sock, flag, ret;/* Create new stream socket */sock = socket( AF_INET, SOCK_STREAM, 0 );/* Disable the Nagle (TCP No Delay) algorithm */flag = 1;ret = setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) );if (ret == -1) {  printf("Couldn't setsockopt(TCP_NODELAY)\n");  exit(-1);}
  提示:使用 Samba 的实验表明,在从 Microsoft? Windows? 服务器上的 Samba 驱动器上读取数据时,禁用 Nagle 算法几乎可以加倍提高读性能。
  技巧 2. 最小化系统调用的负载
  任何时候通过一个 socket 来读写数据时,您都是在使用一个系统调用(system call)。这个调用(例如 read 或 write)跨越了用户空间应用程序与内核的边界。另外,在进入内核之前,您的调用会通过 C 库来进入内核中的一个通用函数(system_call())。从 system_call() 中,这个调用会进入文件系统层,内核会在这儿确定正在处理的是哪种类型的设备。最后,调用会进入 socket 层,数据就是在这里进行读取或进行排队从而通过 socket 进行传输的(这涉及数据的副本)。
  这个过程说明系统调用不仅仅是在应用程序和内核中进行操作的,而且还要经过应用程序和内核中的很多层次。这个过程耗费的资源很高,因此调用次数越多,通过这个调用链进行的工作所需要的时间就越长,应用程序的性能也就越低。
  由于我们无法避免这些系统调用,因此惟一的选择是最小化使用这些调用的次数。幸运的是,我们可以对这个过程进行控制。
  解决方案
  在将数据写入一个 socket 时,尽量一次写入所有的数据,而不是执行多次写数据的操作。对于读操作来说,最好传入可以支持的最大缓冲区,因为如果没有足够多的数据,内核也会试图填充整个缓冲区(另外还需要保持 TCP 的通告窗口为打开状态)。这样,您就可以最小化调用的次数,并可以实现更好的整体性能。
  技巧 3. 为 Bandwidth Delay Product 调节 TCP 窗口
  TCP 的性能取决于几个方面的因素。两个最重要的因素是链接带宽(link bandwidth)(报文在网络上传输的速率)和 往返时间(round-trip time) 或 RTT(发送报文与接收到另一端的响应之间的延时)。这两个值确定了称为 Bandwidth Delay Product(BDP)的内容。
  给定链接带宽和 RTT 之后,您就可以计算出 BDP 的值了,不过这代表什么意义呢?BDP 给出了一种简单的方法来计算理论上最优的 TCP socket 缓冲区大小(其中保存了排队等待传输和等待应用程序接收的数据)。如果缓冲区太小,那么 TCP 窗口就不能完全打开,这会对性能造成限制。如果缓冲区太大,那么宝贵的内存资源就会造成浪费。如果您设置的缓冲区大小正好合适,那么就可以完全利用可用的带宽。下面我们来看一个例子:
  BDP = link_bandwidth * RTT
  如果应用程序是通过一个 100Mbps 的局域网进行通信,其 RRT 为 50 ms,那么 BDP 就是:
  100MBps * 0.050 sec / 8 = 0.625MB = 625KB
  注意:此处除以 8 是将位转换成通信使用的字节。
  因此,我们可以将 TCP 窗口设置为 BDP 或 1.25MB。但是在 Linux 2.6 上默认的 TCP 窗口大小是 110KB,这会将连接的带宽限制为 2.2MBps,计算方法如下:
  throughput = window_size / RTT
  110KB / 0.050 = 2.2MBps
  如果使用上面计算的窗口大小,我们得到的带宽就是 12.5MBps,计算方法如下:
  625KB / 0.050 = 12.5MBps
  差别的确很大,并且可以为 socket 提供更大的吞吐量。因此现在您就知道如何为您的 socket 计算最优的缓冲区大小了。但是又该如何来改变呢?
  解决方案
  Sockets API 提供了几个 socket 选项,其中两个可以用于修改 socket 的发送和接收缓冲区的大小。清单 2 展示了如何使用 SO_SNDBUF 和 SO_RCVBUF 选项来调整发送和接收缓冲区的大小。
  注意:尽管 socket 缓冲区的大小确定了通告 TCP 窗口的大小,但是 TCP 还在通告窗口内维护了一个拥塞窗口。因此,由于这个拥塞窗口的存在,给定的 socket 可能永远都不会利用最大的通告窗口。
  清单 2. 手动设置发送和接收 socket 缓冲区大小
  int ret, sock, sock_buf_size;sock = socket( AF_INET, SOCK_STREAM, 0 );sock_buf_size = BDP;ret = setsockopt( sock, SOL_SOCKET, SO_SNDBUF,                   (char *)&sock_buf_size, sizeof(sock_buf_size) );ret = setsockopt( sock, SOL_SOCKET, SO_RCVBUF,                   (char *)&sock_buf_size, sizeof(sock_buf_size) );
  在 Linux 2.6 内核中,发送缓冲区的大小是由调用用户来定义的,但是接收缓冲区会自动加倍。您可以进行 getsockopt 调用来验证每个缓冲区的大小。
  
  
  巨帧(jumbo frame)
  我们还可以考虑将包的大小从 1,500 字节修改为 9,000 字节(称为巨帧)。在本地网络中可以通过设置最大传输单元(Maximum Transmit Unit,MTU)来设置巨帧,这可以极大地提高性能。
  就 window scaling 来说,TCP 最初可以支持最大为 64KB 的窗口(使用 16 位的值来定义窗口的大小)。采用 window scaling(RFC 1323)扩展之后,您就可以使用 32 位的值来表示窗口的大小了。GNU/Linux 中提供的 TCP/IP 栈可以支持这个选项(以及其他一些选项)。
  提示:Linux 内核还包括了自动对这些 socket 缓冲区进行优化的能力(请参阅下面 表 1 中的 tcp_rmem 和 tcp_wmem),不过这些选项会对整个栈造成影响。如果您只需要为一个连接或一类连接调节窗口的大小,那么这种机制也许不能满足您的需要了。
分享到:
评论

相关推荐

    资料socket性能优化

    ### 资料socket性能优化 #### 一、引言 在开发Socket应用程序时,确保其性能至关重要。本文旨在提供四个实用的技巧帮助开发者优化Socket应用程序的性能,使其能够更高效地运行。这些技巧涵盖了Socket API的使用、...

    提高 Linux 上 socket 性能 加速网络应用程序的 4 种方法

    在开发高性能的网络应用程序时,优化 Linux 上的 socket 性能至关重要。以下四个技巧可以帮助你提升 socket 应用程序的效率: 1. **最小化报文传输的延时** Nagle 算法旨在通过合并小数据包来减少网络中的报文数量...

    基于Linux的Socket网络编程的性能优化.pdf

    Linux Socket网络编程性能优化 基于Linux的Socket网络编程的性能优化是指在Linux操作系统环境下,通过Socket网络编程来实现高性能的网络传输。Socket是Linux操作系统中的一种网络编程接口,允许程序员在不同的主机...

    基于Linux的Socket网络编程的性能优化

    ### 基于Linux的Socket网络编程的性能优化 #### 一、引言 随着互联网技术的迅猛发展,网络在嵌入式系统中的应用变得愈发广泛。越来越多的嵌入式设备选择使用Linux操作系统,这主要得益于Linux的强大移植性和开放源...

    socket性能测试脚本

    在IT行业中,尤其是在服务器开发、网络编程或系统优化领域,对Socket性能的理解和测试是至关重要的。Socket是网络编程的基础,它允许两个应用程序通过网络进行数据交换,因此,性能测试能够帮助我们了解系统的吞吐量...

    提高 Linux 上 socket 性能

    本文将深入探讨四个关键技巧,帮助提升Socket性能。 1. **最小化报文传输的延时**: Nagle算法是一种TCP优化策略,它合并小的数据片段,以减少网络上的数据包数量,降低网络拥塞。然而,这可能会增加传输延时。在...

    基于Linux 的Socket 网络编程的性能优化

    ### 基于Linux的Socket网络编程的性能优化 #### 摘要 本文深入探讨了在Linux操作系统环境中实现Socket网络编程的过程、方法及其性能优化技术。鉴于在实际应用场景中频繁出现的多客户端同时连接服务器的情况,我们...

    Socket性能测试指导.doc

    kylinPET通过提供这些功能和流程,帮助测试人员有效地进行Socket性能测试,以优化网络应用的性能和稳定性。对于需要进一步扩展功能或处理特定情况,kylinPET还提供了调用外部JAVA类和文档支持,以满足各种定制需求。

    基于Linux的Socket网络编程的性能优化(1)

    在实际复杂的网络环境中,针对不同的应用场景,开发者需要综合考虑这些优化策略,以实现最佳的Socket性能。例如,通过最小化消息传输来减少传输时延,可以改善用户体验;而根据网络状况动态调节TCP窗口大小,可以...

    .net使用的高性能大吞吐量socket

    在.NET框架中,为了实现高性能和大吞吐量的网络通信,开发者通常会利用I/O完成端口(IOCP,Input/Output Completion Port)技术来优化Socket编程。本文将深入探讨.NET下的高性能Socket编程,以及如何利用IOCP来提高...

    C#高性能Socket设计实现

    8. **性能优化**:针对特定场景,可能需要进行进一步的性能优化,如减少网络延迟、批量发送数据、利用Nagle算法等。 9. **套接字选项**:C#的Socket类提供了多种选项,如NoDelay、KeepAlive等,可以根据需求调整以...

    基于Linux的Socket网络编程及性能优化.pdf

    【Linux Socket网络编程与性能优化】 Socket编程是网络应用程序的核心技术,特别是在Linux操作系统中,它提供了标准接口供开发者实现网络通信。本文将深入探讨Linux下的Socket网络编程的基本步骤以及性能优化策略。...

    HPSocket.Net-develop_hpsocket.net_HPSocket_.net_socket_tcp_

    通过查看这些内容,开发者可以学习如何集成HPSocket.Net到自己的项目中,以及如何利用其特性来优化TCP通信性能。 总结来说,这个压缩包提供的知识涵盖了C#中的Socket编程基础,特别是使用HPSocket.Net库进行TCP通信...

    Linux性能优化大师.pdf

    《Linux性能优化大师》这本书是Linux系统管理员和开发者的重要参考资料,它深入探讨了如何通过各种技术手段提升Linux系统的运行效率和稳定性。以下是一些关键的知识点: 1. **监控工具**:书中会介绍一系列用于系统...

    HP-Socket压力测试 易源代码

    本话题将聚焦于HP-Socket的压力测试及其易源代码,这对于我们理解和优化网络服务性能至关重要。 一、HP-Socket简介 HP-Socket是一个C++编写的网络通信库,它提供了丰富的API接口,支持TCP、UDP等多种网络协议。该...

    ice和java socket性能测试对比

    1. **性能效率**:Ice通常会比Java Socket更高效,因为它使用了优化的序列化和反序列化机制,减少了网络传输的数据量。此外,Ice的多线程和异步调用模型也能提高处理并发请求的能力。 2. **易用性**:Ice提供了丰富...

    提高socket性能

    综上,提高Socket性能涉及多方面策略,包括选择合适的Socket选项、优化I/O模式、减少系统调用、利用零拷贝技术、高效连接管理以及持续监控与调优。开发者应根据具体应用需求,结合这些方法,制定出适合自己的性能...

    C#高性能大容量SOCKET并发完成端口源码

    【标题】"C#高性能大容量SOCKET并发完成端口源码"涉及到的关键技术是C#编程语言在处理网络通信时的高性能优化,特别是利用I/O完成端口(IOCP,Input/Output Completion Port)来实现高并发的Socket通信。在多线程...

Global site tag (gtag.js) - Google Analytics