【问题标题】:UDP Packet drop - INErrors Vs .RcvbufErrorsUDP 数据包丢弃 - INErrors 与 .RcvbufErrors
【发布时间】:2014-03-07 01:27:33
【问题描述】:

我编写了一个简单的 UDP 服务器程序来了解更多可能的网络瓶颈。

UDP Server:创建一个UDP socket,将其绑定到指定的port和addr,并将socket文件描述符添加到epoll兴趣列表中。然后它的 epoll 等待传入的数据包。在接收到传入的数据包(EPOLLIN)时,它会读取数据包并仅打印接收到的数据包长度。很简单,对吧:)

UDP Client:我使用了hping,如下图:

hping3 192.168.1.2 --udp -p 9996 --flood -d 100

当我以每秒 100 个数据包的速度发送 udp 数据包时,我没有发现任何 UDP 数据包丢失。但是当我淹没 udp 数据包(如上面的命令所示)时,我看到了明显的数据包丢失。

测试1: 当 26356 个数据包从 UDP 客户端泛滥时,我的示例程序仅接收 12127 个数据包,其余 14230 个数据包被内核丢弃,如 /proc/net/snmp 输出所示。

cat /proc/net/snmp | grep udp:
Udp:InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
udp:12372 0 14230 218 14230 0

对于 Test1,丢包率约为 53%。

我验证在客户端和服务器端使用“ethtool -S ethX”命令在硬件级别没有太大损失,而在 appln 级别我看到如上所述的 53% 的损失。

因此,为了减少丢包,我尝试了以下方法:
- 使用 命令增加了我的示例程序的优先级。
- 增加接收缓冲区大小(在系统级别和进程级别)

将优先级提高到 -20:

雷尼斯 -20 2022
2022(进程 ID)旧优先级 0,新优先级 -20

将接收缓冲区大小提高到 16MB:

在过程级别:
int sockbufsize = 16777216;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,(char *)&sockbufsize, (int)sizeof(sockbufsize))
在内核级别:
cat /proc/sys/net/core/rmem_default
16777216
猫 /proc/sys/net/core/rmem_max
16777216

在这些更改之后,执行 Test2。

测试2: 当 1985076 个数据包从 UDP 客户端泛滥时,我的示例程序接收到 1848791 个数据包,其余 136286 个数据包被内核丢弃,如 /proc/net/snmp 输出所示。

cat /proc/net/snmp | grep udp:
Udp:InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
udp:1849064 0 136286 236 0 0

对于 Test2 的丢包率是 6%。

丢包显着减少。但我有以下问题:

  1. 可以进一步减少丢包吗?!?我知道我在这里很贪心:) 但我只是想看看是否有可能进一步减少丢包。
  2. 与 Test1 不同,在 Test2 中,InErrors 与 RcvbufErrors 不匹配,并且 RcvbufErrors 始终为零。有人可以解释一下背后的原因吗?!? InErrors 和 RcvbufErrors 之间到底有什么区别。我了解 RcvbufErrors 但不是 InErrors。

感谢您的帮助和时间!!!

【问题讨论】:

  • 我知道这是一个古老的问题,但您发现这个问题的核心是什么吗?我正在尝试重现 InErrors > RcvbufErrors 条件。

标签: renice linux linux-kernel udp epoll


【解决方案1】:

如果硬件级别没有丢包,那么应该主要是内存问题,您应该能够调整内核配置参数以达到 0 丢包(显然您需要一个合理的平衡硬件来处理您的网络流量正在接收)。

我认为您缺少netdev_max_backlog,这对于传入的数据包很重要:

当接口接收数据包的速度超过内核处理它们的速度时,在 INPUT 端排队的最大数据包数。

【讨论】:

    【解决方案2】:

    InErrors 由以下部分组成:

    • 损坏的数据包(不正确的标头或校验和)
    • 完整的 RCV 缓冲区大小

    所以我猜你已经修复了缓冲区溢出问题(RcvbufErrors 为 0),剩下的是校验和不正确的数据包。

    【讨论】:

      【解决方案3】:

      调整 Linux 内核的网络堆栈以减少数据包丢失有点涉及,因为从驱动程序一直到网络堆栈都有很多调整选项。

      我写了一个long blog post,从上到下解释了所有的调整参数,并解释了/proc/net/snmp 中每个字段的含义,这样你就可以弄清楚为什么会发生这些错误。看一下,我认为它应该可以帮助您将网络下降到 0。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-02
        • 2015-12-02
        • 1970-01-01
        • 2011-02-14
        相关资源
        最近更新 更多