2010-06-28 50 views
3

我有一堆進入系統(存儲到數據庫中)的文件(大約每秒10個)。每個文件都包含1到500個設備之間的條目。給定的設備將出現在多個文件中(但不是每個文件)。這些數據最終需要存儲在另一個數據庫中,並存儲在每臺設備上。有兩種不同的文件格式。在使用阻塞進程時管理線程和內存使用情況

有一個API負責管理最終的數據庫部分,該部分爲單個設備提供多個條目(在幕後,這還會執行一些查找以查找數據庫中的ID,因此一次處理多個條目一個設備意味着執行一次查詢,而不是每次輸入一次)。

要做到這一點,我有幾個部分的程序:

  • 解析文件,提取數據到通用數據集對象。
    • 這是螺紋的過程,每個文件一個線程,將數據添加到一個線程安全的集合
    • 當每個文件被加載,它的數據庫條目被標記爲「正在處理」是
  • 將對象保存到數據庫中
    • 另一個線程化進程,它提取給定設備的所有對象,然後通知數據API保存它們。
    • 一旦保存從一個單一的文件中的所有設備都成功(或者任何失敗)的原始文件的數據庫條目被標記爲成功/失敗

我的問題是:什麼是管理何時解析文件的最佳方式,使用多少個線程,多少RAM等等?

  • 數據API將花費最長時間 - 大多數情況下,線程將等待API返回。
  • 該系統的整體效率是由具有每個設備
  • 應用程序應該不會用完的RAM,或者具有解析這麼多的文件,但等待被保存,它會導致操作系統換分組的更多的數據的改善。
  • 它是未知的DB API多少可以同時呼叫處理,或者它運行的速度有多快 - 這一過程需要適應的是

所以我怎麼知道什麼時候來解析文件,以確保這是怎麼回事儘可能快的速度,而不會因使用太多RAM而導致性能下降?

+0

一些問題......什麼是.NET版本?它是最長的數據* Base * API嗎? – 2010-06-28 19:02:18

+0

目前爲3.5,但在.NET 4中沒有問題。我假定最終數據庫將花費最長時間,因爲它需要爲單個設備插入許多記錄(添加歷史記錄,爲不同的數據添加不同的表)。這需要花費一定的時間,並且在調用API時,調用者(此應用程序)將被I/O綁定,等待它返回。 – gregmac 2010-06-28 19:35:00

回答

1

看起來好像你有一個非常多的I/O限制的系統(他在輸入端和DB上的文件在輸出端)。在那裏我沒有看到任何CPU密集型部件。

明顯的優化已經在質疑:一羣一大堆的傳入的文件和組每個設備中的數據。成本是內存消耗和Db更新中的延遲。你需要這個參數。

作爲第一個想法,我想在所界定的隊列連接3個塊進行設置。這些隊列將讓任何「不堪重負」的組件扼殺其供應商。

塊1:1或2個線程(取決於I/O系統)讀取和解析文件,

塊2:1線程組織和分組數據。決定何時設備的數據應該去到DB

塊3:1+線程推送數據到數據庫。

塊給這個系統有一定的靈活性。有限的隊列讓你控制資源消耗。請注意,塊2應該參數化以調整塊大小。

+0

我喜歡這個方向,因爲它至少可以保持線程之間的交互。根據實施方式的不同,您可以輕鬆運行測試以查看向每個部分添加線程是如何提高或降低性能的。 – ChaosPandion 2010-06-28 19:25:00

0

這就是我該怎麼做的。隨着每個新文件的進入,將其添加到隊列中。讓調度員拿起一個文件並開始一個新的線程。

調度程序可以不斷監視可用的系統內存和CPU使用情況(例如使用性能計數器API)。

只要有足夠的可用內存或足夠低的CPU負載,啓動一個新的線程。您必須測試一下才能找到應用程序的最佳閾值。

另外,如果您是在32位運行,那麼一個過程只能你會得到一個內存溢出異常使用前圍繞〜RAM 800MB的,所以你可能需要考慮這一點爲好。

你開始新的工作第三個因素是DB API。只要它可以吞下你添加的工作,繼續添加更多的線程。

程序的流程是這樣的:

  1. 消費和解析文件
  2. 當到達您的內存限制(和/或CPU限制),批他們到DB API
  3. 當你批量的數據庫API,釋放內存,並且可以處理新文件 - goto 1
相關問題