8.4. 解决常见队列/帧丢失问题
到目前为止,帧丢失最常见的原因是队列超限运转。该内核设定了队列长度限制,且在有些情况下队列填充的速度超过排出的速度。出现这种情况时间过长,则会开始出现掉帧的情况。
如 图 8.1 “网络接收路径图表” 所示,在接收路径中有两种主要队列:NIC 硬件缓冲和插槽队列。这两种队列都需要进行配置以放置队列超限运转。
8.4.1. NIC 硬件缓冲
NIC 使用帧填充其硬件缓冲;然后该缓冲会被
softirq
排干,通过中断肯定 NIC。要询问这个队列的状态,请使用以下命令:
ethtool -S ethX
使用 NIC 的对应设备名称替换
ethX
。这样会显示在 ethX
中已丢失的帧数。丢帧经常是因为该队列超过保存那些帧的缓冲空间所致。
解决这个问题有一些不同方法,即:
- 输入流量
- 您可以通过放缓下行输入流量放置队列超限运转。方法是过滤、减少联合多播组数、降低广播流量等等。
- 队列长度
- 另外,您也可以增加队列长度。这包括在指定队列中将缓冲数增加到该驱动程序最多可以承担的数量。方法是编辑
ethX
的rx
/tx
环参数,命令为:ethtool --set-ring ethX
在前面所说的命令中附加恰当的rx
/tx
值。详情请参考man ethtool
。 - 设备加权
- 您还可以增加排空队列的速度。方法是相应调整 NIC 的设备加权。这个属性指的是
softirq
上下文必须产生 CPU 并重新调度其本身前 NIC 可以接收的最多帧数。它由/proc/sys/net/core/dev_weight
变量控制。
大多数管理员有选择第三个选项的倾向。但请注意这样做会有一定的后果。在一个迭代中增加可以从 NIC 接收的帧数会造成额外的 CPU 周期,在此期间那个 CPU 无法调度任何应用程序。