2014-05-14 49 views
0

這是我在這裏的第一篇文章,非常抱歉,如果這不是很好的結構。饋線應用的多線程體系結構

我們一直負責設計一個工具,將:

  • 閱讀(的帳戶ID)的文件,CSV格式
  • 從網站下載的帳戶數據文件爲每個帳戶(按ID) (REST API)
  • 傳遞該文件以將產生的報告(財務預測等)的轉換器[〜20ms的]
  • 如果預測閾值範圍之內,運行一個分析器來分析數據[400毫秒]
  • Generat E對於上述[80毫秒]分析報告
  • 上傳生成的網頁(REST API)中的所有文件

現在,所有這些各個點都比較容易做到的。我有興趣找出如何最好地設計一些東西來處理這個問題,並在我們的硬件上高效地執行它。

我們必須處理大約2百萬個賬戶。方括號給出了每個過程平均需要多長時間的想法。我想使用機器上可用的最大資源 - 24核心Xeon處理器。這不是一個內存密集型的過程。

將使用TPL和創建每個這些作爲一個好主意?每個都必須按順序發生,但許多可以一次完成。不幸的是,解析器不支持多線程,並且我們沒有源代碼(對我們來說,它本質上是一個黑盒子)。

我的想法是這樣的 - 假設我們使用TPL:

  • 裝載的帳戶數據(本質上是一個CSV導入或SQL SELECT)
  • 每個帳戶(編號):
    • 下載每個帳戶的數據文件
    • 繼續使用數據文件,發送到轉換器
    • 繼續使用檢查閾值,發送到解析器
    • ContinueWith生成報告
    • ContinueWith上傳輸出

這聽起來是可行的還是我沒有理解正確嗎?以不同的方式分解步驟會更好嗎?

我有點不確定如何處理解析器拋出異常(這是非常挑剔的)或當我們獲取失敗上傳問題。

所有這些將在計劃作業中作爲控制檯應用程序在非工作時間運行。

+0

我應該指出,我們正在使用.NET 4.5,並且正在閱讀TPL數據流,它似乎是一種前進的方式。在這個階段不幸的是Messagebus不是一個選項。 – Keerthi

+0

MessageBus是一種方式,因爲它是一個概念 - 猜猜看,DataFLows也在內部使用消息總線。 DataFlows可能是一個很好的方法來做到這一點。作爲tomtom已經說過的 – TomTom

+0

。它非常重要,不要像NMessageBus這樣的庫與conecpt混合在一起:)有真正的輕量級消息總線 –

回答

1

我會考慮使用一些一種消息總線。因此,您可以單獨執行這些步驟,如果某個步驟不起作用(例如,因爲REST服務在一段時間內無法訪問),則可以稍後存儲該消息以便處理它們。

根據您用作messagebus的情況,您可以引入線程。

在我看來,如果您有像服務總線這樣的更高層次的抽象,您可以更好地設計工作流程,處理異常狀態等等。

另外beaucase的部分可以獨立運行,他們不會互相阻塞。

一個簡單的方法可能是將servicestack messaging與Redis ServiceBus結合使用。

從那裏引用的一些優點:

  • 基於消息的設計允許更容易並行化和計算

  • DLQ消息可以內省的內省,固定和服務器的更新和後後重放重新加入正常消息工作流程

0

我覺得簡單的方法來在你的情況下開始與多線程,將會把整個操作的每個帳戶ID在線程(或更好,在線程池)。在下面提出的方式中,我認爲你不需要控制線程間的操作。

像這樣把數據上線程池隊列

var accountIds = new List<int>(); 
foreach (var accountId in accountIds) 
{ 
    ThreadPool.QueueUserWorkItem(ProcessAccount, accountId); 
} 

這就是你將處理每個帳戶的功能:

public static void ProcessAccount(object accountId) 
{ 
    // Download the data file for this account 
    // ContinueWith using the data file, send to the converter 
    // ContinueWith check threshold, send to parser 
    // ContinueWith Generate Report 
    // ContinueWith Upload outputs 
}