31.2. 数据包接收瓶颈

虽然网络堆栈大多优化了,但网络数据包处理过程中有很多点,这可能会成为瓶颈并降低性能。

以下是可能导致瓶颈的问题:

网卡的缓冲或环缓冲
如果内核丢弃大量数据包,则硬件缓冲区可能会出现瓶颈。使用 ethtool 工具监控系统丢弃的数据包。
硬件或软件中断队列
中断可能会增加延迟和处理器争用。如需有关处理器如何处理中断的信息,请参阅关于中断请求的概述手动的负载平衡中断 以及设置 smp_affinity 掩码
应用程序的套接字接收队列
在 /proc/net/snmp 文件中,没有复制或由没有在 /proc/net/snmp 文件中的 UDP 输入错误 (InErrors) 的大量数据包被增加,表示应用程序接收队列中出现瓶颈。

如果硬件缓冲区丢弃大量数据包,则以下是几个潜在的解决方案:

减慢输入流量的速度
过滤流量,减少加入多播组的数量,或者减少广播流量的数量,以减少队列填满率。
调整硬件缓冲区队列大小

重新定义硬件缓冲区队列的大小:通过增加队列的大小来丢弃数据包的数量,使其不会像易管理而溢出。您可以使用 ethtool 命令修改网络设备的 rx/tx 参数:

ethtool --set-ring device-name value

更改队列的排空率
  • 在进入队列前进行过滤或丢弃数据包,或降低设备的权重,可以减少队列被填充的速率。过滤传入的流量或降低网卡的设备权重,以减慢传入流量的速度。

    设备权重指的是,设备可在单个调度的处理器访问中一次接收的数据包数量。您可以通过增加其由 dev_weight 内核设置控制的设备权重来增加排空队列的速度。要临时更改此参数,请更改 /proc/sys/net/core/dev_weight 文件的内容,或使用 procps-ng 软件包提供的 sysctl 命令。

  • 增加应用程序的插槽队列长度:这通常是提高套接字队列的排空率最简单的方法,但不太可能是长期解决方案。如果套接字队列收到大量突发的流量,增加套接字队列的深度,以匹配突发流量的大小可能会阻止数据包被丢弃。要增加队列的深度,请通过进行以下更改来增加套接字接收缓冲区的大小:

    • 增加 /proc/sys/net/core/rmem_default 参数的值:此参数控制套接字使用的接收缓冲区的默认大小。这个值必须小于或等于 /proc/sys/net/core/rmem_max 参数的值。
    • 使用 setockopt 配置更大的 SO_RCVBUF 值:此参数控制套接字接收缓冲区的最大大小(以字节为单位)。使用 getockopt 系统调用来确定缓冲区的当前值。

更改队列的排空率通常是降低网络性能的最简单方法。但是,增加一个设备一次可以接收的数据包数量使用额外的处理器时间,在此期间没有可以调度其他进程,因此这可能会导致其他性能问题。

其他资源

  • ss(8), socket(7), 和 ethtool(8) man page
  • /proc/net/snmp 文件