2012-02-29 108 views
1

我有一個Java批處理選擇一個大resulset(我使用Spring callbackhandler處理元素)。 回調處理程序將任務放入固定線程池中以處理該行。 我的池大小固定在16個線程上。 Resulset包含大約100k個元素。 所有數據庫訪問代碼通過JdbcTemplate或Hibernate/Spring進行處理,不存在手動連接管理。 我試過用Atomikos和Commons DBCP作爲連接池。java連接池,多線程批處理中有多少個最大連接數?

現在,我認爲在我的連接池中有17個最大連接數就足以讓這個批處理完成。一個用於select,另一個用於連接池中的線程,用於更新某些行。然而,這似乎太天真了,因爲我必須指定最大池大小幅度更大(沒有嘗試過一個確切的值),首先我嘗試了50在我的本地Windows機器上工作,但似乎不是在我們的Unix測試環境中足夠了。在那裏我必須指定128才能使它工作(再次,我甚至沒有嘗試過50到128之間的值,我直接去到了128)。

這是正常的嗎?在我缺少的連接池中是否有一些基本機制?我發現很難調試,因爲我不知道如何看到打開的連接會發生什麼。我嘗試了各種log4j設置,但沒有得到滿意的結果。

編輯,附加信息:當連接池大小似乎太低時,該批似乎掛起。如果我在進程上執行jstat,我可以看到所有線程都在等待新的連接。起初,我沒有在dbcp連接池上指定maxWait屬性,這會導致線程在新連接上無限期地等待,並且我注意到批處理保持懸掛狀態。所以沒有連接被釋放。然而,這只是在處理了+ 70k行之後才發生的,這就排除了我最初對連接泄漏的預感。

edit2:我忘了提及我已經在我的任務中重寫了更新部分。我在ConcurrentLinkedQueue中更新了我的更新,我清空了1000個元素。所以我實際上只做了大約100次更新。

edit3:我使用的是Oracle,我使用的是併發實用程序。所以我有一個配置了16位固定池的執行器。我將這些任務提交給這個執行器。我沒有在我的任務中手動使用連接,我使用線程安全的jdbctemplate並詢問連接池中的連接。我想Spring/DBCP處理連接/線程問題。

回答

0

我切換到c3p0而不是DBCP。在c3p0中,您可以指定一些輔助線程。我注意到如果我把這個數字與我使用的線程數量一樣高,連接數量保持非常低(使用c3p0的方便的jmx bean來檢查活動連接)。另外,我對每個自己的實體管理器都有一些依賴關係。顯然每個實體管理器都需要一個新的連接,所以我有大約4個實體管理器/線程,這將解釋大量的連接。我認爲我的任務都非常短暫,以至於DBCP無法關閉/釋放連接,因爲c3p0的工作更異步,您可以指定helperthread的數量,它能夠及時釋放我的連接。

編輯:但批處理在部署到測試環境時保持掛起,所有線程在釋放連接時都被阻塞,鎖在池中。就在同與DBPC :(

編輯:當我切換到BoneCP,我得到了巨大的業績增長作爲獎金太

1

如果您使用的是Linux,您可以嘗試MySql管理員以圖形方式監視連接狀態,前提是您使用的是MySQL。

無論如何,即使100個連接對於大型企業應用程序來說也並不少見,每分鐘處理幾千個請求。

但是,如果請求低或每個請求都不需要唯一的事務,那麼我會建議您在線程內調整您的操作。

也就是說,你如何將100k元素分配給16個線程? 如果您每次從共享位置(或緩衝區)讀取一行時嘗試獲取連接,則預計需要時間。

看看這是否有幫助。

  1. 的getConnection
  2. 每個元素直到緩衝區大小變爲零點
  3. 對其進行處理。
  4. ,如果你需要更新,
  5. 打開一個交易
  6. 更新
  7. 提交/回滾事務
  8. 轉到步驟2
  9. 釋放連接

可以同步緩衝區使用java.util.concurrent collections

不要使用一個每個元素可運行/可調用。這會降低性能。 你怎麼創建線程?使用Executors來運行你的runnable/callable。還要記住,不希望數據庫連接在線程間共享。因此,一次只能在1個線程中使用1個連接。

例如,創建一個Executor並提交16個runnalbles,每個都有自己的連接。

+0

我編輯我的問題更多的信息,我的所有問題dissapeared表現其實很不錯即使我創建了一個Runnable/row – 2012-02-29 18:21:13

+0

嘗試使用Netbeans分析器,它爲您提供線程的實時統計信息,例如等待CPU,等待鎖定,等待IO等。如果結果顯示線程正在等待數據庫連接,那麼增加游泳池的大小是好的,否則優化瓶頸。http://profiler.netbeans.org/ – 2012-02-29 18:29:26

+0

我使用jvisualvm。不幸的是,我無法連接一個探查器到發生問題的unix env ,這是一個鎖定的環境,但我並不是真的有興趣調整我的池大小,現在它工作正常,128和我的源數據大小是不變的,所以應該是好的。然而,我的問題是,應該不夠17?如果不是,爲什麼? – 2012-02-29 19:24:45