Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
38
Help us understand the problem. What is going on with this article?
@cubicdaiya

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

More than 3 years have passed since last update.

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

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

そこで効果的なのが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みたいなパラメータ追加するか)

38
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
cubicdaiya
Tech Lead, Network
mercari
フリマアプリ「メルカリ」を、グローバルで開発しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
38
Help us understand the problem. What is going on with this article?