为什么我的 TCP 吞吐量远大于 UDP 吞吐量?

ell*_*iel 16 performance networking tcp udp

我没有对我的硬件或内核配置(所有默认设置、全新操作系统安装、Linux 内核 3.11 TCP/IP 堆栈)进行任何异常处理,我通过 TCP 平均每秒发送大约 383 万条消息,而我平均只有 0.75每秒通过 UDP 发送百万条消息。这似乎完全违背了我对这两个协议的期望。

造成巨大差异的最可能原因是什么,我如何在 Ubuntu 13.10 上对其进行诊断?

#TCP RESULTS
Recv   Send    Send                          Utilization       Service Demand
Socket Socket  Message  Elapsed              Send     Recv     Send    Recv
Size   Size    Size     Time     Throughput  local    remote   local   remote
bytes  bytes   bytes    secs.    10^6bits/s  % S      % S      us/KB   us/KB

87380  65536     64    10.00      1963.43   32.96    17.09    5.500   2.852

#UDP RESULTS
Socket  Message  Elapsed      Messages                   CPU      Service
Size    Size     Time         Okay Errors   Throughput   Util     Demand
bytes   bytes    secs            #      #   10^6bits/sec % SS     us/KB

4194304      64   10.00     7491010      0      383.5     28.97    24.751
212992            10.00     1404941              71.9     25.03    21.381
Run Code Online (Sandbox Code Playgroud)

对于这个测试,我有两个相同的测试服务器,它们通过 10G 交叉电缆直接连接。在这种情况下使用的 NIC 是具有开箱即用配置的 Intel X520,并连接到主板上的 PCIe 3.0 x8 插槽,该插槽通过 NUMA 控制器与 CPU 通信。

Ste*_*ich 30

除了没有获得有关您的测试设置的详细信息之外,主要问题似乎是您使用了 64 字节的消息大小。这与通常的 1500 字节 MTU 相去甚远,并且使 UDP 的效率非常低:虽然 TCP 将多个发送合并到线路上的单个数据包中(除非设置了 TCP_NODELAY)以有效利用链接,但每个 UDP 消息将导致一个单独的包。在数量上:大约 23 个 64 字节大小的消息将组合成一个 MTU 大小的 TCP 数据包,而对于相同数量的数据,UDP 需要 23 个单个数据包。这些数据包中的每一个都意味着来自主机的发送、在线传输和对等方接收的开销。正如您所看到的,大约 80% 的 UDP 数据包丢失了,因为您的硬件速度不够快,无法传输和接收所有这些数据包。

所以你可以从这个基准测试中学到:

  • UDP 不可靠(80% 丢包)
  • 如果使用远低于 MTU 的数据包大小,则 UDP 效率低下
  • TCP 高度优化以充分利用链路

至于您的期望,UDP 应该更好:您有没有想过为什么所有主要的文件传输(ftp、http、...)都是使用基于 TCP 的协议完成的?基准向您展示原因。

那么人们为什么要使用UDP呢?

  • 对于实时数据(例如 IP 语音),您不关心较旧的消息,因此您不希望发送方将消息组合成更大的数据包以有效利用链路。并且您宁愿接受数据包丢失而不是太晚到达。
  • 对于高延迟链接(如卫星),TCP 的默认行为不是有效利用链接的最佳方式。所以有些人在这种情况下切换到 UDP 并重新实现 TCP 的可靠性层并针对高延迟链路对其进行优化,而其他人则调整现有的 TCP 堆栈以更好地利用链路。
  • “扔掉”数据:有时更重要的是将数据发送出去而不关心数据包丢失,例如日志消息(系统日志)
  • 短交互:使用 TCP,您需要建立连接并维护状态,这会花费客户端和服务器的时间和资源。对于短交互(如短请求和回复),这可能会造成过多的开销。因此,DNS 通常使用 UDP 完成,但在 UDP 之上构建了重试。

  • 您很可能是受 PCI Express 总线限制的 IO。网卡最有可能启用 TCP 段卸载。这意味着 TCP 传输将作为一个大块发送到卡,然后卡将它们切成小块,然后将它们放在线路上。UDP 没有等效项,因此每个数据包的结果是一个 PCIe 事务(以及所有相关的开销)。 (3认同)
  • 您还应该查看使用 UDP 的 80% 数据包丢失情况。看起来您的硬件速度不够快,无法以与发送的速度相同的速度处理数据包。虽然 TCP 以减慢来适应这种丢包,但 UDP 只会以相同的速度发送并继续丢失数据包。但最终与您发送的速度无关,而与您收到的内容有关。 (2认同)