2012-04-18 64 views
0

我的要求是編寫一個永不結束的傳入變量大小的二進制消息流到文件系統。平均大小爲2KB的消息以1000個消息/秒達到。所以在一個小時內,消息的總數將是3600 * 1000 * 2 = 6.8GB。 消息的主要目的是以下 1.存檔他們審計的目的 2.提供一個搜索界面在linux中可靠的寫入

我的問題是

  1. 是否有解決這個問題
  2. 的開源軟件如果進程以塊大小的倍數寫入並且進程在寫入塊的中間時崩潰,會出現什麼樣的錯誤?
  3. 可能發生哪種錯誤,其中應用程序寫入了塊大小,但文件系統未刷新將數據發送到磁盤。
  4. 可以在任何情況下損壞inode
  5. 在linux中是否有文件大小限制?
  6. 是否有理想的文件大小?大文件(GB)與中文文件(MB)的優缺點
  7. 其他需要注意的事項?
  8. 我的選擇是使用C++,但如果需要的話,我可以這裏是切換到C.

回答

2

一旦writewritev返回(即OS已經接受它),操作系統負責將數據寫入到磁盤。這不再是你的問題,而且不管你的程序崩潰,它都會發生。請注意,對於一次接受或實際寫入的數據的確切數量,您是否有無控制,也不知道它是否發生在多個文件系統塊中,或者它是否是任何特定大小。您發送一個請求write,它告訴你它實際接受了多少,它會自行決定將它寫入磁盤。
可能這會發生在塊大小的倍數上,因爲這對於操作系統來說是有意義的,但這是不能以任何方式保證(在許多系統上,包括Linux,讀取和寫入都是通過或緊密耦合與文件映射)。

同樣的「不必關心」保證適用於文件映射(理論上的例外是,崩潰的應用程序原則上仍然可以寫入仍然映射的區域,但是一旦您已經取消映射區域,則不能即使在理論上也是如此)。除非你拔掉插頭(或內核崩潰),否則數據將被寫入並且一致。
由於內存頁面是設備塊的倍數,並且文件映射不知道其他任何內容,因此數據將只能以多個文件系統塊寫入,它只是以這種方式工作。

您可以類型(忽略任何可能的無緩衝的磁盤上寫入緩存)得到一些控制與fdatasync磁盤上的內容。當該函數返回時,之前緩衝區中的內容已發送到磁盤。
但是,這仍然不會阻止您的進程同時在另一個線程中崩潰,並且不會阻止某人拔出插件。 fdatasync優於fsync,因爲它不會觸及inode附近的任何東西,這意味着它更快更安全(由於長度尚未更新,您可能會丟失後續崩潰中寫入的最後一個數據,但是您絕對不應該破壞/損壞整個文件)。使用C庫函數(fwrite)自己進行緩衝並控制您寫入的數據量,但只有「已寫入」數據意味着它存儲在C庫擁有的緩衝區中(在您的過程中) 。如果進程死亡,數據就消失了。無法控制數據如何擊中磁盤,或者如果有的話。 (Nb:你可以控制的一些,只要你可以fflush,這會在返回之前立即將緩衝區的內容傳遞給底層的寫入函數,最有可能的是writev,這樣你就回到了第一段。 )

異步IO(內核 aio)將繞過內核緩衝區,並通常直接從您的進程中提取數據。您的流程死亡,您的數據消失了。 Glibc aio使用在write上阻塞的線程,與第1段中的相同。

如果您隨時拔出插頭或打開「關閉」開關,會發生什麼情況?沒人知道。
通常一些數據會丟失,操作系統可以給很多保證,但是它不能做魔術。儘管在理論上,您可能有一個系統可以緩衝內存與電池或系統,並擁有龐大的專用磁盤緩存,這也是電池供電。沒人能說。無論如何,計劃丟失數據。
也就是說,什麼是寫一次應該不會,如果你繼續追加到一個文件通常會損壞(雖然,真的什麼都可能發生,而「不應該」,並不意味着很多)。總之,在追加模式下使用write或者使用文件映射應該足夠好,它們就像你可以得到的一樣好。除突然斷電之外,它們可靠且高效。
如果電源故障是一個問題,UPS將提供比任何軟件解決方案所能提供的更好的保證。

至於文件大小,我看不出有任何理由人爲地限制文件大小(假設爲合理的新的文件系統)。 「標準」Linux文件系統的普通文件大小限制(如果有的話)在TB級範圍內。
無論哪種方式,如果你感到不安與破壞一個文件,不管是什麼原因可能會破壞有價值的數據30天的想法,開始每天都有新的文件一次。它不需要額外的費用。

+0

至少在Linux系統中,你可以結合使用'fflush'用'fsync'或'sync',以確保所有的數據被寫入到磁盤當然違反這個保證... – jofel 2012-04-18 10:25:23

+0

@jofel:的確,我在編寫這個時編輯了它。 :-)但是還有更多。首先它阻塞,除非你有多個線程,否則每秒鐘到達1000條消息。對於多個線程,同步不會產生任何影響,因爲另一個線程可能在同步過程中結束您的進程。另外,在磁盤上有未知的電源故障行爲寫入緩存(希望是一個好的,但誰知道)。現在當然也有非阻塞同步,但是...... – Damon 2012-04-18 10:35:23

0

問題,該方案未確切說明。 因此,一些答案是猜測:

  1. 是 - 它被稱爲'g ++'。 ;-)
  2. 許多不同。恕我直言,儘量通過爲您的程序編寫好的和許多測試用例來避免這種情況。
  3. 根據您的系統和您的程序,將'only'寫入內存緩衝區是正常的做事方式。應該沒有問題。
  4. 這取決於故障情況和使用的文件系統。 (也有文件系統沒有inodes。)
  5. 每個文件系統都有它的文件大小限制。正確的答案(對你來說可能沒用)是:是的。
  6. 否 - 這在很大程度上取決於您的應用程序和您的環境(如硬盤,備份系統,IO系統,...)
  7. 需要更多信息來回答此問題。
  8. 不是問題。

希望這有助於第一步。 如果您決定朝哪個方向行進,請在問題中添加信息 - 您提供的要求越多,回答 的效果就越好。

0

你手邊有一個有趣的問題。我不是這方面的專家,但有足夠的知識來評論這些。

如果您還沒有閱讀本文,您可以閱讀本文,以獲得有關各種文件系統linux的綜合概述,他們的優點&缺點,限制等。 Comparison of FileSystems in Linux

1)我所遇到的自動旋轉日誌文件庫,在Python/Perl中,確保在C/C++太可用相同。 2/3/4)日誌文件系統在很大程度上防止文件系統崩潰。他們也支持數據記錄,但沒有使用太多。

Check this for more info on journaling

0

你應該使用SQLite。它解決了你需要的一切。包括速度,如果你正確使用該數據庫。寫作過程中突然斷電(或者其它硬件故障)可能 -