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

时间:2011-07-08 16:48:42

标签: udp multicast

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

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

所以看起来一个NIC卡的功能不足以支持两个多播应用程序,即使它们听同样的事情也是如此。丢包问题的可能原因可能是,在这种情况下,NIC卡驱动程序需要将传入数据复制到两个sock缓冲区,而这个额外的复制任务对于以太网卡来说太多了,因此它会丢弃数据包。对此问题和任何可能的解决方案进行更深入的分析?

谢谢

1 个答案:

答案 0 :(得分:1)

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

选择最佳案例场景,为每个传入的数据包分配新的SKB,但数据包有效负载在两个套接字之间通过引用计数共享。现在想象两个应用程序会发生什么,每个应用程序都在自己的核心和单独的套接字上。对数据包有效负载的每次引用都会导致内存总线停止,而两个核心高速缓存都必须刷新并重新加载,并且高于每个应用程序必须来回内核上下文切换以传递套接字有效负载。结果是糟糕的表现。

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

例如TIBCO的Rendezvous和29 West的Ultra Messaging显示了660ns的IPC总线:

http://www.globenewswire.com/newsroom/news.html?d=194703