0

私の要件は、着信可変サイズのバイナリメッセージの終わりのないストリームをファイルシステムに書き込むことです。平均サイズ2KBのメッセージは、1000メッセージ/秒で到着します。したがって、1時間で、メッセージの総数は3600 * 1000 * 2 =6.8GBになります。メッセージの主な目的は次のとおりです。1。監査目的でメッセージをアーカイブします。2。検索インターフェイスを提供します。

私の質問は

  1. この問題を解決するオープンソースソフトウェアはありますか
  2. プロセスがブロックサイズの倍数で書き込み、ブロックの書き込み中にプロセスがクラッシュした場合、どのようなエラーが発生する可能性がありますか
  3. アプリケーションがブロックサイズを書き込んだのに、ファイルシステムがデータをディスクにフラッシュしていない場合、どのようなエラーが発生する可能性がありますか。
  4. どのシナリオでもiノードが破損する可能性があります
  5. Linuxにファイルサイズの制限はありますか?
  6. 理想的なファイルサイズはありますか?ラージファイル(GB単位)とミディアムファイル(MB単位)の長所と短所は何ですか
  7. 他に注意すべき点はありますか?
  8. 私の好みはC++を使用することですが、必要に応じてCに切り替えることができます。
4

4 に答える 4

2

Once write or writev returns (i.e. the OS has accepted it), the operating system is responsible for writing data to disk. It's not your problem any more, and it's happening irrespectively of your process crashing. Note that you have no control over the exact amount of data accepted or actually written at a time, nor whether it happens in multiples of filesystem blocks or whether it's any particular size at all. You send a request to write and it tells you how much it actually accepted, and it will write that to disk, at its own discretion.
Probably this will happen in multiples of the block size because it makes sense for the OS to do that, but this is not guaranteed in any way (on many systems, Linux included, reading and writing is implemented via or tightly coupled with file mapping).

The same "don't have to care" guarantee holds for file mapping (with the theoretical exception that a crashing application could in principle still write into a still mapped area, but once you've unmapped an area, that cannot happen even theoretically). Unless you pull the plug (or the kernel crashes), data will be written, and consistently.
Data will only ever be written in multiples of filesystem blocks, because memory pages are multiples of device blocks, and file mapping does not know anything else, it just works that way.

You can kind of (neglecting any possible unbuffered on-disk write cache) get some control over what's on the disk with fdatasync. When that function returns, what has been in the buffers before has been sent to the disk.
However, that still doesn't prevent your process from crashing in another thread in the mean time, and it doesn't prevent someone from pulling the plug. fdatasync is preferrable over fsync since it doesn't touch anything near the inode, meaning it's faster and safer (you may lose the last data written in a subsequent crash since the length has not been updated yet, but you should never destroy/corrupt the whole file).

C library functions (fwrite) do their own buffering and give you control over the amount of data you write, but having "written" data only means it is stored in a buffer owned by the C library (in your process). If the process dies, the data is gone. No control over how the data hits the disk, or if ever. (N.b.: You do have some control insofar as you can fflush, this will immediately pass the contents of the buffers to the underlying write function, most likely writev, before returning. With that, you're back at the first paragraph.)

Asynchronous IO (kernel aio) will bypass kernel buffers and usually pull the data directly from your process. Your process dies, your data is gone. Glibc aio uses threads that block on write, the same as in paragraph 1 applies.

What happens if you pull the plug or hit the "off" switch at any time? Nobody knows.
Usually some data will be lost, an operating system can give many guarantees, but it can't do magic. Though in theory, you might have a system that buffers RAM with a battery or a system that has a huge dedicated disk cache which is also battery powered. Nobody can tell. In any case, plan for losing data.
That said, what's once written should not normally get corrupted if you keep appending to a file (though, really anything can happen, and "should not" does not mean a lot).

All in all, using either write in append mode or file mapping should be good enough, they're as good as you can get anyway. Other than sudden power loss, they're reliable and efficient.
If power failure is an issue, an UPS will give better guarantees than any software solution can provide.

As for file sizes, I don't see any reason to artificially limit file sizes (assuming a reasonably new filesystem). Usual file size limits for "standard" Linux filesystems (if there is any such thing) are in the terabyte range.
Either way, if you feel uneasy with the idea that corrupting one file for whatever reason could destroy 30 days worth of data, start a new file once every day. It doesn't cost extra.

于 2012-04-18T09:30:44.743 に答える
0

ここでの問題は、シナリオが正確に記述されていないことです。したがって、答えのいくつかは当て推量です。

  1. はい-「g++」と呼ばれます。;-)
  2. 多くの異なる。IMHOは、プログラムに適した多くのテストケースを作成することで、これを回避しようとしています。
  3. システムとプログラムによっては、メモリバッファに「のみ」を書き込むのが通常の方法です。問題ないはずです。
  4. これは、障害シナリオと使用されているファイルシステムによって異なります。(iノードのないファイルシステムもあります。)
  5. 各ファイルシステムには、ファイルサイズの制限があります。正解(あなたには役に立たないかもしれません)は次のとおりです。はい。
  6. いいえ-これは、アプリケーションと環境(ハードディスク、バックアップシステム、IOシステムなど)に大きく依存します。
  7. これに答えるには、より多くの情報が必要です。
  8. 質問ではありません。

これが最初のステップに役立つことを願っています。どちらの方向に進むかを決めた場合は、質問に情報を追加してください。要件が多ければ多いほど、答えは良くなります。

于 2012-04-18T06:27:54.987 に答える
0

手元に興味深い問題があります。私はこれらの分野の専門家ではありませんが、これらについてコメントするのに十分な知識を持っています。

まだ読んでいない場合は、これを読んで、Linuxのさまざまなファイルシステムの長所と短所、制限などの概要を確認でき ます。Linuxでのファイルシステムの比較

1)Python / Perlで自動回転ログファイルライブラリに出くわしましたが、C /c++でも同じです。2/3/4)ジャーナリングファイルシステムは、ファイルシステムのクラッシュからより強力に保護します。彼らはデータのジャーナル化もサポートしていますが、あまり使用していません。

ジャーナリングの詳細については、これを確認してください

于 2012-04-18T06:53:35.470 に答える
0

SQLiteを使用する必要があります。それはあなたが必要とするすべてを解決します。そのDBを適切に使用する場合の速度を含みます。

于 2016-10-23T20:55:38.420 に答える