2016-02-25 40 views
0

我正在尋找設計最佳實踐來實現以下應用程序。 平臺:RedHat Linux,Tomcat 8,Java 8.最終,這將被移至JBOSS應用服務器。Servlet長數據緩存過程

我的servlet在啓動時會從10個大文件中讀取數據,並構建一個用於回答用戶查詢的數據結構。它大約需要。 2分鐘,在數據結構準備好之前總共20分鐘加載每個文件。

目前我有一個ServletContextListener中的代碼,並使用setAttribute()方法將數據結構放置到Servlet中。

問題:當我上傳我的war文件時,servlet在加載文件集20分鐘之前不可用。我不介意這一點,但我想知道是否有更好的方法來實現這一點。

+0

這些文件有多大?你可以用'BufferedReader.readLine()'來讀取數百萬行。爲什麼閱讀它們需要很長時間? – EJP

+0

我們使用BufferedReader - 我們的文件每個都有超過30M行。 – RVT

+0

@EJP - 我們發現讀取文件似乎不是延遲的原因。它很快讀取文件 - 它的內存分配(-Xmx80G-Xms80G)似乎是問題所在。我們必須請求Java分配一個大內存來處理我們的數據結構。 – RVT

回答

0

我同意閱讀時間不是你的問題:閱讀10 * 30M = 300M應該可以在< 1分鐘內完成。您的問題是構建數據結構所花費的時間。

我建議你...

  1. 簡化您的數據結構存儲
  2. 優化您的文件格式快速加載
  3. 避免垃圾收集,同時讀取文件
  4. 加載文件並行線程

在(1)中,讓您的數據結構保持較少的較大對象。例如,而不是1000個具有(int)成員的對象,請使用byte [4000]。然後,對於每個客戶端請求,您可以從byte [4000]數組中選取數據。這將節省批次的時間,因爲分配大量小的長壽命對象很慢。我預計這將是你的主要勝利。在(2)中,使文件將數據存儲在對應於(1)中的byte [4000]數組等的塊中。然後,您可以通過一次讀取(arByte)調用加載數據塊。 (如果你想要更快的速度,你可以將你的文件映射到內存映射中,但由於代碼中存在額外的複雜性,我不建議這樣做。)(3),避免在讀取文件時製作大量臨時對象。每個臨時對象都必須被垃圾收集。垃圾收集可能需要很長時間才能處理像服務器這樣的高內存使用程序。對您的服務器進行配置以查看GC-s是否正在放慢速度。如果他們(例如)重用StringBuilder對象來處理每條記錄,而不是爲每條記錄分配一個新的String對象。

我強烈推薦(1)。你的服務器加載速度會更快,反過來它的運行速度也會更快,因爲它會節省很多內存。