译|Monitoring and Tuning the Linux Networking Stack: Receiving Data(三)

简介: 译|Monitoring and Tuning the Linux Networking Stack: Receiving Data(三)
启用中断

此时,几乎所有东西都已设置好。剩下的只是启用网卡的中断并等待数据到达。启用中断是硬件特定的,但 igb 驱动程序在 __igb_open 中调用名为 igb_irq_enable 的辅助函数来实现。

写入寄存器为此设备启用中断。

static void igb_irq_enable(struct igb_adapter *adapter)
{
  /* ... */
    wr32(E1000_IMS, IMS_ENABLE_MASK | E1000_IMS_DRSTA);
    wr32(E1000_IAM, IMS_ENABLE_MASK | E1000_IMS_DRSTA);
  /* ... */
}
网络设备现已启动

驱动程序可能会做一些其他事情,如启动计时器、工作队列或其他硬件特定的设置。一旦完成,网络设备就已启动并准备好使用。

让我们看看如何监控和调优网络设备驱动程序的设置。

监控网络设备

有几种不同的方法可以监控您的网络设备,提供不同程度的粒度和复杂性。让我们从最精细的开始,逐渐过渡到最粗略的。

ethtool -S 使用

您可以运行 sudo apt-get install ethtool 在 Ubuntu 系统上安装 ethtool

安装完成后,您可以传递 -S 标志以及您想要获取统计信息的网络设备名称来访问统计信息。

使用 ethtool -S 监控详细的网卡设备统计信息(例如,数据包丢弃)。

$ sudo ethtool -S eth0
NIC statistics:
     rx_packets: 597028087
     tx_packets: 5924278060
     rx_bytes: 112643393747
     tx_bytes: 990080156714
     rx_broadcast: 96
     tx_broadcast: 116
     rx_multicast: 20294528
     ....

监控这些数据可能很困难。它很容易获得,但字段值没有标准化。不同的驱动程序,甚至不同版本的 相同 驱动程序可能会产生具有相同含义的不同字段名称。

您应该寻找带有 “drop”、“buffer”、“miss” 等标签的值。接下来,您将不得不阅读驱动程序源代码。您能够确定哪些值完全在软件中计算(例如,没有内存时增加),哪些值直接读取寄存器从硬件获得。对于寄存器值,您应该查阅硬件的数据表,以确定计数器的真实含义; ethtool 给出的许多标签都可能是误导性的。

sysfs 使用

sysfs 也提供了许多统计值,但它们的层级比直接提供的网卡级别统计值略高一些。

您可以使用 cat 在文件上查找丢弃的传入网络数据帧的数量,例如 eth0。

使用 sysfs 监控更高层级的网卡统计信息。

$ cat /sys/class/net/eth0/statistics/rx_dropped
2

计数器值分为 collisionsrx_droppedrx_errorsrx_missed_errors 等文件。

不幸的是,由驱动程序决定每个字段的含义,何时增加它们以及值来自哪里。您可能会注意到,有些驱动程序将某种类型的错误条件计为丢弃,但其他驱动程序可能将其计为错过。

如果这些值对您至关重要,您需要阅读驱动程序源代码,以准确了解您的驱动程序认为每个值的含义。

/proc/net/dev 使用

一个更高层级的文件是 /proc/net/dev,它为系统上的每个网络适配器提供高层级概要信息。

读取 /proc/net/dev 监控高层级网卡统计信息。

$ cat /proc/net/dev
Inter-|   Receive                                                                                                               |  Transmit
 face |                   bytes         packets errs drop fifo frame compressed     multicast |                   bytes           packets errs drop fifo colls carrier compressed
  eth0:    110346752214   597737500     0      2    0        0                    0  20963860   990024805984 6066582604     0       0    0      0         0                    0
       lo: 428349463836 1579868535     0      0    0        0                    0                  0    428349463836  1579868535     0       0    0      0         0                    0

这个文件显示了上面提到的 sysfs 文件中找到的值的子集,但它可能作为一个有用的一般参考。

上面提到的警告在这里也适用:如果这些值对您很重要,您仍然需要阅读驱动程序源代码,以准确了解何时、何地以及为什么它们会增加,以确保您对 error、drop 或 fifo 的理解与你的驱动程序相同。

调优网络设备

检查正在使用的接收队列数量

如果您的网卡和系统上加载的设备驱动程序支持 RSS / 多队列,您通常可以使用 ethtool 调整接收队列(也称为接收通道)的数量。

