2013-05-04 26 views
-4

我有一個賬單守護進程,必須以非常快速的方式處理成千上萬的數據。我實施了ExecutorSerivce進行並行處理。它確實增加了速度,但不是很多。大約需要2.5-3小時處理100,000條記錄。如何在半小時內處理這些數據的速度更快?如何更快地創建Java應用程序?

我已經寫了執行設置如下:

-Xms2048M -Xmx2048M -XX:MaxPermSize=256m 

我試圖實現與1對生產者和消費者4生產者消費者模式。每個列表可以包含10,000條記錄。

ArrayBlockingQueue<BillableList> list =new ArrayBlockingQueue<BillableList>(10); 

ExecutorService threadPool = Executors.newFixedThreadPool(5); 
threadPool.execute(new Consumer("pool1", list)); 
threadPool.execute(new Consumer("pool2", list)); 
threadPool.execute(new Consumer("pool3", list)); 
threadPool.execute(new Consumer("pool4", list)); 
Future producerStatus = threadPool.submit(new Producer("Producer", list)); 
producerStatus.get(); 
threadPool.shutdown(); 

在更新記錄到數據庫時,我也收到很多「超出數據庫鎖定等待超時」異常。是否由於不同的消費者在同一時間嘗試同一用戶?我如何讓不同的消費者從ArrayBlockingQueue的列表中獲取不同的數據?

+1

第1步:找出爲什麼它很慢。記錄高級操作的執行時間,使用分析器,執行GC日誌記錄以查看是否正在損壞內存...... – millimoose 2013-05-04 18:14:32

+0

爲數據庫獲取非常快速的SSD陣列。 – 2013-05-04 18:14:48

+1

也〜purrrrformance ~~~~ – 2013-05-04 18:14:52

回答

10

對此的唯一可能的答案是「使用探查器並找出緩慢的原因」。當你不知道問題出在哪裏時,你無法做任何事情。你要做什麼,選擇一個隨機函數並對其進行微優化? Profiler數據或者什麼都不會發生。

+0

唯一可能的答案?真? – Gray 2013-05-04 18:32:01

+4

@格雷:你的答案主要是猜測。投機是你所能做的事實顯示了我所說的正確性。 – Puppy 2013-05-04 18:34:38

+0

推測它是「但運行一個分析器」是一個簡單的答案 - 特別是如果OP討論數據庫爭用。 – Gray 2013-05-04 18:37:14

1

如何讓它更快地在半小時內處理這些數據?

如果添加線程沒有幫助,那麼你可能會受到限制,而不是我的CPU,但受到其他因素的限制。最有可能的磁盤或網絡IO。如上所述,分析你的代碼應該顯示你的罪魁禍首。

在更新記錄到數據庫時,我也會遇到很多「超出數據庫鎖定等待超時」異常。

還有你的大腦線索。無論工作中有多少線程在工作,如果他們都在等待數據庫,那麼添加線程並沒有讓它更快。

這裏有一些想法:

  • 增加數據庫箱的物理速度。 SSD可以爲IO密集型操作提供出色的改進。由於磁盤高速緩存的存在,增加內存也可以獲得巨大的勝利。
  • 考慮分割數據並寫入多個數據庫實例。根據你的模式,這可能是不可能的。
  • 考慮關閉自動提交併在大約100次左右的操作後手動提交。
  • 小心索引。如果您正在進行某種批量加載,通常如果關閉索引,插入操作會更快。在最後添加索引需要一段時間,但仍然是一個勝利。
  • 此外,如果您正在進行查詢,請確保您在需要的地方有良好的索引。檢查數據庫日誌以查看哪些查詢花費的時間過長,以查看是否缺少關鍵位置中的某些索引。
+0

這確實是一個很好的答案 – 2013-05-04 18:38:25

+0

@Gray ..系統在Amazon EC2上,而mysql數據庫在RDS上。查詢需要10秒鐘來檢索10,000條記錄!我會嘗試探查器,看看裏面發生了什麼!謝謝.. !! – 2013-05-04 18:54:58

+1

探查器是一個好主意,但我不確定這會有多大幫助。你會發現它花費在JDBC上的時間意味着等待數據庫連接。祝你好運@MadanMadan。 – Gray 2013-05-04 18:59:58