2009-09-30 26 views
3

我有每個連接到服務器和接收數據從他們多個應用程序的處理。通常連接的服務器和檢索的數據在進程之間重疊。因此,有很多在網絡中的數據的不必要的重複,比應該是必要的(其中徵稅服務器)更多的連接,並且將數據最終得到冗餘地存儲在存儲器中的應用程式。通過多個進程共享連接和數據的最快方法?

一種解決方案是將多個應用程序合併到一個單一的一個 - 但在大多數情況下,他們確實在邏輯上不同,這可能是多年的工作。

不幸的是,等待時間非常重要,而且數據量很大(任何一個數據可能都不太大,但是一旦客戶端發出請求,服務器會在數據發生變化時發送更新流,可以高達20MB/s,並且這些全部都需要以儘可能短的延遲提供給請求的應用程序)。

,想到的解決方案是編碼一個本地守護進程,該應用程序流程將與請求數據。守護進程會檢查與相應服務器的連接是否已經存在,如果不存在,然後它會檢索數據並使用共享內存(由於延遲問題,否則我會使用套接字)將數據提供給請求的應用程序。

在短期內只會解決冗餘連接的一個簡單的想法是使用unix域套接字(這將在unix操作系統上運行,儘管我願意堅持跨平臺庫),以便共享一個套接字所有進程之間的描述符,因此它們共享一個連接。與此相關的問題是消耗緩衝區 - 我希望所有進程都能看到通過套接字的所有內容,如果我理解正確,使用此方法時,讀取套接字上的一個進程將阻止其他進程在其上看到相同的數據下一次讀取(共享描述符內的偏移量將被碰撞)。

回答

2

我相信,通過共享內存公開數據的專用服務是您最好的選擇。除此之外,它將是一種通過命名管道組播數據的服務,除了你的目標是一個Unix變體而不是Windows。

另一種選擇是UDP多播,從而使數據複製發生在硬件或驅動程序級。唯一的問題是UDP數據傳輸不能保證按順序進行,也不能保證提供。

我認爲共享物理套接字是一種詭計,應該避免,你最好是實現一個驅動程序來完成你想讓守護進程透明地執行的操作(例如,進程將套接字視爲普通套接字,除了內部套接字被映射到一個單一的套接字,在那裏存在邏輯來重新在虛擬套接字中廣播數據)。不幸的是,把它做正確的努力的水平將是非常重要的,如果完成的時間是一個共同關心的問題,那麼套接字並不是真的一個好的途徑(無論是在驅動程序級別完成,還是通過一些其他的黑客手段,例如共享套接字描述符跨進程)。

共享套接字還假定它是隻推式連接,例如沒有流量協商在應用程序級發生(例如數據請求或數據接收確認)。

完成的快速路徑可能是查看諸如BNC之類的項目並轉換代碼或劫持一般的想法,做你需要的。將流量複製到本地套接字不應產生巨大的延遲,儘管您將對所有數據複製行使NIC(以及相關的緩衝區),並且如果您接近硬件的限制(或者驅動程序和/或驅動程序較差TCP堆棧實現),那麼你可能會結束一個死亡的服務器。在我工作的地方,我們已經看到數據複製罐在驅動程序級別上是千兆以太網卡,所以這並不是前所未有的。

如果您希望保持平臺獨立性和性能,而不會因爲內核或硬件/驅動程序更改而導致5年內不可支持的任何內容,則共享內存是最好的選擇。

+0

+1我會將此延伸到網絡上的多播和本地訪問的共享內存的組合。 – 2009-09-30 18:34:36

3

我建議你看看ZeroMQ。這可能有助於解決您的問題。我不認爲20MB/s是非常高的......你應該能夠通過在ZeroMQ中使用TCP傳輸來達到這個吞吐量水平。還支持其他傳輸機制,包括使用OpenPGM的可靠多播。有計劃將UNIX管道添加爲傳輸機制。

消息傳送可能比共享內存更安全,更簡單。值得注意的是,如果您使用消息傳遞而不是共享內存,那麼您可以將應用程序組件分散到一組服務器中......這可能會給您帶來比共享內存更好的性能,具體取決於您的瓶頸所在。

+0

爲你的答案+1了(ZeroMQ很漂亮),但我給了Shaun一個選中標記,因爲它覆蓋了所有選項。 – 2010-12-01 01:10:47

相關問題