Linux 网络性能tuning向导(6)

从上面的输出可以计算出接收队列几乎已满。 当sk_rmem_alloc> sk_rcvbuf时,TCP栈将调用“收缩”接收队列的例程。 这是一种管家,内核将通过减少开销来尝试释放接收队列中的可用空间。 然而,这种操作带来了CPU成本。 如果崩溃无法释放足够的空间用于附加流量,则数据被“修剪”,意味着数据从存储器丢弃,并且分组丢失。 因此,最好围绕这个条件,避免缓冲区折叠和修剪。 第一步是识别缓冲区折叠和修剪是否正在发生。

# netstat -sn | egrep “prune|collap”; sleep 30; netstat -sn | egrep “prune|collap”    

17671 packets pruned from receive queue because of socket buffer overrun    

18671 packets pruned from receive queue because of socket buffer overrun

如果在此间隔期间数字增加,则需要调整。 第一步是增加网络和TCP接收缓冲区设置。 这是检查应用程序是否调用setsockopt(SO_RCVBUF)的好时机。 如果应用程序调用此函数,这将覆盖默认设置,并关闭套接字自动调整其大小的能力。 接收缓冲区的大小将是应用程序指定的大小。 考虑从应用程序中删除setsockopt(SO_RCVBUF)函数调用,并允许缓冲区大小自动调整。

Tuning tcp_rmem 

套接字内存可调参数有三个值,描述最小值,默认值和最大值(以字节为单位)。 大多数Red Hat Enterprise Linux版本的默认最大值为4MiB。 要查看这些设置,请将其增加4倍:

# sysctl net.ipv4.tcp_rmem 

4096 87380 4194304

# sysctl -w net.ipv4.tcp_rmem=“16384 349520 16777216”

# sysctl net.core.rmem_max 4194304

# sysctl -w net.core.rmem_max=16777216

如果应用程序无法更改为删除setsockopt(SO_RCVBUF),则增加最大套接字接收缓冲区大小,这可以使用SO_RCVBUF套接字选项设置。 仅当更改tcp_rmem的中间值时,才需要重新启动应用程序。 更改tcp_rmem的第3个和最大值不需要重新启动应用程序,因为这些值是通过自动调整动态分配的。

TCP Listen Backlog

当TCP套接字由处于LISTEN状态的服务器打开时,该套接字具有其可以处理的最大数量的未接受的客户端连接。 如果应用程序在处理客户端连接时速度很慢,或者服务器快速获得许多新连接(通常称为SYN Flood),则新连接可能丢失,或者可能会发送称为“SYN cookie”的特制回复包。 如果系统的正常工作负载使得SYN cookie经常被输入到系统日志中,则应调整系统和应用程序以避免它们。

应用程序可以请求的最大积压由net.core.somaxconn内核可调参数决定。 应用程序可以总是请求更大的积压,但它只会得到一个大到这个最大值的积压。 可以如下检查和更改此参数

# sysctl net.core.somaxconn net.core.somaxconn = 128

# sysctl -w net.core.somaxconn=2048 net.core.somaxconn = 2048

# sysctl net.core.somaxconn net.core.somaxconn = 2048

更改最大允许积压量后,必须重新启动应用程序才能使更改生效。 此外,在更改最大允许积压之后,必须修改应用程序以在其侦听套接字上实际设置较大的积压。 下面是一个在C语言中增加套接字积压所需的更改的示例:

-   rc = listen(sockfd, 128);

+   rc = listen(sockfd, 2048);    

if (rc < 0)     {        

perror("listen() failed");        

close(sockfd);        

exit(-1);    

}

上述更改将需要从源代码重新编译应用程序。 如果应用程序设计为积压是一个可配置的参数,这可以在应用程序的设置中更改,并且不需要重新编译。

Advanced Window Scaling

您可能会看到“修剪”错误继续增加,无论上述设置如何。在Red Hat Enterprise Linux 6.3和6.4中,有一个提交被添加到收取skb共享结构到套接字的成本,在内核更新日志中描述为[net]更准确的skb truesize。这种改变具有更快地填充TCP接收队列的效果,因此更快地击中修剪条件。此更改已在Red Hat Enterprise Linux 6.5中恢复。如果接收缓冲区增加并且修剪仍然发生,则参数net.ipv4.tcp_adv_win_scale决定分配给数据的接收缓冲区与被通告为可用TCP窗口的缓冲区的比率。 Red Hat Enterprise Linux 5和6上的默认值为2,等于分配给应用程序数据的缓冲区的四分之一。在RedHat Enterprise Linux 7版本上,此默认值为1,导致一半的空间被通告为TCP窗口。在Red Hat Enterprise Linux 5和6上将此值设置为1将会减少通告的TCP窗口的影响,可能会阻止接收缓冲区溢出,从而阻止缓冲区修剪。

# sysctl net.ipv4.tcp_adv_win_scale 2

# sysctl -w net.ipv4.tcp_adv_win_scale=1

UDP Buffer Tuning 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/14794.html