Linuxでページキャッシュを確認・解放してみた

ページキャッシュについて知らなかった・解放してみたことがなかったのでやってみた時のメモ。

# 参考

+ [ページキャッシュの詳細確認と削除方法](http://tsuchinoko.dmmlabs.com/?p=1206)
+ [Linux のページキャッシュ](http://d.hatena.ne.jp/naoya/20070521/1179754203)
+ [Linux OS でキャッシュをクリアする方法 (Kernel 2.6.16～)](http://www.shift-the-oracle.com/linux/utility/flush-buffer-cache.html)

# そもそもページキャッシュとは

+ CPUはストレージから直接読むことはできない
+ 上記より一旦メモリにデータを読み込む必要がある
+ メモリに読み込んだデータはそのままページキャッシュとして再利用することで次回以降CPUからは高速に読み書きができる
+ キャッシュにはページキャッシュとSlabキャッシュがある
+ ページキャッシュは上記のようなディスクの内容を読んだらメモリにキャッシュするというもの
+ Slabキャッシュはディレクトリのメタデータ情報を格納するdentryやファイルのメタデータ情報を格納するinode構造体などをキャッシュしているカーネル内のメモリ領域らしい（引用)


# ページキャッシュを解放してみる

現在のキャッシュしているサイズを確認します。

```bash
$free -m
             total       used       free     shared    buffers     cached
Mem:           995        898         96          0         51        722
-/+ buffers/cache:        124        870
Swap:            0          0          0
```

現在は722MByteのキャッシュがされているようです。

次に一度ページキャッシュを解放します。
ページキャッシュをするために`/proc/sys/vm/drop_caches`に1を指定します。

```bash
$sudo sh -c "echo 1 > /proc/sys/vm/drop_caches"
```

なお、2を指定した場合にはSlabキャッシュの解放、3を指定した場合にはページキャッシュとSlabキャッシュの解放を行います。

話が逸れましたが、キャッシュをクリアできたら再度キャッシュサイズを確認します。

```bash
$free -m
             total       used       free     shared    buffers     cached
Mem:           995        119        875          0          0         16
-/+ buffers/cache:        103        892
Swap:            0          0          0
```

722->17なのでかなりキャッシュが解放されました。

# linux-ftoolsのインストール

具体的にどのファイルがキャッシュされているかを確認するために`linux-ftools`をインストールします。

```bash
# mercurialのインストール
$sudo yum -y install mercurial

# ビルドに必要なパッケージ群のインストール
$sudo yum  -y groupinstall "Development Tools"

# linux-ftoolsインストール
$hg clone https://code.google.com/p/linux-ftools/
$cd linux-ftool
```

自分の環境(AmazonLinux2015.09.01)ではautomakeのバージョンが1.11でなく、1.13だったので`configure`ファイルの一部を変更します。(変更しないと自分はエラーになりました)

```
$git diff
diff --git a/configure b/configure
index 570dbb3..29c12e4 100755
--- a/configure
+++ b/configure
@@ -2220,7 +2220,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu



-am__api_version='1.11'
+am__api_version='1.13'
```

変更後、インストールします。

```bash
# インストール
$./configure
$make
$sudo make install

# 確認
$linux-fincore --version
linux-fincore: unrecognized option '--version'
fincore version 1.3.0
fincore [options] files...

  -s --summarize          When comparing multiple files, print a summary report
  -p --pages              Print pages that are cached
  -o --only-cached        Only print stats for files that are actually in cache.
  -g --graph              Print a visual graph of each file's cached page distribution.
  -S --min-size           Require that each files size be larger than N bytes.
  -C --min-cached-size    Require that each files cached size be larger than N bytes.
  -P --min-perc-cached    Require percentage of a file that must be cached.
  -h --help               Print this message.
  -L --vertical           Print the output of this script vertically.
```


# linux-fincoreを使ってページキャッシュを確認する

次にlinux-fincoreを使いながら具体的にキャッシュの流れを確認します。

一度、ページキャッシュを解放した状態で`/var/log`配下で何がキャッシュされているか確認します。

```bash
$sudo /usr/local/bin/linux-fincore  --pages=false --summarize --only-cached /var/log/*
filename                                                                                       size        total_pages    min_cached page       cached_pages        cached_size        cached_perc
--------                                                                                       ----        -----------    ---------------       ------------        -----------        -----------
Could not mmap file: /var/log/audit: No such device
/var/log/btmp                                                                                 3,456                  1                  0                  1              4,096             100.00
/var/log/lastlog                                                                            146,292                 36                 35                  1              4,096               2.78
Could not mmap file: /var/log/mail: No such device
/var/log/messages                                                                            50,232                 13                 12                  1              4,096               7.69
Could not mmap file: /var/log/ntpstats: No such device
/var/log/secure                                                                               9,026                  3                  1                  2              8,192              66.67
/var/log/wtmp                                                                                 6,144                  2                  1                  1              4,096              50.00
---
total cached size: 24,576
```

幾つかすでにキャッシュされているファイルもあります。
次にわざと/var/log配下のまだキャッシュされていない状態のファイルを読み込んでキャッシュに入れます。

```bash
# /var/logファイルの内容を一度キャッシュに入れる.キャッシュしたいだけなので標準出力は捨てる
$sudo sh -c "find /var/log/* -type f|xargs cat > /dev/null"

# キャッシュされているファイルを再度確認
$sudo /usr/local/bin/linux-fincore  --pages=false --summarize --only-cached /var/log/*
filename                                                                                       size        total_pages    min_cached page       cached_pages        cached_size        cached_perc
--------                                                                                       ----        -----------    ---------------       ------------        -----------        -----------
Could not mmap file: /var/log/audit: No such device
/var/log/btmp                                                                                 3,456                  1                  0                  1              4,096             100.00
/var/log/cloud-init-output.log                                                                9,332                  3                  0                  3             12,288             100.00
/var/log/cloud-init.log                                                                      72,977                 18                  0                 18             73,728             100.00
/var/log/cron                                                                                 4,053                  1                  0                  1              4,096             100.00
/var/log/dmesg                                                                               24,271                  6                  0                  6             24,576             100.00
/var/log/dracut.log                                                                         171,068                 42                  0                 42            172,032             100.00
/var/log/lastlog                                                                            146,292                 36                  0                 36            147,456             100.00
Could not mmap file: /var/log/mail: No such device
/var/log/maillog                                                                                193                  1                  0                  1              4,096             100.00
/var/log/messages                                                                            50,232                 13                  0                 13             53,248             100.00
Could not mmap file: /var/log/ntpstats: No such device
/var/log/secure                                                                              10,254                  3                  0                  3             12,288             100.00
/var/log/wtmp                                                                                 6,144                  2                  0                  2              8,192             100.00
/var/log/yum.log                                                                              7,954                  2                  0                  2              8,192             100.00
---
total cached size: 524,288
           0          0          0

```

だいぶ増えましたね。

ではこの状態でページキャッシュを解放し、その後キャッシュしているファイルを再度確認します。

```bash
# ページキャッシュの解放
$sudo sh -c "echo 1 > /proc/sys/vm/drop_caches"

# /var/log配下のキャッシュの確認
$sudo /usr/local/bin/linux-fincore  --pages=false --summarize --only-cached /var/log/*
filename                                                                                       size        total_pages    min_cached page       cached_pages        cached_size        cached_perc
--------                                                                                       ----        -----------    ---------------       ------------        -----------        -----------
Could not mmap file: /var/log/audit: No such device
Could not mmap file: /var/log/mail: No such device
/var/log/messages                                                                            50,314                 13                 12                  1              4,096               7.69
Could not mmap file: /var/log/ntpstats: No such device
/var/log/secure                                                                              10,889                  3                  2                  1              4,096              33.33
---
total cached size: 8,192
```

ページキャッシュ解放によってファイルのキャッシュが消え、キャッシュサイズも少なくなっているのが確認できました。