2013-05-28 24 views
7

我的問題涉及JVM應用程序可以利用主機的NUMA佈局的程度。對JVM的NUMA認識

我有一個Akka應用程序,其中參與者通過將傳入數據與已加載到不可變(Scala)對象的「通用」數據進行組合來併發處理請求。該應用可以在雲中很好地擴展,使用許多雙核虛擬機,但在單個64核心機器上執行效果不佳。我認爲這是因爲公共數據對象駐留在一個NUMA單元中,並且從其他單元併發訪問的許多線程對於互連而言太多。

如果我運行64個單獨的JVM應用程序,每個應用程序包含1個actor,那麼性能會很好。一個更溫和的方法可能是運行儘可能多的JVM應用程序,因爲有NUMA單元(我的情況是8個),給主機操作系統一個保持線程和內存在一起的機會?

但是,在單個JVM中實現相同效果還有更明智的方法嗎?例如。如果我用一個case類的幾個實例替換了我的公共數據對象,那麼JVM是否有能力將它們放在最佳的NUMA單元上?

更新:

我使用Oracle JDK 1.7.0_05和阿卡2.1.4

現在我已經試圖與UseNUMA和UseParallelGC JVM選項。在使用一個或幾個JVM時,對性能下降似乎沒有任何顯着影響。我也試過用PinnedDispatcher和thre-pool-executor沒有任何作用。我不確定配置是否有效,因爲在啓動日誌中似乎沒有什麼不同。

當我每個工人使用一個JVM(〜50)時,最大的改進仍然存在。然而,這個問題似乎是在FailureDector註冊Akka集羣JVM之間的「第一次心跳」成功交換之前存在長時間延遲(長達幾分鐘)。我懷疑還有其他一些問題,我還沒有發現。自從我達到默認的最大進程數(1024)以來,我不得不增加ulimit -u。

只是爲了澄清,我並沒有試圖實現大量的消息,只是試圖讓很多獨立的角色同時訪問一個不可變的對象。

+2

您是否在使用-XX:+ UseNUMA jvm選項? – cmbaxter

+0

另外,您使用的是什麼GC設置?什麼執行器配置? –

+0

您可能需要告訴akka使用更好的線程模式,請參閱此處獲取某些郵箱配置選項:http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html – Noah

回答

2

我想如果你確定問題不在消息處理算法中,那麼你應該考慮到不僅NUMA選項,而且整個環境。配置,從JVM版本開始(最新版本更好,Oracle JDK也主要比OpenJDK更好),然後選擇JVM選項(包括GC,內存,併發選項等),然後選擇Scala和Akka版本(最新版本的候選版本和里程碑版本會更好)還有Akka配置。

here你可以借用所有重要的事情得到50M messages per second of total throughput for Akka actors on contemporary laptops

從來沒有機會在64核心服務器上運行這些基準 - 所以任何反饋都將不勝感激。

根據我的發現,當池中的線程數量增加時,ForkJoinPool的當前實現會增加消息發送延遲。對於參與者之間的響應請求呼叫率很高的情況來說,這是非常明顯的。 G。在我的筆記本電腦中,當將池大小從4增加到64時,對於這種情況,Akka演員的消息發送延遲增長到多數執行程序服務(Scala的ForkJoinPool,JDK的ForkJoinPool,ThreadPoolExecutor)的2-3倍。

您可以通過運行mvnAll.sh並將benchmark.parallelism系統變量設置爲不同的值來檢查是否有任何差異。

+0

下面是一篇博客文章,介紹我們的48核心測試服務器上使用FJP的akka​​可伸縮性配置文件:http://letitcrash.com/post/20397701710/50-million-messages-per-second-on-a-single-machine –