私もできることを知っていますLinuxファイルシステムキャッシュのすべてのエントリを削除するところで、特定のファイルを1つだけ削除する方法はありますか?それともファイルがキャッシュされないようにしますか?または、プロセスが作成したファイルをキャッシュしないように指示しますか?
多くの小さなファイルを読み取り、1つの大きなファイルに書き込むプロセスがあります。ディスクの検索を避けるために、小さなファイルをキャッシュに保存したいので、大きなファイルキャッシュには興味がありません。
答え1
潜在的な方法 #1 - F_DROP_CACHES
私はこのメールスレッドでLinuxカーネルに提案されたパッチを議論する2012年の方法を見つけました。Re: [RFC パッチ] fs: ファイル別削除キャッシュの実装。
抜粋Cong>ファイル別削除キャッシュを実装するためのドラフトパッチです。
興味深い。では、プロセスの外部でこれを行うことができますか?私はシステム管理者なので、システムがストレスを受けたときにパフォーマンスの問題を見つけて修正することが私の視点です。
Cong> It introduces a new fcntl command F_DROP_CACHES to drop Cong> file caches of a specific file. The reason is that currently Cong> we only have a system-wide drop caches interface, it could Cong> cause system-wide performance down if we drop all page caches Cong> when we actually want to drop the caches of some huge file.
ファイルがどのくらいのキャッシュを使用しているのか、どうすればわかりますか?使用量の多いシステムで実行するとパフォーマンスにどのような影響がありますか?このパッチは私たちに何をもたらしますか?これは、システムにメモリのプレッシャーが加わると、VMがキャッシュを放棄したはずです。
Cong> 以下は、このパッチの小さなテストケースです。
fs/drop_caches.c
このスレッドには、を呼び出すアドオンを追加するLinuxカーネル内の複数のファイルのテストケースと実際のパッチが含まれています。この機能は、drop_pagecache_file(struct file *filp)
フロントエンドツールを介してコマンドを介してアクセスできます。この例では、次の関数を呼び出します。fnctl.c
F_DROP_CACHES
file_drop_caches(filp, arg);
特定のファイルに関連するすべてのキャッシュ削除を処理します。ドキュメントからinclude/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
それではこれを使用できますか?
このパッチが主要なLinuxカーネルコードストアに含まれているという証拠が見つからなかったため、このオプションはLinuxカーネルを直接再コンパイルしたい場合にのみ使用できるようです。
可能なアプローチ #2 - dd の使用
同じスレッドで他のユーザーはdd
。
試験を受けるこれは便利な機能です。まだ提供されていません
以下はパッチの例です。POSIX_FADV_DONTNEED
が?この機能は次に追加されました。GNU dd (8.11) 1年前。
ファイル全体のキャッシュを削除することをお勧めします
$ dd if=ifile iflag=nocache count=0
ファイル全体がキャッシュから削除されていることを確認してください。
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
一部のファイルのキャッシュの削除
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
先読みキャッシュを使用してデータのみを転送する
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
これをテストする方法を100%確信することはできませんが、次の方法を見つけました。
100MBファイルの作成
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
ファイルアクセス使用量の追跡
fatrace
$ sudo fatrace | grep sample.txt
実行する
top
と、メモリ使用量を監視して利用可能な量を確認できます。$ top
ファイルを開き、現在使用可能なメモリ量を確認します。
fatrace
このファイルを注意深く見てくださいsample.txt
。$ cat sample.txt > /dev/null
メモリからファイルを削除し、現在利用可能なメモリ量を確認します。出力を参照してください
fatrace
。$ sudo dd of=/home/saml/tst/162600/sample.txt \ oflag=nocache conv=notrunc,fdatasync count=0
はい
第1ターミナル:$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s
$ ls -l sample.txt
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
第2ターミナル:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
第3ターミナル:
$ sudo fatrace | grep sample.txt
ここでファイルを開き、sample.txt
RAMのサイズを確認してください。第1ターミナルから。
$ cat sample.txt > /dev/null
第2ターミナル:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
fatrace
ターミナル#3の出力を参照してください。
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
これで、ターミナル#4のRAMからファイルを削除します。
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
fatrace
ターミナル#2の出力を参照してください。
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
ターミナル#3のRAMを確認してください。
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
したがって、RAM内のファイルが消費するすべてが解放されたように見えます。
潜在的なアプローチ #3 - python-fadvise
[pyadvise][4]
@frostchutzのコメントのおかげで、上記の方法よりも簡単なインターフェースを提供するPython Scriptという別のツールがありますdd
。スクリプトは同じposix_fadvise(2)
インタフェースを使用します。
$ sudo pyadvise --help
Usage:
pyadvise [options] [FILE]..
Options:
-h, --help show this help message and exit
-w, --willneed The specified files will be accessed in the near future
-s, --sequential The application expects to access the specified files
sequentially (with lower offsets read before higher ones)
-d, --dontneed The specified files will not be accessed in the near
future
-r, --random The specified files will be accessed in random order
-o, --noreuse The specified files will be accessed only once. Under
Linux, this operation is a no-op; see contrib/copyfileobj-
fadvise.py in the python-fadvise source tree for an
example on how to achieve approximately the same effect
-n, --normal Indicates that the application has no advice to give about
its access pattern for the specified files. If no advice
is given for an open file, this is the default assumption
-v, --verbose Explain what is being done
上記のテストを繰り返して、pyadvise
以下を使用するとdd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
dd
.
答え2
O_DIRECT
@geekosaurの回答を拡張すると、LD_PRELOADとここの手順を使用して強制的に適用できます。http://aighi.blogspot.com/2007/04/how-to-bypass-buffer-cache-in-linux.html
このコードはO_DIRECT
すべてのファイルで動作します。ただし、strncmpロジックを追加すると、__do_wrap_open
O_DIRECTをオプションで適用できます。
免責事項:私はこれをテストしていません。
答え3
このフラグを使用して単一のファイルを開くことができますO_DIRECT
(参照man 2 open
) - 読み取りノートそのマンページのセクションを注意深く読んで、自分が欲しいかどうかを検討してくださいO_SYNC
。
答え4
ファイルが常にO_SYNCを使用するようにするには、拡張属性に表示するだけですchattr +S $file
。
男性チャット:
「S」属性が設定されているファイルが変更されると、変更はディスクに同期的に書き込まれます。これは、ファイルサブセットに適用される「同期」マウントオプションと同じです。
O_SYNCはデータ+メタデータを強制的にディスクバッファに書き込みますが、それでもページキャッシュを通過します。 O_DIRECTはページキャッシュをバイパスします。
ただし、O_DIRECTで開くとパフォーマンスに有害な影響を与える可能性がありますが、大きなファイルを追加するだけでは違いが少なくなる可能性があります。ただし、大容量ファイルを任意の場所に上書きすると、O_DIRECTがキャッシュにあることを考慮してもパフォーマンスに大きな影響を与え、いくつかの小さな読み取りファイルをキャッシュから削除できます。
小さなファイルをすべて保存できるメモリがある場合は、別の方法でこの問題を解決できます。小さなファイルが常にメモリにあることを確認し、そのファイルを次の場所にコピーすることをお勧めします。一時ファイルシステム:
tmpfsはすべてを内部カーネルキャッシュに保存し、埋め込みファイルを収容できるように拡張および縮小します。