2011-07-08 33 views
3

在Redhat Linux上,我有一個多路廣播監聽器正在監聽非常繁忙的多播數據源。它本身完美運行,沒有數據包丟失。但是,一旦我使用完全相同的設置(相同的src/dst IP地址,sock緩衝區大小,用戶緩衝區大小等)啓動相同應用程序的第二個實例,我開始看到來自兩個實例的非常頻繁的數據包丟失。他們丟失了完全相同的數據包。如果我停止其中一個實例,則剩餘的一個會恢復正常,不會丟失任何數據包。組播數據包丟失 - 運行相同應用程序的兩個實例

最初,我雖然是CPU /內核負載問題,但它可能無法足夠快地將數據包從緩衝區中取出。所以我做了另一個測試。我仍然保持應用程序的一個實例正在運行。但隨後在同一臺計算機上啓動了一個完全不同的多路廣播監聽器,但使用第二個NIC卡並監聽一個不同但更繁忙的多播源。兩個應用程序運行良好,沒有任何丟包。

所以它看起來像一個NIC卡不夠強大,不足以支持兩個多播應用程序,即使他們聽着完全相同的東西。數據包丟失問題的可能原因可能是,在這種情況下,NIC卡驅動程序需要將傳入數據複製到兩個sock緩衝區,而這個額外的複製任務對於以太網卡來說太多了,因此它會丟棄數據包。有關此問題的更深入分析和任何可能的解決方案?

謝謝

+0

這實在是不可思議。 NIC卡不會立即從NIC設備驅動程序複製到套接字。當網卡接收到多播幀時,多播服務程序將進行過濾並將數據包轉發到協議棧例程。協議棧例程負責將UDP數據包複製到每個套接字緩衝區。 如果讓兩個實例加入相同的多播地址但在不同的接口上會發生什麼? – badawi

+0

我無法進行此測試,因爲只有此NIC端口連接到數據源。但是我做的測試(在問題中提到)表明它應該起作用。但我真的想讓它在同一個NIC卡上工作。 – welch

回答

1

您基本上發現內核在多播數據包扇出時效率低下。最糟糕的情況是代碼針對每個傳入數據包分配兩個新緩衝區,SKB對象和數據包有效負載,以及複製NIC緩衝區兩次。

選擇最佳情況,對於每個傳入數據包都分配了一個新的SKB,但數據包有效負載由兩個插座共享,並帶有引用計數。現在想象當兩個應用程序發生什麼時,每個應用程序在各自的核心和不同的套接字上。每個對數據包有效載荷的引用都會導致內存總線停頓,同時兩個核心緩存必須刷新並重新加載,並且在每個應用程序的上面都必須來回切換內核上下文以傳遞套接字有效載荷。結果是糟糕的表現。

你不是第一個遇到這樣的問題,許多供應商已經爲它創建瞭解決方案。基本設計是將傳入的數據限制在一個套接字上的一個核心上的一個線程上,然後讓該線程將數據分發給所有其他感興趣的線程,最好使用基於共享內存和無鎖數據結構的用戶空間代碼。

例子是TIBCO的交會29西方的Ultra消息顯示660ns IPC總線:

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

+0

嗨史蒂夫,任何開源的解決方案可用於解決這個問題? – bdubey

+0

@bdubey檢出[aeron](http://highscalability.com/blog/2014/11/17/aeron-do-we-really-need-another-messaging-system.html)或[disruptor](https: //lmax-exchange.github.io/disruptor/)。 –

相關問題