2010-12-08 138 views
2

我想在Java中開發一段代碼,它將能夠處理JDBC驅動程序從SQL數據庫中獲取的大量數據,然後將其保留回數據庫。一個閱讀器線程,一個寫入器線程,n個工作線程

我想創建一個包含一個讀取器線程,一個寫入器線程和可定製數量的工作線程處理數據的管理器。閱讀器線程會將數據讀取到DTO,並將它們傳遞給Queue標籤「準備處理」。工作者線程將處理DTO並將處理後的對象放置到另一個標記爲「準備好持久化」的隊列中。編寫器線程會將數據保存到數據庫。這種方法是最佳的嗎?或者,也許我應該讓更多的讀者獲取數據? Java中是否有任何準備好的庫用於執行這種我不知道的事情?

回答

3

您提出的方法是否最優取決於處理數據的成本與從數據庫獲取數據的成本有多大以及如何將結果寫回數據庫中。如果處理相對昂貴,這可能會工作得很好;如果不是這樣,那麼可能會帶來相當多的複雜性,但效果不大(您仍然會得到管道並行性,這對於整體吞吐量可能並不重要)。

要確保的唯一方法是基準三個階段分開,然後依賴於最優設計。

如果多線程方法行之有效,那麼帶有兩個隊列的設計聽起來很合理。您可能需要考慮的另一件事是對每個隊列的大小進行限制。

1

使用顯式隊列的替代方法是使用ExecutorService並向其中添加任務。這樣你可以讓Java管理器成爲線程池。

1

您正在描述寫類似於Spring Batch提供的功能的東西。如果我是你,我會檢查一下。我有很大的運氣來做類似於你所描述的操作。並行和多線程處理,以及幾個不同的數據庫讀者/作者和其他一些東西提供。

2

我聽到了過去的回聲,我想提供一種不同的方法,以防萬一您要重複我的錯誤。它可能會或可能不適用於您的情況。

您寫道,您需要從數據庫中提取大量數據,然後保留回數據庫。

是否可以將需要使用的外部數據臨時插入到數據庫中,並執行數據庫內的所有處理?這將具有以下優點:

  1. 它消除了需要提取大量數據
  2. 它消除了需要持續大量的數據
  3. 它使基於集合的處理(其性能優於程序)的
  4. 如果您的數據庫支持它,您可以使用並行執行
  5. 它爲您提供了一個框架(表和SQL)來報告您在過程中遇到的任何錯誤。

舉個例子。很久以前,我實施了一個(java)程序,其目的是將文件中的購買,付款和相關客戶數據加載到中央數據庫中。那時(我對此深感遺憾),我設計了負載以逐個處理事務,併爲每個數據執行多個數據庫查找(sql),最後還有一些插入到適當的表中。當然,這個數量一旦增加就不會縮放。

然後我又犯了一個錯誤。我認爲這是數據庫問題(因爲我有聽說 SELECT慢),所以我決定從數據庫中提取所有數據,並在Java中進行所有處理。然後最後將所有數據保存到數據庫。我用回調機制實現了各種各樣的層,以輕鬆擴展加載過程,但我無法讓它表現良好。

從後視鏡看,我應該做的是在表格中臨時插入(可笑的少量)100,000行,並從那裏處理它們。如果我發揮我掌握的所有技術的優勢,花費將近半天的時間處理最多花費幾分鐘的時間。

1

使用Spring批處理!那正是你需要的