Udp 多播数据包丢失-运行同一应用程序的两个实例

Udp 多播数据包丢失-运行同一应用程序的两个实例,udp,multicast,Udp,Multicast,在Redhat Linux上,我有一个多播侦听器,侦听非常繁忙的多播数据源。它本身运行完美,没有数据包丢失。然而,一旦我使用完全相同的设置(相同的src/dst IP地址、sock缓冲区大小、用户缓冲区大小等)启动同一应用程序的第二个实例,我开始看到这两个实例的数据包丢失非常频繁。他们丢失了完全相同的数据包。如果我停止其中一个实例,其余的实例将恢复正常,不会丢失任何数据包 起初,我认为这是CPU/内核负载问题,也许它不能足够快地将数据包从缓冲区中取出。所以我做了另一个测试。我仍然保持应用程序的一

在Redhat Linux上,我有一个多播侦听器,侦听非常繁忙的多播数据源。它本身运行完美,没有数据包丢失。然而,一旦我使用完全相同的设置(相同的src/dst IP地址、sock缓冲区大小、用户缓冲区大小等)启动同一应用程序的第二个实例,我开始看到这两个实例的数据包丢失非常频繁。他们丢失了完全相同的数据包。如果我停止其中一个实例,其余的实例将恢复正常,不会丢失任何数据包

起初,我认为这是CPU/内核负载问题,也许它不能足够快地将数据包从缓冲区中取出。所以我做了另一个测试。我仍然保持应用程序的一个实例运行。但随后在同一台计算机上启动了一个完全不同的多播侦听器,但使用第二个NIC卡侦听不同但更繁忙的多播源。两个应用程序都运行良好,没有任何数据包丢失

因此,看起来一个NIC卡的功能不足以支持两个多播应用程序,即使它们侦听的内容完全相同。数据包丢失问题的可能原因可能是,在这种情况下,NIC卡驱动程序需要将传入数据复制到两个sock缓冲区,而此额外的复制任务对以太卡来说太多,以太卡无法处理,因此会丢弃数据包。对这个问题有没有更深入的分析和可能的解决方案


谢谢

您基本上发现内核在扇出多播数据包时效率低下。最坏情况下,代码针对每个传入数据包分配两个新缓冲区,即SKB对象和数据包负载,并复制NIC缓冲区两次

选择最佳情况,为每个传入数据包分配一个新的SKB,但数据包有效负载在两个套接字之间通过引用计数共享。现在想象一下,当两个应用程序分别位于各自的核心和独立的套接字上时会发生什么。每个对数据包有效负载的引用都会导致内存总线暂停,同时两个核心缓存都必须刷新和重新加载,并且每个应用程序都必须来回切换内核上下文以传递套接字有效负载。结果是糟糕的表现

您不是第一个遇到这种问题的人,许多供应商已经为其创建了解决方案。基本设计是将传入数据限制为一个套接字上一个内核上的一个线程,然后让该线程将数据分发给所有其他感兴趣的线程,最好使用基于共享内存和无锁数据结构的用户空间代码

例如,TIBCO的会合站和29 West的Ultra Messaging显示了660ns IPC总线:


这真的很奇怪。NIC卡不会立即从NIC设备驱动程序复制到套接字。当NIC接收到多播帧时,多播服务例程将进行过滤并将数据包转发到协议栈例程。协议栈例程负责将UDP数据包复制到每个套接字缓冲区。如果让两个实例加入相同的多播地址,但在不同的接口上,会发生什么情况?我无法进行此测试,因为只有此NIC端口连接到数据源。但是我做的测试(在问题中提到)表明它应该有效。但是我真的很想让它在同一个网卡上工作。嗨,史蒂夫,有没有开源解决方案可以解决这个问题?@bdubey签出或。