2011-04-04 81 views
2

我正在構建一個應用程序來通過REST API提供大量數據,我正在尋找一些有關如何構建它的輸入。我正在使用.NET(C#4.0),ASP.NET MVC和Sql Server 2008.通過HTTP API提供大量數據的體系結構

現在我在關係數據庫中有大約400k行,其中+ - 其中5%通過內部應用程序更新直接進入數據庫。我需要通過REST API來提供這些數據,以返回XML的自定義格式。但是,在輸出數據之前需要處理數據。好的是我可以在需要之前預先處理它。

我寫了一個小的POC,它獲取數據,處理它並將其緩存到本地XML文件中。由於處理此過程需要大約一個小時才能處理所有400k行。緩存完成後,我只是在每個請求中返回物理文件。

現在我需要能夠更新數據,因爲它在源代碼中得到更新並更新我的緩存,所以每次更新單行時都不需要生成所有內容。

我正在考慮使用AppFabric來保持內存緩存,並使用物理文件只是爲了確保在內存緩存熄滅的情況下,我不需要從頭開始。只要一行在源代碼中更新,我就會更新緩存並寫入物理文件以確保其最新。

因此,我的主要來源是AppFabric緩存,然後是物理緩存文件,並作爲最後的手段從數據庫重新生成文件,大約需要一個小時,並且無論誰調用該文件都無法使用該文件。

我對此並不滿意,但這是我得到的。有什麼建議麼?

非常感謝!

+0

很清楚的解釋,但它留下了一個問題在我心中:是否從〜400k行生成的輸出文件的一些組合關閉所有這些無效,無論是一行更改,還是這是一個可能發生的行按行? 如果這是以後的情況,可能的答案就是自身。 – coffeetocode 2011-04-08 22:55:16

+0

不,該過程產生的輸出文件是輸入行(產品,這與電子商務有關)的列表,其中一些數據被修改(價格)。所以如果一行更新,我只需要更新這一行。並非全部。 – tucaz 2011-04-10 18:32:40

回答

1

感謝您的澄清以上。這裏有一個基於此的選項。

添加一個表到您的數據庫。稱之爲Products_Processed(或價格,無論)。這個新表格對於產品中的每一行都有一行(例如,與源數據一一對應)。這個新表中的每一行都包含相應源行的處理數據。

每次通過外部應用程序更新Products中的一行時,您只需計算該行並更新Products_Processed中的相應行。

這裏有一些方法可以得到一段代碼運行的只是最近更新的條目:

  • 有程序中的一個線程輪詢DB 1次(或分鐘)運行在您的任何處理邏輯行在一秒鐘(或分鐘)之前的最後一秒更新。這意味着您在產品行更新的時候保留時間戳(無論如何,這可能是個好主意)。
  • 如果您不想要時間戳,請在產品表上的數據庫中添加觸發器,以將更新的行添加到Products_ToProcess表。民意調查和出現有條目運行處理邏輯,並從Products_ToProcess
  • 刪除
  • 在實際調用你的C#代碼的產品表使用觸發器:Create and Run CLR SQLServer Trigger

這種方法可以使你得出的數據在邏輯上接近真實的來源(在帶有源數據的數據庫中)並減少了複製/格式化/處理數據的次數。另外,重要的是,使用經過驗證的真實數據庫提供的機制來檢測/觸發已更改的數據,將使您無法編寫大量自己的同步代碼。

現在,返回結果本質上是流出select * from Products_Processed。如果您想僅爲特定產品返回已處理數據,則您擁有SQL和模式的全部功能;同樣用於排序。整個設置應該足夠快,以至於不需要將文件緩存在磁盤上。實際上,如果你有足夠的空間,MSSQL緩存應該可以將大部分/全部已處理的數據行保留在RAM中,所以你很少需要做一個冷選擇(如果你沒有足夠的RAM,那麼考慮一下額外的演出與你的時間相比是值得的;把硬件扔在一個問題上也不會作弊;)。 (但是,如果您確實想將其寫入磁盤,則可以將偏移量存儲到每個行記錄的物理文件中,並在更新相應的處理數據行時快速更新文件中的單個數據。)

+0

這是我使用的方法,唯一的區別是我將生成的數據保存在XDocument(作爲@grzeg建議的+1)對象的內存中並更新它直接在產品發生變化時直接進行,我不希望將所有內容都存儲在數據庫中,以免在每次請求時爲其生成XML。 – tucaz 2011-04-14 14:27:44

1

你可以把所有的處理在數據庫中?如果屬實,我認爲你應該保留所有的處理。 400k行是少量行,SQLserver可以處理這種情況(一個小時太長了!)。嘗試使用集成服務登臺並使用「設置處理」執行所有插入/更新/選擇,而不是使用光標/行處理。 我的2美分。

+0

嘿,我的男人!好久不見,安?不幸的是我不能:(它是一個處理.NET組件,謝謝,雖然! – tucaz 2011-04-04 17:24:27

+0

很長一段時間,rsrs。讓我再問你一個問題:你可以重寫這個.net組件來僅使用數據庫嗎?我的意思是,一些使用'set processing'而不是'row processing'進行處理的過程在數據庫中加載一個包含所有應更新值的表,並使用一些連接/臨時表,您可以根據此temp更新目標表表格或類似的東西在這種情況下設置處理是最好的方法 – rboaretto 2011-04-11 21:17:14

1

您是否想過使用Linq To Xml?

你會知道最好的它是否適合你的其他方面的限制,但這裏是我的2便士:

優點:

  • XML是你的目標格式,所以沒有與轉換問題
  • 是可讀
  • 非常容易使用(CRUD)
  • 加載/保存到文件將解決您的'重新加載服務重新啓動時處理的數據'問題
  • 具有合理有效的實現,這意味着它可以處理您的400k行(取決於您的記錄大小)。
  • 使用LINQ意味着你可以很容易地parallelise它(與PLINQ),從而有效地利用你的核心

缺點:

  • 內存使用可能是一個問題,但是這取決於你的記錄大小

的下方(爲500K元素)在2secs生成和更新所有的元件價格0.5秒下一個良好的開發框:

var root = new XElement("root"); 

for (int i = 0; i < 500000; i++) 
{ 
    root.Add(new XElement("product", new XAttribute("name", "product_" + i), 
          new XElement("price", 13.0 + 1.0/(i + 1)))); 
} 

foreach (XElement updateElem in root 
    .Elements("product") 
    .Where(x => x.Attribute("name").Value.StartsWith("product"))) 
{ 
    updateElem.Element("price").Value = "16.0"; 
} 

root.Save(@"c:\temp\huge.xml");