Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

6.3. 配置工具

红帽企业版 Linux 提供大量工具来协助管理员配置系统。本章概述了可用的工具并举例说明如何使用它们来解决在红帽企业版 Linux 7 中与网络相关的性能问题。
但要记住的重要的一点是,网络性能问题有时是硬件故障或基础结构层故障造成的。红帽极力推荐在开始调节网络堆栈前先核实硬件及基础结构层在按预期运作。
此外,比起重新配置网络子系统来说,通过改变应用程序来解决一些网络性能问题显得较为容易。通常,配置应用程序来运行频繁的 posix 调用是个好办法,即使这意味着在应用程序空间排列数据,但这使得数据存储灵活且能按要求换入或换出内存。

6.3.1. 网络性能 Tuned-adm 配置文件

tuned-adm 对很多特定用例提供大量不同的配置文件以提高性能。以下配置文件有助于提高网络性能。
  • 延迟性能
  • 网络延迟
  • 网络吞吐量
关于这些配置文件的更多信息,请见 <第 A.6 节 “tuned-adm”>。

6.3.2. 配置硬件缓冲区

如果硬件缓冲区弃置了大量的数据包,那么有很多可能的解决方法。
减缓输入流量
筛选传入的流量,减少加入的多播组数量或减少广播流量,以降低队列填充率。筛选传入流量的方法,详情请见 Red Hat Enterprise Linux 7 Security Guide。关于多播组详情,请见红帽企业版 Linux 7 聚类分析文档。关于广播流量详情,请见 《红帽企业版 Linux 7 系统管理员参考指南》,或用户想要配置的设备相关文档。所有红帽企业版 Linux 7 的文档可从 http://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/ 中获取。
调整硬件缓冲队列
通过增加队列的大小以减少传送的数据包数量,使其不易过剩。用户可以使用 ethtool 指令来更改网络设备的 rx/tx 参数:
# ethtool --set-ring devname value
改变队列的排出率
设备重量是指设备一次可以接收的数据包数量(单个预定处理器访问)。用户可以通过提高设备重量以增加队列的排出比率,这由 dev_weight 参数控制。此参数可以通过改变 /proc/sys/net/core/dev_weight 文件的内容来做临时更改,或使用 sysctl 进行永久更改,这由 procps-ng 数据包提供。
改变队列排出率通常是缓解不良网络性能最简单的方法。但是,增加设备一次可以接收的数据包数量会消耗处理器额外的时间,在此期间不可调度其他进程,因此可能会导致其他性能问题。

6.3.3. 配置中断队列

如果分析显示高延迟,系统可能受益于基于轮询的包接收,而不是基于中断的包接收。

6.3.3.1. 配置繁忙轮询

繁忙轮询有助于减少网络接收路径中的延迟, 使 socket 层代码查询网络设备的接收队列并禁用网络中断,这可以消除由于中断和由此产生的环境切换所造成的延误。但是,它会增加 CPU 的使用率。繁忙轮询可以防止 CPU 进入睡眠状态,睡眠状态会造成额外的功耗。
繁忙轮询是默认禁用的。要在特定 socket 中启用繁忙轮询,请按以下指示:
  • sysctl.net.core.busy_poll 设置为除 0 以外的值。这一参数控制的是 socket 轮询和选择位于等待设备队列中数据包的微秒数。红帽推荐值为 50
  • 添加 SO_BUSY_POLL socket 选项至 socket。
要全局启用繁忙轮询, 须将 sysctl.net.core.busy_read 设置为除了 0 以外的值。这一参数控制了socket 读取位于等待设备队列中数据包的微秒数,且设置了 SO_BUSY_POLL 选项的默认值。红帽推荐在 socket 数量少时将值设置为 50 , socket 数量多时将值设置为 100。对于 socket 数量极大时(超过几百),请使用 epoll
繁忙轮询由以下驱动程序支持。红帽企业版 Linux 7 支持这些驱动程序。
  • bnx2x
  • be2net
  • ixgbe
  • mlx4
  • myri10ge

6.3.4. 配置 socket 接收队列

如果分析数据显示,数据包由于 socket 队列排出率太慢而被弃置,有几种方法来解决由此产生的性能问题。
减少传入流量的速度
减少队列填充速率可以通过筛选或弃置进入队列前的数据包,或是减少设备重量。
增加应用程序的 socket 队列深度
如果一个 socket 队列接收数量有限的涌入流量,增加 socket 的队列深度以便与涌入的流量大小相配,从而防止数据包被弃置。

6.3.4.1. 减少传入流量的速度

