0

我有一個Java主應用程序,它將逐行讀取一個文件。每條線代表用戶數據。多線程文件處理和數據庫批量插入

name, email, mobile, ... 

每行,創建用戶對象正在處理,然後這個目的是在數據庫中使用JDBC持續。

PS:輸入文件有大約1,500萬個用戶數據,應用程序需要大約10-12小時才能處理。我需要將這個時間縮短到2-3個小時,因爲這項任務是一項遷移活動,我們得到的停機時間約爲4-5小時。

我知道我需要使用多線程/線程池,可能是Java的本機ExecuterService。但我被要求做一個批量更新。假設採用50或100個工作線程的線程池和500-1000個訂戶的批量更新。

我熟悉使用ExecuterService,但沒有得到一種方法,我也可以批量更新邏輯。

我的整個應用程序代碼如下所示:

while (null != (line = getNextLine())) { 
    Subscriber sub = getSub(line); // creates subscriber object by parsing the line 
    persistSub(sub); // JDBC - PreparedStatement insert query executed 
} 

需要知道的方法,我可以用多線程和使用批處理更新或任何現有的框架或Java的API可用於這樣的情況下更快地處理它。

+0

使用多線程讀取單個文件不會提高性能,事實上,它可能會惡化性能。大多數媒體不能同時執行多個讀取。 – VGR

+0

我想讀取文件可以由主線程本身完成。讀完一行後,它可以將其作爲任務委託給ThreadPool,並在下一行繼續執行。在我的情況下,工作線程會執行對象創建和persing。 –

回答

1

persistSub(sub)不應該立即訪問數據庫。相反,它應該將sub存儲在長度爲500-1000的數組中,並且只有當數組已滿或輸入文件終止時,纔將其包裝在Runnable中並提交給線程池。 Runnable然後通過jdbc訪問數據庫,如JDBC Batching with PrepareStatement Object中所述。

UPDATE

如果寫入到數據庫是緩慢的,輸入文件讀取是在數據庫中寫有可以創建等待數據的快速,多陣列和系統可運行內存不足。所以persistSub(sub)應該跟蹤分配數組的數量。最簡單的方法是使用Semaphore以允許的數組數量進行任意設置。在分配新陣列之前,persistSub(sub)使得Semaphore.aquire()。每個Runnable任務在其結束前都會產生Semaphore.release()