LoginSignup
40
38

More than 5 years have passed since last update.

cachectldでOSのページキャッシュ削除を自動化

Last updated at Posted at 2014-12-28

サーバを運用していると時々全然メモリが余っているはずなのにスワップが起きてしまうことがあります。この場合よくあるケースは非常に大きなログファイルがあってそのログファイルのために大量のページキャッシュが利用されていることです。

ログファイルなんて滅多に読まないので、そんなのにメモリ使うぐらいだったらもっと別のアプリケーションにちゃんと割り当ててくれよと思うのですが、なかなかうまくいかないものです。

そこで効果的なのがposix_fadivseをラップして指定したファイルのページキャッシュを解放するツールです。

私の場合、今まではnocacheというツールをちょこっと改造して使っていましたが、最近もうちょっと便利な風に改造したいと思うようになってきました。例えば、

  • 指定したディレクトリ内すべてのファイルのページキャッシュの確認・解放がしたい
  • いちいちfindと組み合わせたりcronの設定書きたくない

といった要件です。nocacheはCで書かれてることもあってがっつり改造するには不向きです。いや、Cは書けるんだけど最近はもうこういうツールはGoでいいよなぁと思ってるだけなんですが。(もちろんposix_fadviseを呼び出す部分はFFI(Goの場合はcgo))

cachectl

というわけで書きました。

名前は若干ネタですが、やってることはいたってまじめです。(ISUCON4でCache-Controlに気付かなかった皆さんお元気ですか?僕も気付きませんでした)

ビルド手順はこんな感じです。ビルドが成功するとbinディレクトリにcachectlcachectldというファイルが出来ます。

git clone https://github.com/cubicdaiya/cachectl.git
cd cachectl
make bundle
make

cachectl-fオプションにファイルパスを与えるとそのファイルの内容がページキャッシュにのっているかチェックできます。

$ bin/cachectl -f conf/cachectld.toml
conf/cachectld.toml 's pages in cache: 0/1 (0.0%)  [filesize=0.2K, pagesize=4K]
$

ディレクトリも指定できます。

$ bin/cachectl -f cachectl
bin/cachectl -f cachectl
cachectl/activepages.go 's pages in cache: 0/1 (0.0%)  [filesize=1.2K, pagesize=4K]
cachectl/conf.go 's pages in cache: 0/1 (0.0%)  [filesize=0.8K, pagesize=4K]
cachectl/const.go 's pages in cache: 0/1 (0.0%)  [filesize=0.1K, pagesize=4K]
cachectl/purge.go 's pages in cache: 0/1 (0.0%)  [filesize=1.1K, pagesize=4K]
cachectl/stat.go 's pages in cache: 0/1 (0.0%)  [filesize=0.7K, pagesize=4K]
cachectl/version.go 's pages in cache: 0/1 (0.0%)  [filesize=0.2K, pagesize=4K]
$

ページキャッシュを消す場合は-op purgeを指定します。(↓の例だと元々ページキャッシュにのってないですが)

$ bin/cachectl -f conf/cachectld.toml -op purge
Before purging conf/cachectld.toml 's page cache

conf/cachectld.toml 's pages in cache: 0/1 (0.0%)  [filesize=0.2K, pagesize=4K]

After purging conf/cachectld.toml 's page cache

conf/cachectld.toml 's pages in cache: 0/1 (0.0%)  [filesize=0.2K, pagesize=4K]
$

また、ファイルの末尾だけページキャッシュにのせたままにしたい場合は-rで割合を指定できます。例えばページキャッシュをファイルの末尾1割を除いて削除する場合は0.9を指定すればよいわけです。

cachectldで定期的にページキャッシュを削除

cachectldは定期的に指定ファイルのページキャッシュを削除するデーモンです。まずはこんな感じのTOMLファイルを用意します。

[[targets]]
path = "/vagrant/cachectl.go"
purge_interval = 30

[[targets]]
path = "/vagrant/cachectld.go"
purge_interval = 20

[[targets]]
path = "/vagrant/cachectl"
purge_interval = 5
filter = "\\.go$"
rate = 0.9

purge_intervalがキャッシュを削除する間隔(秒)です。あとはこれを起動しておくだけで定期的にページキャッシュを削除してくれます。

$ bin/cachectl -c conf/cachectld.toml

とはいえログローテートのタイミングでログのページキャッシュ消されたらそれはそれで困るのでこのあたりはなんかうまい方法考えたい。(disabled_hour_rangeみたいなパラメータ追加するか)

40
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
38