8.2. 优化的网络设置
性能调节通常采用优先方式进行。通常我们会在运行程序或者部署系统前调整已知变量。如果调整不起作用,则会尝试调整其他变量。此想法的逻辑是默认情况下,系统并不是以最佳性能水平运作;因此我们认为需要相应对系统进行调整。在有些情况下我们根据计算推断进行调整。
如前所述,网络栈在很大程度上是自我优化的。另外,有效调整网络要求网络栈有深入的理解,而不仅仅值直到网络栈是如何工作,同时还要直到具体系统的网络资源要求。错误的网络性能配置可能会导致性能下降。
例如:缓存浮点问题。增加缓存队列深度可导致 TCP 连接的拥塞窗口比允许连接的窗口更大(由深层缓存造成)。但那些连接还有超大 RTT 值,因为帧在队列中等待时间过长,从而导致次佳结果,因为它可能变得根本无法探测到拥塞。
当讨论网络性能时,建议保留默认设置,除非具体的性能问题变得很明显。此类问题包括帧损失,流量极大减少等等。即便如此,最佳解决方法通常是经过对问题的细致入微的研究,而不是简单地调整设置(增加缓存/队列长度,减少中断延迟等等)。
要正确诊断网络性能问题请使用以下工具:
- netstat
- 这是一个命令行程序可以输出网络连接、路由表、接口统计、伪连接以及多播成员。它可在
/proc/net/
文件系统中查询关于联网子系统的信息。这些文件包括:/proc/net/dev
(设备信息)/proc/net/tcp
(TCP 插槽信息)/proc/net/unix
(Unix 域插槽信息)
有关netstat
及其在/proc/net/
中的参考文件的详情请参考netstat
man page:man netstat
- dropwatch
- 监控内核丢失的数据包的监视器工具。有关详情请参考 A monitoring utility that monitors packets dropped by the kernel. For more information, refer to the
dropwatch
man page:man dropwatch
- ip
- 管理和监控路由、设备、策略路由及通道的工具。有关详情请参考
ip
man page:man ip
- ethtool
- 显示和更改 NIC 设置的工具。有关详情请参考
ethtool
man page:man ethtool
- /proc/net/snmp
- 显示 IP、ICMP、TCP 以及 UDP 根据
snmp
代理管理信息所需 ASCII 数据的文件。它还显示实时 UDP-lite 统计数据。
《SystemTap 初学者指南》中包含一些示例脚本,您可以用来概括和监控网络性能。您可在 http://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/ 找到本指南。
收集完网络性能问题的相关数据后,您就可以形成一个理论 —,同时也希望能有一个解决方案。[5]例如:在
/proc/net/snmp
中增加 UDP 输入错误表示当网络栈尝试将新帧排入程序插槽时,一个或者多个插槽接受队列已满。
这代表数据包至少在一个插槽队列中被瓶颈,就是说插槽队列输送数据包的速度太慢,或者对于该插槽队列该数据包过大。如果是后者,那么可验证任意依赖网络程序的日志查看丢失的数据以便解决这个问题,您应该需要优化或者重新配置受到影响的程序。
插槽接收缓存大小
插槽发送和接收大小都是动态调节的,因此基本不需要手动编辑。如果进一步分析,比如 SystemTap 网络示例中演示的分析,
sk_stream_wait_memory.stp
认为该插槽队列的排放速度过慢,那么您可以增大该程序插槽队列深度。要做到这一点,请增大插槽接收缓存,方法是配置以下值之一:
- rmem_default
- 控制插槽使用的接收缓存默认大小的内核参数。要配置此参数,请运行以下命令:
sysctl -w net.core.rmem_default=N
使用所需缓存大小以字节为单位替换N
。要确定这个内核参数值请查看/proc/sys/net/core/rmem_default
。请记住rmem_default
值不得大于rmem_max
);如果需要请增大rmem_max
值。 - SO_RCVBUF
- 控制插槽接收缓存最大值的插槽选项,单位为字节。有关
SO_RCVBUF
的详情请参考其 man page:man 7 socket
。要配置SO_RCVBUF
,请使用setsockopt
工具,您可以使用getsockopt
查询当前SO_RCVBUF
值。有关这两个工具的详情请参考setsockopt
man page:man setsockopt
。