簡體   English   中英

通過網絡讀取和解析大型文本文件的最佳方法是什么?

[英]What's the best way to read and parse a large text file over the network?

我有一個問題,需要我從遠程機器解析幾個日志文件。 有一些復雜情況:1)文件可能正在使用2)文件可能相當大(100mb +)3)每個條目可能是多行的

要解決使用中的問題,我需要先復制它。 我目前正在將它直接從遠程計算機復制到本地計算機,並在那里進行解析。 這導致問題2.由於文件非常大,在本地復制它可能需要相當長的時間。

為了增強解析時間,我想使解析器具有多線程,但這使得處理多行條目變得有點棘手。

兩個主要問題是:1)我如何加速文件傳輸(壓縮?,本地傳輸甚至是必要的?,我可以用其他方式讀取使用文件嗎?)2)我如何處理多行條目什么時候分開線程之間的線?

更新:我沒有對服務器進行明顯解析的原因是我希望盡可能減少對cpu的影響。 我不想影響系統im測試的性能。

如果您正在讀取順序文件,則需要通過網絡逐行讀取。 您需要一種能夠流式傳輸的傳輸方法。 您需要檢查您的IO流技術以解決這個問題。

像這樣的大型IO操作不會因多線程而受益,因為您可以盡可能快地處理項目,只需通過網絡讀取它們即可。

另一個很好的選擇是將日志解析器放在服務器上,然后下載結果。

考慮到您已經復制文件的最簡單方法是在復制之前壓縮它,並在復制完成后解壓縮。 壓縮文本文件會獲得巨大的收益,因為zip算法通常可以很好地處理它們。 您現有的解析邏輯也可以保持原樣,而不必將其連接到遠程網絡文本閱讀器。

這種方法的缺點是你無法非常有效地獲得逐行更新,這對於日志解析器來說是一件好事。

我想這取決於它是多么“遙遠”。 100Mb局域網上的100MB將大約8秒......將其增加到千兆位,你可以在大約1秒內完成它。 這些卡的價格為50美元* 2,交換機價格為100美元,這是您可以做的非常便宜的升級。

但是,假設它比那更遠,你應該能夠以只讀模式打開它(當你復制時你正在讀它)。 SMB / CIFS支持文件塊讀取,所以你應該在那時流式傳輸文件(當然,你實際上沒有說你是如何訪問文件的 - 我只是假設SMB)。

多線程無濟於事,因為無論如何你都會受到磁盤或網絡限制。

使用壓縮進行傳輸。

如果你的解析真的讓你失望,並且你有多個處理器,你可以打破解析工作,你只需要以聰明的方式做 - 有一個確定的算法,工人負責處理不完整的記錄。 例如,假設您可以確定一條線是記錄中間的一部分,您可以將文件分成N / M段,每段都負責M行; 當其中一個作業確定其記錄未完成時,它必須繼續讀取,直到它到達記錄的末尾。 當其中一個作業確定它正在讀取一個沒有開頭的記錄時,它應該跳過該記錄。

從性能的角度來看,更好的選擇是在遠程服務器上執行解析。 除特殊情況外,網絡速度始終是瓶頸,因此限制通過網絡發送的數據量將大大提高性能。

這是許多數據庫使用在服務器端運行的存儲過程的原因之一。

通過使用多線程解析速度(如果有的話)的改進將被網絡傳輸的相對速度所淹沒。

如果您在解析文件之前承諾傳輸文件,則可以考慮的一個選項是在進行文件傳輸時使用動態壓縮。 例如,有可用的sftp服務器可以即時執行壓縮。 在本地端,你可以使用像libcurl這樣的東西進行傳輸的客戶端,這也支持動態解壓縮。

如果您可以復制該文件,則可以閱讀該文件。 因此,首先不需要復制它。

編輯 :使用FileStream類可以更好地控制訪問和共享模式。

new FileStream("logfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

應該做的伎倆。

我已經使用SharpZipLib壓縮大文件,然后再通過Internet傳輸它們。 所以這是一個選擇。

1)的另一個想法是創建一個在遠程機器上運行並在那里進行解析的程序集。 您可以使用.NET遠程處理從本地計算機訪問程序集。 遠程程序集需要是Windows服務或托管在IIS中。 這將允許您將日志文件的副本保存在同一台計算機上,理論上它將花費更少的時間來處理它們。

我認為使用壓縮(deflate / gzip)會有所幫助

給出的答案並不能讓我滿意,也許我的答案會幫助別人不要認為它太復雜,或者多線程在這種情況下不會受益。 也許它不會使傳輸速度更快,但根據解析的復雜性,它可能會更快地解析/或分析解析的數據。

這實際上取決於解析的細節。 您需要從日志文件中獲取哪些信息? 這些信息是統計信息還是依賴於多條日志消息? 你有幾個選擇:

  • 解析多個文件同樣是最簡單的我猜,你有文件作為上下文,可以為每個文件創建一個線程
  • 如前所述的另一種選擇是使用壓縮進行網絡通信
  • 您還可以使用幫助程序將日志文件拆分為屬於第一步的行,然后使用多個線程處理這些行塊; 解析這個依賴行應該非常容易和快速。

在這種情況下非常重要的是衡量你的實際瓶頸是什么。 如果您的瓶頸是網絡,那么您將無法過多地優化解析器。 如果您的解析器創建了許多相同類型的對象,您可以使用ObjectPool模式並創建具有多個線程的對象。 嘗試處理輸入而不分配太多新字符串。 解析器通常是使用很多string.Split等編寫的,但實際上並不是那么快。 您可以通過檢查即將到來的值來導航Stream,而無需讀取完整的字符串並再次將其拆分,但可以在解析完成后直接填充您需要的對象。

幾乎總是可以進行優化,問題是您可以獲得多少輸入以及您的方案的重要程度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM