Linuxファイルシステムキャッシュからすべてをドロップできることは知っていますが、特定のファイルを1つだけドロップする方法はありますか?または、ファイルがキャッシュされないようにしますか?または、書き込むファイルをキャッシュしないようにプロセスに指示しますか?
多くの小さなファイルを読み取り、大きなファイルを書き込むプロセスがあります。ディスクシークを回避するために小さなファイルをキャッシュに保持したいのですが、大きなファイルをキャッシュする必要はありません。
Linuxファイルシステムキャッシュからすべてをドロップできることは知っていますが、特定のファイルを1つだけドロップする方法はありますか?または、ファイルがキャッシュされないようにしますか?または、書き込むファイルをキャッシュしないようにプロセスに指示しますか?
多くの小さなファイルを読み取り、大きなファイルを書き込むプロセスがあります。ディスクシークを回避するために小さなファイルをキャッシュに保持したいのですが、大きなファイルをキャッシュする必要はありません。
回答:
このメールスレッドでLinuxカーネルに提案されたパッチについて説明している2012年の方法を見つけました:Re:[RFC Patch] fs:implement per file drop caches。
抜粋Cong>これは、ファイルごとのドロップキャッシュを実装するためのドラフトパッチです。
面白い。プロセスの外部からこれを行うことができますか?私はSysAdminであるため、POVはシステムがプレッシャーにさらされているときにパフォーマンスの問題に気づき、発見し、修正することからのものです。
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>以下は、このパッチの小さなテストケースです。
スレッドには、テストケースと、Linuxカーネル内のいくつかのファイルへの実際のパッチの両方が含まれており、追加の機能がfs/drop_caches.c
calledに追加され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カーネルを自分で再コンパイルする場合にのみ、このオプションが利用できるように見えます。
同じスレッドで、別のユーザーがを使用するまったく異なる方法論に言及していますdd
。
それをテストするこれは便利な機能です。既に提供されていないの
そのパッチの例を次に示します。POSIX_FADV_DONTNEED
ですか?この機能は1年前にGNU dd(8.11)に追加されました。
ファイル全体のキャッシュを削除することをお勧めします
$ 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
$ 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内のファイルによって消費されたものはすべて解放されたように見えます。
@frostchutzのコメントのおかげ[pyadvise][4]
で、上記のdd
メソッドよりもはるかにシンプルなインターフェースを提供するPythonスクリプトという別のツールがあります。このスクリプトは同じ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
たときと同じように、RAMの消費量が消費されていることに気付きました。
dd
私のために働く。私は終わったchris-lamb.co.uk/projects/python-fadviseより明白なコマンドでも同じことである自分自身を。
python-fadvise
の方がはるかに簡単dd
です。
os.posix_fadvise()
、Pythonの標準ライブラリにあります。
@geekosaurの答えを展開するO_DIRECT
と、LD_PRELOADとプログラムを使用して強制的に使用できます:http : //arighi.blogspot.com/2007/04/how-to-bypass-buffer-cache-in-linux.html
そのコードO_DIRECT
はすべてのファイルに強制的に適用されます。ただし、strncmpロジックを追加するだけで、__do_wrap_open
O_DIRECTを選択的に適用できます。
免責事項:私はこれをテストしていません。
O_DIRECT
フラグを使用して個々のファイルを開くことができます(を参照man 2 open
)— そのマンページのNOTESセクションを注意深く読み、必要かどうかも検討してくださいO_SYNC
。
cat
であり、私はそれを書き直したくない。:)コマンドラインツールまたは/proc/sys
ノブを望んでいた。
open
フラグを別にしてこれを制御するファイルごとの方法を知りません。実際にそれを行うにはプログラムを書く必要があります。(OSバッファリングではなく、バッファリングcat -u
のみを無効にしますstdio
。)
ファイルが常にO_SYNCを使用するように強制する場合は、拡張属性でそのようにマークできますchattr +S $file
。
男のおしゃべり:
「S」属性が設定されたファイルが変更されると、変更は同期的にディスクに書き込まれます。これは、ファイルのサブセットに適用される 'sync'マウントオプションと同等です。
O_SYNCは、データ+メタデータをディスクバッファーに強制的に書き込みますが、それでもページキャッシュを通過します。O_DIRECTはページキャッシュをバイパスします。
ただし、O_DIRECTで開くとパフォーマンスが低下することに注意してください。大きなファイルが追加されるだけで、差が小さくなる場合があります。しかし、大きなファイルがランダムな場所で書き換えられた場合、O_DIRECTはパフォーマンスに大きな影響を与えます。キャッシュに格納すると、小さな読み取りファイルの一部がキャッシュから削除される可能性があることを考慮しても。
すべての小さなファイルをそこに保持するRAMがある場合は、別の方法で問題にアプローチできます。小さなファイルが常にRAMにあることを確認してから、それらをtmpfsにコピーすることをお勧めします。
tmpfsは、すべてをカーネルの内部キャッシュに入れ、それに含まれるファイルに合わせて拡大および縮小します
chattr +S
同じものではありませんO_DIRECT
、それは同じことですO_SYNC
。O_DIRECT
原因は読み込み(この質問があるものについてである)キャッシュされていない、と保証なしで、バッファリングされていない書き込みます。書き込みO_SYNC
のみがバッファリングされません。
O_DIRECT
するO_SYNC
と、回答が内部的に一貫したものになりますが、質問を考慮するとまだ間違っています。