筛选传入流量或降低网络接口卡的设备重量来减少传入的流量。关于筛选传入流量的方法,详情请见 《红帽企业版 Linux 7 安全指南》,可从 http://access.redhat.com/site/documentation/Red_Hat_Enterprise_Linux/ 中获取。
设备重量是指设备一次可以接收的数据包数量(单个预定处理器访问)。设备重量由 dev_weight 参数控制。此参数可以通过改变 /proc/sys/net/core/dev_weight 文件的内容来做临时更改,或是使用 sysctl 来做永久更改,这由 procps-ng 数据包提供。

6.3.4.2. 增加队列深度

增加应用程序的 socket 队列深度往往是提高 socket 队列排出率最简单的方法,但不可能是一个长期的解决方法。
要增加队列深度就要增加 socket 接收缓冲区的大小,可以做如下变化:
增加 /proc/sys/net/core/rmem_default 值
这一参数控制 socket 使用的接收缓冲区的默认大小,这个值必须小于 /proc/sys/net/core/rmem_max 的值。
使用 setsockopt 配置较大的 SO_RCVBUF 值
这一参数控制的是以字节为单位的 socket 接收缓冲区的最大值。使用 getsockopt 系统调用来确定当前缓冲区的值。此参数的更多信息,请见手册页:
$ man 7 socket

6.3.5. 配置 RSS

RSS(接收端调整),也叫多队列接收,是通过一些基于硬件的接收队列来分配网络接收进程,从而使入站网络流量可以由多个 CPU 进行处理。RSS 可以用来缓解接收中断进程中由于单个 CPU 过载而出现的瓶颈,并减少网络延迟。
要确定您的网络接口卡是否支持 RSS,须查看多个中断请求队列是否在 /proc/interrupts 中有相关的接口。例如,如果用户对 p1p1 接口有兴趣:
# egrep 'CPU|p1p1' /proc/interrupts
   CPU0    CPU1    CPU2    CPU3    CPU4    CPU5
89:   40187       0       0       0       0       0   IR-PCI-MSI-edge   p1p1-0
90:       0     790       0       0       0       0   IR-PCI-MSI-edge   p1p1-1
91:       0       0     959       0       0       0   IR-PCI-MSI-edge   p1p1-2
92:       0       0       0    3310       0       0   IR-PCI-MSI-edge   p1p1-3
93:       0       0       0       0     622       0   IR-PCI-MSI-edge   p1p1-4
94:       0       0       0       0       0    2475   IR-PCI-MSI-edge   p1p1-5
之前的输出显示 NIC 驱动程序为 p1p1 接口创建了 6 个接收队列(p1p1-0p1p1-5)。也显示出每个队列处理的中断数量以及处理中断的 CPU。在这种情况下,由于有 6 个默认队列,这一特殊的 NIC 驱动程序就为每个 CPU 创建一个队列,这个系统一共有 6 个 CPU。这是 NIC 驱动程序中很常见的模式。
或者用户可以在网络驱动程序加载后查看 ls -1 /sys/devices/*/*/device_pci_address/msi_irqs 的输出。例如,如果用户对 PCI 地址为 0000:01:00.0 的设备感兴趣,可以通过以下指令来列出该设备中断请求队列:
# ls -1 /sys/devices/*/*/0000:01:00.0/msi_irqs
101
102
103
104
105
106
107
108
109
RSS 是默认启用的。RSS 的队列数(或是需要运行网络活动的 CPU )会由适当的网络驱动程序来进行配置。 bnx2x 驱动程序是在 num_queues 中进行配置。sfc 驱动程序是用 rss_cpus 参数进行配置。通常,这都是在 /sys/class/net/device/queues/rx-queue/ 中进行配置,其中 device 是网络设备的名称(比如 eth1),rx-queue 是适当的接收队列名称。
配置 RSS 时,红帽推荐限制每一个物理 CPU 内核的队列数量。超线程在分析工具中通常代表独立的内核,但是所有内核的配置队列,包括如超线程这样的逻辑内核尚未被证实对网络性能有益。
启用时,基于每个队列的 CPU 进程数量,RSS 在 CPU 间平等地分配网络进程。但是,用户可以使用 ethtool --show-rxfh-indir--set-rxfh-indir 参数来更改网络活动的分配方式,并权衡哪种类型的网络活动更为重要。
irqbalance 后台程序可与 RSS 相结合,以减少跨节点内存及高速缓存行反弹的可能性。这降低了处理网络数据包的延迟。

6.3.6. 配置 RPS

