15 微调网络 #
网络子系统非常复杂,其微调方式在很大程度上取决于系统的使用方案以及多种外部因素,例如网络中的软件客户端或硬件组件(交换机、路由器或网关)。Linux 内核更注重的是可靠性和低延迟,而不是低开销和高吞吐量。其他设置可能会降低安全性,但可以提高性能。
15.1 可配置的内核套接字缓冲区 #
网络在很大程度上依赖于 TCP/IP 协议以及一个套接字接口来实现通讯;有关 TCP/IP 的详细信息,请参见第 23 章 “基本网络知识”。Linux 内核通过套接字缓冲区中的套接字接口来处理它接收或发送的数据。这些内核套接字缓冲区是可调的。
从内核版本 2.6.17 开始支持完全自动微调缓冲区大小(最大大小 4 MB)。这意味着,手动微调往往不会明显改善网络性能。通常,最好不要改动以下变量,或者,最起码要仔细检查执行微调的效果。
如果您要从旧版内核更新,建议去除手动 TCP 微调,改用自动微调功能。
/proc
文件系统中的特殊文件可以修改内核套接字缓冲区的大小和行为;有关 /proc
文件系统的一般信息,请参见第 2.6 节 “/proc
文件系统”。在以下位置查找网络相关的文件:
/proc/sys/net/core /proc/sys/net/ipv4 /proc/sys/net/ipv6
内核文档 (linux/Documentation/sysctl/net.txt
) 中解释了一般的 net
变量。linux/Documentation/networking/ip-sysctl.txt
和 linux/Documentation/networking/ipvs-sysctl.txt
中解释了特殊的 ipv4
变量。
例如,在 /proc
文件系统中,可为所有协议设置“最大套接字接收缓冲区”和“最大套接字发送缓冲区”,或者仅为 TCP 协议设置这两个选项(在 ipv4
中),从而覆盖所有协议的设置(在 core
中)。
/proc/sys/net/ipv4/tcp_moderate_rcvbuf
如果
/proc/sys/net/ipv4/tcp_moderate_rcvbuf
设置为1
,则会激活自动微调并动态调整缓冲区大小。/proc/sys/net/ipv4/tcp_rmem
包括三个值,用于设置每个连接的内存接收缓冲区的最小大小、初始大小和最大大小。这些值定义了实际内存用量,而不仅仅是 TCP 窗口大小。
/proc/sys/net/ipv4/tcp_wmem
与
tcp_rmem
相同,但用于设置每个连接的内存发送缓冲区。/proc/sys/net/core/rmem_max
设置此项可以限制应用程序能够请求的最大接收缓冲区大小。
/proc/sys/net/core/wmem_max
设置此项可以限制应用程序能够请求的最大发送缓冲区大小。
可以通过 /proc
禁用您不需要的 TCP 功能(默认已打开所有 TCP 功能)。例如,检查以下文件:
/proc/sys/net/ipv4/tcp_timestamps
TCP 时戳在 RFC1323 中定义。
/proc/sys/net/ipv4/tcp_window_scaling
TCP 窗口缩放也在 RFC1323 中定义。
/proc/sys/net/ipv4/tcp_sack
选择确认 (SACKS)。
使用 sysctl
读取或写入 /proc
文件系统的变量。sysctl
比 cat
(用于读取)和 echo
(用于写入)更可取,因为它还能从 /etc/sysctl.conf
读取设置,因此,每次重引导后,这些设置能够可靠地保留下来。使用 sysctl
可以轻松读取所有变量及其值;以 root
身份使用以下命令可以列出 TCP 相关的设置:
>
sudo
sysctl -a | grep tcp
微调网络变量可能会影响其他系统资源,例如 CPU 或内存用量。
15.2 检测网络瓶颈和分析网络流量 #
在开始进行网络微调之前,必须确定网络瓶颈和网络流量模式。某些工具可帮助您检测这些瓶颈。
以下工具可帮助分析网络流量:netstat
、tcpdump
和 wireshark
。Wireshark 是一个网络流量分析器。
15.3 Netfilter #
Linux 防火墙和掩蔽功能由 Netfilter 内核模块提供。此模块是一个高度可配置的基于规则的框架。如果某个规则与某个包匹配,Netfilter 会接受或拒绝该包,或者根据规则的定义执行特殊操作(“目标”),例如地址转换。
Netfilter 可能会考虑相当多的属性。因此,定义的规则越多,包处理的持续时间就越长。另外,高级连接跟踪的开销可能相当大,因而会减慢总体网络速度。
当内核队列已满时,将会丢弃所有新包,导致现有连接失败。在网络流量较大的情况下,“故障打开”功能可让用户暂时禁用包检查并保持连接。有关参考信息,请参见 https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/。
有关详细信息,请参见 Netfilter 和 iptables 项目的主页 http://www.netfilter.org
15.4 使用接收包导向 (RPS) 改善网络性能 #
新式网络接口设备可以移动大量的包,导致主机成了实现最大性能的限制因素。为了跟上性能需求,系统必须能够将工作分发给多个 CPU 核心。
某些新式网络接口可以通过在硬件中实施多个传输队列和多个接收队列,帮助将工作分发到多个 CPU 核心。但是,还有一些网络接口仅配备了单个队列,驱动程序必须在单个序列化流中处理所有传入的包。要解决此问题,操作系统必须“并行化”流以在多个 CPU 之间分发工作。在 SUSE Linux Enterprise Desktop 上,此功能是通过接收包导向 (RPS) 实现的。还可以在虚拟环境中使用 RPS。
RPS 使用 IP 地址和端口号为每个数据流创建唯一的哈希。使用此哈希可确保将同一数据流的包发送到同一 CPU,从而帮助提升性能。
RPS 是根据网络设备接收队列和接口配置的。配置文件名符合以下模式:
/sys/class/net/<device>/queues/<rx-queue>/rps_cpus
<device> 表示网络设备,例如 eth0
、eth1
。<rx-queue> 表示接收队列,例如 rx-0
、rx-1
。
如果网络接口硬件仅支持单个接收队列,则仅存在 rx-0
。如果它支持多个接收队列,则每个接收队列都有一个 rx-N 目录。
这些配置文件包含 CPU 位图的逗号分隔列表。默认情况下,所有位都设置为 0
。使用此设置会禁用 RPS,因此,处理中断的 CPU 也会处理包队列。
要启用 RPS 并让特定的 CPU 来处理接口接收队列的包,请将这些 CPU 在位图中的位置值设置为 1
。例如,要让 CPU 0-3 处理 eth0 的第一个接收队列的包,请将位位置 0-3 设置为二进制 1:00001111
。然后,需将此表示法转换为十六进制 — 在本例中结果为 F
。使用以下命令设置此十六进制值:
>
sudo
echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
如果您想要启用 CPU 8-15:
1111 1111 0000 0000 (binary) 15 15 0 0 (decimal) F F 0 0 (hex)
用于设置十六进制值 ff00
的命令为:
>
sudo
echo "ff00" > /sys/class/net/eth0/queues/rx-0/rps_cpus
在 NUMA 计算机上,要获得最佳性能,可将 RPS 配置为使用同一 NUMA 上的 CPU 来处理接口接收队列的中断。
在非 NUMA 计算机上,可以使用所有 CPU。如果中断率很高,排除用于处理网络接口的 CPU 可提升性能。可以通过 /proc/interrupts
确定用于网络接口的 CPU。例如:
>
sudo
cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 ... 51: 113915241 0 0 0 Phys-fasteoi eth0 ...
在本例中,CPU 0
是唯一一个用于处理 eth0
中断的 CPU,因为只有 CPU0
包含非零值。
在 x86 和 AMD64/Intel 64 平台上,可以使用 irqbalance
将硬件中断分发给多个 CPU。有关详细信息,请参见man 1
irqbalance
。