使用 ethtool 检查网卡接收队列的数量。

$ sudo ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:   0
TX:   0
Other:    0
Combined: 8
Current hardware settings:
RX:   0
TX:   0
Other:    0
Combined: 4

此输出显示预设的最大值(由驱动程序和硬件强制执行)和当前设置。

注意: 并非所有设备驱动程序都支持此操作。

如果您的 NIC 不支持此操作,则会出现错误。

$ sudo ethtool -l eth0
Channel parameters for eth0:
Cannot get device channel parameters
: Operation not supported

这意味着您的驱动程序没有实现 ethtool 的 get_channels 操作。这可能是因为网卡不支持调整队列数量,不支持 RSS / 多队列,或者您的驱动程序尚未更新以处理此功能。

调整接收队列的数量

一旦您找到了当前和最大队列数,您可以使用 sudo ethtool -L 调整这些值。

注意: 一些设备及其驱动程序仅支持组合队列,用于传输和接收,如上一节中的示例。

使用 ethtool -L 设置组合网卡传输和接收队列为 8。

$ sudo ethtool -L eth0 combined 8

如果您的设备和驱动程序支持单独设置接收队列和传输队列,并且您只想更改接收队列数为 8,则可以运行:

使用 ethtool -L 设置 NIC 接收队列数为 8。

$ sudo ethtool -L eth0 rx 8

注意: 对于大多数驱动程序,这些更改将使接口下线,然后重新启动;与此接口的连接将中断。对于一次性更改,这可能并不重要。

调整接收队列的大小

一些网卡及其驱动程序也支持调整接收队列的大小。具体如何操作取决于硬件,但幸运的是,ethtool 为用户提供了一种通用的调整大小的方法。在接收大量数据帧的时期,增加接收队列的大小可以帮助防止网卡丢失网络数据。不过,数据仍然可能在软件中丢失,并且需要其他调整来减少或完全消除丢失。

使用 ethtool -g 检查当前网卡队列大小。

$ sudo ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:   4096
RX Mini:  0
RX Jumbo: 0
TX:   4096
Current hardware settings:
RX:   512
RX Mini:  0
RX Jumbo: 0
TX:   512

上述输出表明硬件支持最多 4096 个接收和传输描述符,但目前仅使用 512 个。

使用 ethtool -G 增加每个接收队列的大小到 4096。

$ sudo ethtool -G eth0 rx 4096

注意: 对于大多数驱动程序,这些更改将使接口下线,然后重新启动;与此接口的连接将中断。对于一次性更改,这可能并不重要。

调整接收队列的处理权重

一些网卡支持设置权重来调整网络数据在接收队列之间的分配。

如果满足以下条件,您可以进行配置:

  • 网卡支持流量引导。
  • 驱动程序实现了 ethtool 函数 get_rxfh_indir_sizeget_rxfh_indir
  • 运行的 ethtool 版本足够新,支持命令行选项 -x-X 分别显示和设置引导表。

使用 ethtool -x 检查 RX 流量引导表。

$ sudo ethtool -x eth0
RX flow hash indirection table for eth3 with 2 RX ring(s):
0: 0 1 0 1 0 1 0 1
8: 0 1 0 1 0 1 0 1
16: 0 1 0 1 0 1 0 1
24: 0 1 0 1 0 1 0 1

此输出在左侧显示数据包哈希值,其中列出了接收队列 0 和 1。 因此,散列到 2 的数据包将被递送到接收队列 0,而散列到 3 的数据包将被递送到接收队列 1。

示例:在前两个接收队列之间均匀扩散处理

$ sudo ethtool -X eth0 equal 2

如果你想设置自定义权重来改变命中特定接收队列(以及CPU)的数据包数量,你也可以在命令行中指定这些权重:

使用 ethtool -X 设置自定义收队队列权重

$ sudo ethtool -X eth0 weight 6 2

上述命令指定接收队列 0 的权重为 6,接收队列 1 权重为 2,使得推送更多的数据到队列 0 处理。

一些网卡还允许您调整哈希算法中使用的字段,我们接下来会看到。

调整网络流的接收哈希字段

您可以使用 ethtool 来调整计算 RSS 时使用的哈希字段。

使用 ethtool -n 检查 UDP 接收流哈希所用的字段。

$ sudo ethtool -n eth0 rx-flow-hash udp4
UDP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA

对于 eth0,计算 UDP 流的哈希的字段是 IPv4 源地址和目标地址。让我们添加源端口和目标端口:

