2013-01-18 56 views
0

我正在尋找分析自定義日誌文件的方法。解析和分析少量GB數據

我現在已經實現了使用LINQ和C#.NET。它僅適用於最大500MB的日誌文件。

日誌文件中的每一行是將對象,看起來像

public class Metrics 
{ 
    public DateTime Date { get; set; } 
    public string Metrics1 { get; set; } 
    public string Metrics2 { get; set; } 
       : 
       : 
    public string Metrics9 { get; set; } 
} 

List<Metrics> MetricsList = new List<Metrics>(); 

填充MetricsList。 在MetricsList上運行各種LINQ查詢以提供有用的分析。 觀察到一個度量對象需要300個字節。我在500MB日誌文件中有大約400萬行,這使得MetricsList的大小單獨佔用1GB以上的程序內存。

我的要求是解析和分析大小高達2 GB的文件,這看起來會消耗4 GB的內存。

使用Windows,Microsoft Technologies和任何開源庫的更好的方法或替代品。

+3

您可能需要流入數據。一次只讀取一個度量標準(或一組度量標準),將它們從內存中置入,然後轉到下一個。 –

+0

你最近怎麼看書?您可以使用'Streamreader'或'File.ReadLines'來讀取一行,而不是所有的(f.e.'File.ReadAllLines')。你還應該看看['MemoryMappedFile'-class](http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx)。 _內存映射文件使程序員能夠處理極大的文件,因爲內存可以同時管理,並且允許完全隨機地訪問文件而無需查找。內存映射文件也可以在多個進程間共享_「 –

+0

」我有使用Windows和Microsoft技術的限制「,您爲什麼將此視爲限制?你有什麼技術? –

回答

1

我已經使用SQlite完成了類似的任務。安裝System.Data.SQLite NuGet(可選:我已經使用Dapper NuGet作爲一個非常高效的微ORM),然後你有一個很好的工具來執行查詢和生成你的報告。你可能不喜歡的唯一的事情是你必須編寫SQL而不是LINQ(雖然也有LINQ for SQLite,但我沒有使用它)。

這樣,內存消耗也會消失。

1

通常你不想在內存中存儲那樣的文件(除非你有足夠的課程),但是在解析文件時處理數據。我只是安裝更多的內存,並將解決方案設置爲64位大概...

但是,如果這不是一個選項,您可以隨時優化內存使用情況。 .NET將字符串存儲爲char [],其中char基本上是一個2字節的短字符串。通過使用Encoding.UTF8.GetBytes,您不需要將其存儲爲char [],而是將其存儲爲byte [],您可以輕鬆節省大量內存。

此外,每個字符串或字節[]在64位環境中消耗24個字節(對於對象本身爲16,對於指針爲8)。如果你有很多小字符串,這可以加起來。除了將它們存儲爲字符串外,您還可以存儲單個字節[]並在getter中進行解析。

因此,總結我的建議是:購買更多的內存或在您閱讀/需要時處理數據。

[更新+ 1]

只注意到您使用列表。最先進的流程最簡單的方法是將文件作爲IEnumerable讀取,然後使用Linq。不要先把它列入清單。例如: -

​​

[更新+ 2]

哦,我還有一個絕招給你。讀取文件可能會帶來性能上的痛苦,因爲文件IO相對較差。因此,不是使用上面的IEnumeration技巧,您還可以使用壓縮流將所有數據存儲在內存中 - 然後在處理期間使用該數據而不是文件。

對於那些想知道我是否認真對待這個怪異解決方案的人來說:當你構建搜索技術和數據庫時,這是一種常用的技術,只是因爲擁有更多(快速)內存意味着擁有更少)磁盤IO。此外,日誌文件可能會非常好地壓縮。

因此讀取文件& & flatestream在內存頂部。然後以上面討論的方式閱讀Linq(同樣,在內存流頂部的flatestream)。