いつ/dev/shm/ を使うべきか、いつ/tmp/ を使うべきか?
/dev/shm/
を使うべきタイミングと/tmp/
を使うべきタイミングは?Unices上では常に両方とも存在していることを頼りにしてもいいのでしょうか?
/dev/shm/
を使うべきタイミングと/tmp/
を使うべきタイミングは?Unices上では常に両方とも存在していることを頼りにしてもいいのでしょうか?
tmpfs
可能性の高い順:
┌───────────┬──────────────┬────────────────┐
│ /dev/shm │ always tmpfs │ Linux specific │
├───────────┼──────────────┼────────────────┤
│ /tmp │ can be tmpfs │ FHS 1.0 │
├───────────┼──────────────┼────────────────┤
│ /var/tmp │ never tmpfs │ FHS 1.0 │
└───────────┴──────────────┴────────────────┘
あなたが質問しているのは、Linux特有のtmpfsマウントポイントと、_tmpfsかもしれない移植可能な定義のディレクトリ(sysadminやディストロのデフォルトの設定による)についてなので、あなたの質問には2つの側面があり、他の回答では異なって強調されています。
1.これらのディレクトリをいつ使うか、good practiceに基づいて 2. tmpfsを使うのが適切な場合
保守版(FHS の規約と一般的な使用法の混合):
/tmp
を使用してください。/var/tmp
を使用する。/var/tmp
を使用してください。/dev/shm
を呼び出すことの副作用として shm_open()
を使用する。対象となるのは、無限に上書きされる境界付きバッファです。そのため、これはコンテンツが揮発性で、それほど大きくない長持ちするファイルのためのものです。mktemp
プログラムは環境変数 TMPDIR
を尊重します。実用版。
tmpfs を使用することが重要な場合は /dev/shm
を使用し、使用しないことが重要な場合は /var/tmp
を使用し、そうでない場合は /tmp
を使用する。
fsync
は tmpfs を使わない。このシステムコールは (IO) パフォーマンス (とフラッシュの寿命を気にするなら) の一番の敵ですが、もしあなたが fsync を倒すためだけに tmpfs (または eatmydata ) を使っていることに気がついたら、あなた (またはチェーン内の他の開発者) は何か間違ったことをしていることになります。それは、ストレージデバイスへのトランザクションが目的のために不必要に細かい粒度になっていることを意味します - あなたは明らかにパフォーマンスのためにいくつかのセーブポイントをスキップしても構わないと思っています。また、SSDを持つことの最大の利点のいくつかは、ここにあるトランザクションパフォーマンスの土地にあります - どんなまともなSSDでも、回転するディスクが取ることができるものと比較して、この世のものとは思えないほどのパフォーマンスを発揮します (7200 rpm = 120 Hz、他の人がアクセスしていない場合)。だから、超高速SSDの開発者の皆さん、ユーザーにこのユースケースを強要しないように注意してください。
馬鹿げた話を聞きたいですか?私の最初のfsync
レッスン: 私は、Sqliteデータベースの束(テストケースとして保管されている)を、常に変化し続ける現在のフォーマットに日常的に「アップグレード」する仕事をしていました。アップグレード “フレームワークは、1つのデータベースをアップグレードするために、スクリプトの束を実行し、それぞれ少なくとも1つのトランザクションを作成していました。もちろん、私はデータベースを並行してアップグレードしました(8コアのCPUに恵まれていたので、8つのデータベースを並行してアップグレードしました)。しかし、わかったことですが、プロセスが完全にIOに縛られていたため、並列化のスピードアップは全くありませんでした(むしろ少しだけヒットしました)。面白いことに、アップグレードフレームワークをスクリプトでラップして、各データベースを/dev/shm
にコピーして、そこでアップグレードして、ディスクにコピーし直すと、100倍くらい速くなりました(それでも8コア並列)。おまけに、データベースをアップグレードしている間は、PCも_使用可能でした。
tmpfs の適切な使い方は、揮発性データの不要な書き込みを避けることです。事実上、通常のファイルシステムで/proc/sys/vm/dirty_writeback_centisecs
を無限大に設定するのと同じように、writebackを無効にします。
これはパフォーマンスとはほとんど関係がなく、これに失敗することは fsync を悪用するよりもはるかに小さな問題です。ライトバックタイムアウトは、ディスクのコンテンツがページキャッシュのコンテンツの後にどれだけ怠惰に更新されるかを決定し、デフォルトの 5 秒はコンピュータにとって長い時間です。アプリケーションが fsync を使って強制的にファイルを上書きしない限り、です。アプリケーションがこの時間に小さなファイルを何回出力できるかを考えてみてください。
で助けられないこと - 読み込みパフォーマンス。データがホットな場合(tmpfs に保存することを考えるならば、そうした方が良いでしょう)、とにかくページキャッシュにヒットしてしまいます。違いは、ページキャッシュをヒットしない場合です; この場合は、以下の「Where tmpfs sux」を参照してください。
- 短命ファイル。これらのファイルは、書き出される前にページキャッシュの中で(dirtyページとして)一生を過ごすことができます。もちろん fsync
で強制しない限り。
cold データを保持している。スワップからファイルを出すことは通常のファイルシステムと同じように効率的だと思いたくなるかもしれませんが、そうではない理由がいくつかあります:
さて、ここからが現実です。
tmpfsも通常のファイルシステムもディスク上のメモリキャッシュである。
tmpfs はメモリとスワップスペースをバッキングストアとして使用しますが、ファイルシステムはディスクの特定の領域を使用します。
違いは、データがディスクに書き込まれるタイミングにあります。tmpfsの場合、メモリがいっぱいになったときや、すぐに使用できそうにないときにのみデータが書き込まれます。しかし、ほとんどの通常のLinuxファイルシステムは、ユーザがプラグを抜いてもすべてのデータを失うことがないように、多かれ少なかれ一貫したデータが常にディスクに書き込まれるように設計されています。
個人的には、クラッシュしないオペレーティングシステムとUPSシステム(例: ラップトップのバッテリー)には慣れているので、ext2/3ファイルシステムは5-10秒のチェックポイント間隔であまりにも偏執的だと思います。ext4 ファイルシステムは 10 分間のチェックポイントの方が良いのですが、ユーザデータを二流扱いして保護していないことを除けば、その方が良いでしょう。(ext3も同じですが、5秒のチェックポイントがあるので気がつきません)
この頻繁なチェックポイントは、/tmpであっても不要なデータがディスクに書き込まれ続けていることを意味しています。
その結果、/tmp に必要な大きさのスワップスペースを作成し(たとえスワップファイルを作成する必要があったとしても)、そのスペースを使って必要なサイズの tmpfs を /tmp にマウントする必要があるということになります。
/dev/shm は絶対に使わないでください。
/dev/shm は非常に小さな (おそらく mmap された) IPC ファイルに使用していて、/dev/shm が存在していることを確認していて (これは標準ではありません)、マシンに十分以上のメモリとスワップが利用可能であることを確認している場合を除いては、絶対に使用しないでください。
一時的なファイルには /tmp/ を使ってください。共有メモリが必要な場合は /dev/shm/ を使います (ファイルを介したプロセス間通信など)。
/tmp/ があることに頼ることができますが、/dev/shm/ は比較的最近の Linux 専用のものです。
(Linux 2.6 以上では)/dev/shm を使うべき時は、ディスクへの書き込みができるかどうかわからないので、保証された tmpfs ファイルシステムが必要な時です。
私がよく知っている監視システムでは、中央サーバに提出するためのレポートを作成している間に一時ファイルを書き出す必要があります。実際には、何かがファイルシステムへの書き込みを阻止する可能性の方がはるかに高いです(ディスクスペースがないか、RAID の故障でシステムがハードウェアの読み取り専用モードになっているかのどちらか)が、tmpfs が使用可能なメモリがすべて使えなくなるような事態が発生した場合よりも、アラートを出すことができます。このような場合、監視システムは RAM への書き込みを優先し、ディスクがいっぱいになったり、ハードウェアが死んだり死んだりした場合にアラートを送信できるようにします。
/dev/shm は、共有仮想メモリシステム固有のデバイスドライバやプログラムに使用されます。
仮想メモリヒープを必要とするプログラムを作成している場合は、仮想メモリにマッピングする必要があります。これは、メモリに安全にアクセスできるようにするために複数のプロセスやスレッドが必要な場合には、2倍の効果があります。
ドライバがtmpfsの特別なバージョンを使っているからといって、一般的なtmpfsパーティションとして使うべきとは限りません。代わりに、一時ディレクトリ用に別の tmpfs パーティションを作成してください。
PERLでは、任意のマシン(すべてLinux Mintを実行している)で最低8GBを持っている、私は私が良い習慣だと思うもののDB_Fileベースの(ファイル内のデータ構造)複雑なアルゴリズムを行うには、/dev/shm
/dev/shm を使用して数百万の読み取りと書き込みを使用しています他の言語では、どこでもgigetherを持っていない。ネットワーク転送の開始と停止を避けるために、(クライアント・サーバの雰囲気の中でサーバ上にあるファイルをローカルで作業する)ある種のバッチファイルを使って、一度に全体(300-900MB)のファイルを/dev/shmにコピーし、/dev/shmに出力してプログラムを実行し、その結果をサーバに書き戻し、/dev/shmから
を削除していきます。通常、/dev/shm のインメモリファイルシステムは、使用可能な RAM の半分のサイズとして読み込みます。しかし、通常のRAMの使用量は一定です。ですから、2GB以下のデバイスでは本当にできません。言い換えを大げさに言うと、RAMにはシステムですらうまく報告してくれないことがよくあります。