使用 ethtool -N 设置 UDP 接收流哈希字段。

$ sudo ethtool -N eth0 rx-flow-hash udp4 sdfn

sdfn 字符串有点神秘;请查看 ethtool 手册页获取每个字母的解释。

调整哈希的字段很有用,但是,对于更精细地控制哪些流将由哪个接收队列处理, ntuple 过滤更有用。

ntuple 过滤引导网络流

一些网卡支持一种称为 “ntuple 过滤” 的功能。此功能允许用户通过 ethtool 指定一组参数,在硬件中过滤传入的网络数据并将其排队到特定的接收队列。例如,用户可以指定目标为特定端口的 TCP 数据包应发送到接收队列 1。

在英特尔网卡上,此功能通常称为 Intel Ethernet Flow Director。其他网卡供应商可能为此功能提供其他营销名称。

正如我们稍后将看到的,ntuple 过滤是另一种称为加速接收流引导 (aRFS) 的功能的关键组成部分,如果您的网卡支持它,则使用 ntuple 更容易。aRFS 将在后面介绍。

如果系统的运行要求最大化数据局部性,以期在处理网络数据时提高 CPU 缓存命中率,那么此功能可能很有用。例如,考虑在端口 80 上运行的 Web 服务器的以下配置:

  • 在端口 80 上运行的 Web 服务器被固定在 CPU 2 上运行。
  • 接收队列的 IRQ 被分配给 CPU 2 处理。
  • 目标为端口 80 的 TCP 流量使用 ntuple 过滤到 CPU 2。
  • 所有传入端口 80 的流量都由 CPU 2 处理,从数据到达用户程序开始。
  • 需要仔细监控系统,包括缓存命中率和网络堆栈延迟,以确定有效性。

如前所述,可以使用 ethtool 配置 ntuple 过滤,但首先,您需要确保在您的设备上启用了此功能。

使用 ethtool -k 检查是否启用了 ntuple 过滤。

$ sudo ethtool -k eth0
Offload parameters for eth0:
...
ntuple-filters: off
receive-hashing: on

正如所见,在这个设备上 ntuple-filters 被禁用。

使用 ethtool -K 启用 ntuple 过滤

$ sudo ethtool -K eth0 ntuple on

一旦你启用了 ntuple 过滤,或者验证它已经启用,你可以使用 ethtool 检查现有的ntuple 规则:

使用 ethtool -u 检查现有的 ntuple 过滤

$ sudo ethtool -u eth0
40 RX rings available
Total 0 rules

如您所见,此设备没有 ntuple 过滤规则。您可以在 ethtool 命令行上指定它来添加规则。让我们添加一个规则,定向目标端口为 80 的所有 TCP 流量到接收队列 2:

添加 ntuple 过滤器,发送目标端口为 80 的 TCP 流量到接收队列 2。

$ sudo ethtool -U eth0 flow-type tcp4 dst-port 80 action 2

您还可以使用 ntuple 过滤在硬件级别丢弃特定流的数据包。这对于缓解来自特定 IP 地址的大量传入流量很有用。有关配置 ntuple 过滤规则的更多信息,请参阅 ethtool 手册页。

您通常可以检查 ethtool -S [设备名称] 输出的值来获取有关 ntuple 规则成功(或失败)的统计信息。例如,在英特尔网卡上,统计信息 fdir_matchfdir_miss 计算您的 ntuple 过滤规则的匹配和未命中次数。请查阅您的设备驱动程序源代码和设备数据表以追查统计计数器(如果可用)。

目录
相关文章
|
7月前
|
监控 Linux
Linux的epoll用法与数据结构data、event
Linux的epoll用法与数据结构data、event
92 0
|
运维 监控 网络协议
译|llustrated Guide to Monitoring and Tuning the Linux Networking Stack: Receiving Data
译|llustrated Guide to Monitoring and Tuning the Linux Networking Stack: Receiving Data
143 0
|
Linux
linux下的内存查看(virt,res,shr,data的意义)
linux下的内存查看(virt,res,shr,data的意义)
172 0
|
SQL 存储 缓存
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(十)
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(十)
363 1
|
SQL 缓存 监控
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(十一)
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(十一)
156 0
|
缓存 监控 Linux
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(九)
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(九)
241 0
|
监控 Linux 调度
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(八)
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(八)
99 0
|
存储 Ubuntu Linux
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(七)
译|Monitoring and Tuning the Linux Networking Stack: Sending Data(七)
147 0
|
15天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
104 6
|
16天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
57 3