linux内核丢弃UDP数据包

linux内核丢弃UDP数据包,linux,udp,multicast,packet-loss,Linux,Udp,Multicast,Packet Loss,我有一个通过多播发送UDP数据包的服务器,还有一些客户端正在列出这些多播数据包。 每个数据包的固定大小为1040字节,服务器发送的整个数据大小为3GB 我的环境如下: 1Gbit以太网 40个节点,1个发送方节点和39个接收方节点。 所有节点都有相同的硬件配置:2个AMD CPU,每个CPU有2个内核@2,6GHz 在客户端,一个线程读取套接字并将数据放入队列。另外一个线程从队列中弹出数据并进行一些轻量级处理 在多播传输期间,我发现节点端的丢包率为30%。通过观察netstat–su统计数据,我

我有一个通过多播发送UDP数据包的服务器,还有一些客户端正在列出这些多播数据包。 每个数据包的固定大小为1040字节,服务器发送的整个数据大小为3GB

我的环境如下:

1Gbit以太网

40个节点,1个发送方节点和39个接收方节点。 所有节点都有相同的硬件配置:2个AMD CPU,每个CPU有2个内核@2,6GHz


在客户端,一个线程读取套接字并将数据放入队列。另外一个线程从队列中弹出数据并进行一些轻量级处理

在多播传输期间,我发现节点端的丢包率为30%。通过观察netstat–su统计数据,我可以说,客户端应用程序丢失的数据包等于netstat输出的RcvbufErrors值

这意味着所有丢失的数据包都会被操作系统丢弃,因为套接字缓冲区已满,但我不理解捕获线程为什么不能及时读取缓冲区。 在传输过程中,4个内核中的2个被75%利用,其余的正在休眠。 我是唯一一个使用这些节点的人,我假设这种机器在处理1Gbit带宽方面没有问题。我已经做了一些优化,通过为amd CPU添加g++编译器标志,这将丢包率降低到10%,但在我看来还是太高了

当然我知道UDP是不可靠的,我有自己的修正协议

我没有任何管理权限,因此无法更改系统参数

有什么可以提高性能的提示吗

编辑:
我通过使用读取套接字的两个线程解决了这个问题。recv套接字缓冲区有时仍会变满。但平均降幅在1%以下,因此处理它不成问题

除了从套接字读取循环中明显删除所有不必要的内容外:

  • 增加套接字接收缓冲区
  • 如果您的内核支持,请使用它来减少系统调用和内核用户区拷贝的数量
  • 考虑边缘触发的非阻塞方法
  • 看看这里是否真的需要线程,锁定/同步非常昂贵
  • 在客户端,一个线程读取套接字并将数据放入队列
    我想问题就出在这条线上。它接收消息的速度不够快。太多的时间花在其他事情上,例如在将数据放入队列时获取互斥。尝试优化队列上的操作,例如使用无锁队列。

    在Linux上跟踪网络丢弃可能有点困难,因为有许多组件可能发生数据包丢弃。它们可以发生在硬件级别、网络设备子系统或协议层


    我写了一篇非常详细的文章,解释如何监视和调优每个组件。这里有点难概括为一个简洁的答案,因为有太多不同的组件需要监控和调整。

    您可以调查是否有巨型帧支持,并为每个数据包发送更多数据,从而减少节点必须处理的中断量。在最坏的情况下,网络驱动程序不够好。仅为了第一个项目的完整性:(1)内核可能会限制大小-因此请阅读
    /proc/sys/net/core/rmem_max
    ,&(2)用于
    setsockopt
    optval
    so\RCVBUF