RPS(接收端包控制)与 RSS类似,用于将数据包指派至特定的 CPU 进行处理。但是,RPS 是在软件级别上执行的,这有助于防止单个网络接口卡的软件队列成为网络流量中的瓶颈。
较之于基于硬件的 RSS ,RPS 有几个优点:
  • RPS 可以用于任何网络接口卡。
  • 易于添加软件过滤器至 RPS 来处理新的协议。
  • RPS 不会增加网络设备的硬件中断率。但是会引起内处理器间的中断。
每个网络设备和接收队列都要配置 RPS,在 /sys/class/net/device/queues/rx-queue/rps_cpus 文件中,device 是网络设备的名称(比如 eth0),rx-queue 是适当的接收队列名称(例如 rx-0)。
rps_cpus 文件的默认值为 0。这会禁用 RPS,以便处理网络中断的 CPU 也能处理数据包。
要启用 RPS,配置适当的 rps_cpus 文件以及特定网络设备和接收队列中须处理数据包的 CPU 。
rps_cpus 文件使用以逗号隔开的 CPU 位图。因此,要让 CPU 在一个接口为接收队列处理中断,请将它们在位图里的位置值设为 1。例如,用 CPU 0、1、2 和 3 处理中断,将 rps_cpus 的值设为 00001111 (1+2+4+8),或 f(十六进制的值为 15)。
对于单一传输队列的网络设备,配置 RPS 以在同一内存区使用 CPU 可获得最佳性能。在非 NUMA 的系统中,这意味着可以使用所有空闲的 CPU。如果网络中断率极高,排除处理网络中断的 CPU 也可以提高性能。
对于多队列的网络设备,配置 RPS 和 RSS 通常都不会有好处,因为 RSS 配置是默认将 CPU 映射至每个接收队列。但是,如果硬件队列比 CPU 少,RPS依然有用,并且配置 RPS 是来在同一内存区使用 CPU。

6.3.7. 配置 RFS

RFS(接收端流的控制)扩展了 RPS 的性能以增加 CPU 缓存命中率,以此减少网络延迟。RPS 仅基于队列长度转发数据包,RFS 使用 RPS 后端预测最合适的 CPU,之后会根据应用程序处理数据的位置来转发数据包。这增加了 CPU 的缓存效率。
RFS 是默认禁用的。要启用 RFS,用户须编辑两个文件:
/proc/sys/net/core/rps_sock_flow_entries
设置此文件至同时活跃连接数的最大预期值。对于中等服务器负载,推荐值为 32768 。所有输入的值四舍五入至最接近的2的幂。
/sys/class/net/device/queues/rx-queue/rps_flow_cnt
device 改为想要配置的网络设备名称(例如,eth0),将 rx-queue 改为想要配置的接收队列名称(例如,rx-0)。
将此文件的值设为 rps_sock_flow_entries 除以 N,其中 N 是设备中接收队列的数量。例如,如果 rps_flow_entries 设为 32768,并且有 16 个配置接收队列,那么 rps_flow_cnt 就应设为 2048。对于单一队列的设备,rps_flow_cnt 的值和 rps_sock_flow_entries 的值是一样的。
从单个发送程序接收的数据不会发送至多个 CPU。如果从单个发送程序接收的数据多过单个 CPU 可以处理的数量,须配置更大的帧数以减少中断数量,并以此减少 CPU 的处理工作量。或是考虑 NIC 卸载选项来获得更快的 CPU。
考虑使用 numactltaskset 与 RFS 相结合,以将应用程序固定至特定的内核、 socket 或 NUMA 节点。这可以有助于防止数据处理紊乱。

6.3.8. 配置加速 RFS

加速 RFS 是通过添加硬件协助来增速的。如同 RFS,数据转发是基于应用程序处理数据包的位置。但不同于传统 RFS 的是,数据是直接发送至处理数据线程的本地 CPU:即运行应用程序的 CPU,或是对于在缓存层次结构中的 CPU 来说的一个本地 CPU。
加速 RFS 只有满足以下条件才可以使用:
  • 网络接口卡须支持加速 RFS。加速 RFS 是由输出 ndo_rx_flow_steer() netdevice 功能的接口卡支持。
  • ntuple 筛选必须启用。
一旦满足了这些条件,队列映射 CPU 就会基于传统 RFS 配置自动导出。即队列映射 CPU 会基于由每个接收队列的驱动程序配置的 IRQ 关联而自动导出。从 <第 6.3.7 节 “配置 RFS”> 中来获取配置传统 RFS 的信息。
红帽推荐在可以使用 RFS 以及网络接口卡支持硬件加速时使用加速 RFS 。