【问题标题】:Big sent socket buffer size cause UDP packet loss大的发送套接字缓冲区大小导致 UDP 数据包丢失
【发布时间】:2021-09-01 20:21:13
【问题描述】:

操作系统:Centos7.6.10 内核:3.10.0-957.el7.x86_64 我使用netperf测试UDP。当我设置发送套接字大小8129920;接收套接字大小212992时,UDP数据包丢失很多。这个问题只会出现大数据包。two pc netperf test我尝试tcpdump,我发现发送的UDP数据不完整,总是缺少一个IP帧,导致对方无法合并这些帧。tcpdump result我在发送端PC上使用dropwatch查找内核问题,我找到了这些

1581 drops at brk_limit+369bd232 (0xffffffffc0437232)
1 drops at skb_queue_purge+18 (0xffffffff88a235d8)
1632 drops at brk_limit+369bd232 (0xffffffffc0437232)
1682 drops at brk_limit+369bd232 (0xffffffffc0437232)
1732 drops at brk_limit+369bd232 (0xffffffffc0437232)
1 drops at brk_limit+369bd232 (0xffffffffc0437232)
1783 drops at brk_limit+369bd232 (0xffffffffc0437232)
1834 drops at brk_limit+369bd232 (0xffffffffc0437232)
1882 drops at brk_limit+369bd232 (0xffffffffc0437232)
2 drops at brk_limit+369bd232 (0xffffffffc0437232)
1934 drops at brk_limit+369bd232 (0xffffffffc0437232)
1984 drops at brk_limit+369bd232 (0xffffffffc0437232)
2 drops at brk_limit+369bd232 (0xffffffffc0437232)
2036 drops at brk_limit+369bd232 (0xffffffffc0437232)
2087 drops at brk_limit+369bd232 (0xffffffffc0437232)
2135 drops at brk_limit+369bd232 (0xffffffffc0437232)
4 drops at brk_limit+369bd232 (0xffffffffc0437232)
2187 drops at brk_limit+369bd232 (0xffffffffc0437232)
2237 drops at brk_limit+369bd232 (0xffffffffc0437232)
2289 drops at brk_limit+369bd232 (0xffffffffc0437232)
2338 drops at brk_limit+369bd232 (0xffffffffc0437232)
2 drops at brk_limit+369bd232 (0xffffffffc0437232)
2390 drops at brk_limit+369bd232 (0xffffffffc0437232)
2439 drops at brk_limit+369bd232 (0xffffffffc0437232)
3 drops at brk_limit+369bd232 (0xffffffffc0437232)
2492 drops at brk_limit+369bd232 (0xffffffffc0437232)
2544 drops at brk_limit+369bd232 (0xffffffffc0437232)
2595 drops at brk_limit+369bd232 (0xffffffffc0437232)
2641 drops at brk_limit+369bd232 (0xffffffffc0437232)
2694 drops at brk_limit+369bd232 (0xffffffffc0437232)
2745 drops at brk_limit+369bd232 (0xffffffffc0437232)
2 drops at udp4_lib_rcv+b9 (0xffffffff88ab5139)
2795 drops at brk_limit+369bd232 (0xffffffffc0437232)
2846 drops at brk_limit+369bd232 (0xffffffffc0437232)
2898 drops at brk_limit+369bd232 (0xffffffffc0437232)
2949 drops at brk_limit+369bd232 (0xffffffffc0437232)
3000 drops at brk_limit+369bd232 (0xffffffffc0437232)
251 drops at __brk_limit+369bd232 (0xffffffffc0437232)
6 drops at icmp_rcv+125 (0xffffffff88aba7a5)**

the network card info这个现象我看不懂,希望大家帮我解决这个问题,谢谢!

【问题讨论】:

    标签: linux sockets tcp udp kernel


    【解决方案1】:

    Linux 提供了一些栈内流控制,设置一个非常大的 UDP 发送套接字缓冲区可以短路它。栈内流控制取决于出口接口,其传输队列 (txqueuelen) 大到足以容纳比 UDP 发送套接字缓冲区容纳更多的数据报。或者换一种说法,UDP 发送套接字缓冲区不能容纳超过可以排队到接口传输队列。

    否则,当发送 UDP 数据报的速度快于它们离开接口时,而不是填充发送套接字缓冲区,从而使套接字不可写,直到一些数据报离开系统,接口传输队列溢出并且数据包开始出站被丢弃。

    您可能会在 netstat -s 输出的 Udp: 部分中看到相关统计信息。

    您“应该”做的不是使发送套接字缓冲区变得如此之大。对于 UDP,它需要足够大,以最大限度地从接口获取数据报。 10 次中有 99 次(原文如此)默认值应该没问题。您可能需要增加大小的是接收器上的接收套接字缓冲区。

    另外,除非您的应用程序发送 65507 字节的消息,否则您应该添加一个特定于测试的 -m 选项来告诉 netperf 发送与您的应用程序通常发送的字节数一样多的字节数。

    就目前而言,您将发送套接字缓冲区设置为 8129920 字节意味着它可以容纳 124、65507 字节的 UDP 数据报。正如大卫指出的那样,当这些数据包被分成 44 个 IP 数据报片段时,这将是 5456 个数据包。默认接口发送队列长度为1000包...

    【讨论】:

      【解决方案2】:

      这是预期的行为。假设您发送一个 65,500 字节的数据报,而您的最大数据包大小为 1,500 字节。这意味着每个数据报需要 44 个数据包。现在说你的丢包率是 1%。这意味着您的数据报丢失率为 35%。哎哟。

      不要使用这么大的数据报。或者不要使用 UDP。

      【讨论】:

      • 但是我在vmware中安装了Centos 7并设置了Consistent配置。没有UDP丢包。
      • UDP 不提供可靠传输,期间。这就是UDP的本质。如果您不能容忍数据报丢失,请不要使用 UDP。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2015-04-16
      • 2012-04-16
      相关资源
      最近更新 更多