Linux上のメモリーベースファイルシステムtmpfsについてメモ

Summary

  • バックエンドがブロックデバイスではなくスワップ。メモリに乗らなくなったら、スワップ領域を使う。
  • ファイルシステムの容量は指定可能(デフォルトでは RAM の半分)。あとから変更することも可能。
  • 容量はファイルシステム作成時に予め確保されるわけではなく、ファイルシステム上の容量に応じて確保する。
  • リブートすると、すべてのファイルは失われる

Use Case

主な用途

  • anonymous mmap と System V 共有メモリではカーネル内で外からわ見えない形で tmpfs を利用
  • glibc の Posix 共有メモリ/セマフォでは /dev/shm 以下を利用
  • ディスクI/O が大量に発生するようなテストを高速化するために利用
  • キャッシュ/セッションファイルの出力先として利用

tmpfs setup

新規に tmpfs をマウント

# mkdir -pv /tmp/newtmp
# mount -t tmpfs -o size=256m newtmp /tmp/newtmp
# cat /proc/mounts | grep newtmp
newtmp /tmp/newtmp tmpfs rw,relatime,size=262144k 0 0
# mount
/dev/mapper/precise64-root on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /boot type ext2 (rw)
rpc_pipefs on /run/rpc_pipefs type rpc_pipefs (rw)
newtmp on /tmp/newtmp type tmpfs (rw,size=256m)

varnish のチューニング目的

キャッシュサーバの Varnish は、ログなどが出力される作業ディレクトリを tmpfs にして ディスク I/O が発生しないようにすすめている。

3.4 The shared memory log

Varnish’ shared memory log is used to log most data. It’s sometimes called a shm-log, and operates on a round-robin capacity. There’s not much you have to do with the shared memory log, except ensure that it does not cause I/O.
This is easily accomplished by putting it on a tmpfs. This is typically done in ‘/etc/fstab’, and the shmlog is normally kept in ‘/var/lib/varnish’ or equivalent locations. All the content in that directory is safe to delete.
https://www.varnish-software.com/static/book/Tuning.html#the-shared-memory-log

具体的な手順は以下。

# vi /etc/fstab
tmpfs          /var/lib/varnish    tmpfs size=512m    0    0
# mount -a
# mount | grep varnish
tmpfs on /var/lib/varnish type tmpfs (rw,size=512m)

tmpfs Memory Usage

ファイルシステム tmpfs で

  1. ファイルを追加した時
  2. ディスク容量がいっぱいになった時
  3. ファイル容量がRAM を超えた時

の挙動を確認。

1. ファイルを追加した時

$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955        675       3279          0         33        493
-/+ buffers/cache:        148       3806
Swap:         1023          0       1023
$ df -h
Filesystem               Size  Used Avail Use% Mounted on
...
tmp                      512M     0  512M   0% /tmp/tmpfs

RAM に十分な空き容量があるときに400 M のファイルを追加。

$ dd if=/dev/zero of=/tmp/tmpfs/400M bs=100M count=4
4+0 records in
4+0 records out
419430400 bytes (419 MB) copied, 0.228821 s, 1.8 GB/s
$ df -h
Filesystem               Size  Used Avail Use% Mounted on
...
tmp                      512M  400M  112M  79% /tmp/tmpfs
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955       1076       2878          0         33        893
-/+ buffers/cache:        149       3805
Swap:         1023          0       1023

df の結果から /tmp/tmpfs の容量が 400M 増えた。
free の結果から、メモリの使用量が 400M 増え、すべて cached に乗っかっている。Swap は増えていない。

書き込み速度は 1.8 GB/s とかなり高速。

2. ディスク容量がいっぱいになった時

ファイルシステムの空きが 112M しかない状態で 200M のファイルを追加してみる。

$ dd if=/dev/zero of=/tmp/tmpfs/200M bs=100M count=2
dd: writing `/tmp/tmpfs/200M': No space left on device
2+0 records in
1+0 records out
117440512 bytes (117 MB) copied, 0.0995273 s, 1.2 GB/s

117 MB 書き込んだところでディスクフルになった。

$ df -h
Filesystem               Size  Used Avail Use% Mounted on
...
tmp                      512M  512M     0 100% /tmp/tmpfs
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955       1188       2766          0         33       1005
-/+ buffers/cache:        149       3805
Swap:         1023          0       1023

df の結果から、 /tmp/tmpfs のディスク使用量が 100% とわかる。

free の結果から、実際に書き込み成功した分だけメモリ使用量が増えている。

ファイルの削除

ディスクフルな状態で 400M のファイルを空にする。

$ cat /dev/null  > /tmp/tmpfs/400M
$ df -h
Filesystem               Size  Used Avail Use% Mounted on
...
tmp                      512M  112M  400M  22% /tmp/tmpfs
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955        788       3166          0         33        605
-/+ buffers/cache:        149       3805
Swap:         1023          0       1023

free の結果から、メモリーの used と cached が 400M ごっそり解放された。
また df の結果から、 /tmp/tmpfs の空き容量も 400M 増えている。

3. ファイル容量が RAM を超えた時

最後に RAM を超えた時のスワップアウトを確認。

$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955       3046        908          0         33       2863
-/+ buffers/cache:        149       3805
Swap:         1023          0       1023
$ df -h
Filesystem               Size  Used Avail Use% Mounted on
...
tmp                      2.0G  2.0G     0 100% /tmp/tmpfs
tmp                      2.0G  500M  1.5G  26% /tmp/tmpfs2

4G の RAM があって、約1G 空きがある。tmpfs だけで 2.5G 使っている。
さらに 1G のファイルを tmpfs 上に作成する。

$ dd if=/dev/zero of=/tmp/tmpfs2/1.0G bs=100M count=10
10+0 records in
10+0 records out
1048576000 bytes (1.0 GB) copied, 16.4084 s, 63.9 MB/s
$ free -m
             total       used       free     shared    buffers     cached
Mem:          3955       3638        316          0         29       2641
-/+ buffers/cache:        967       2988
Swap:         1023       1023          0

free の結果から、メモリーの used は 600M 程度しか増えず、これまで使っていなかったスワップを 100% 使っている。
また、これまでは書き込み速度が 1.0GB/s を大幅に超えていたのに、 63.9 MB/s にまで激減している。

比較のためにメモリを解放した後で ext4 で同じ操作をすると 115 MB/s だった。


$ dd if=/dev/zero of=1g bs=100M count=10
10+0 records in
10+0 records out
1048576000 bytes (1.0 GB) copied, 9.13518 s, 115 MB/s

disk io の統計情報の取得

ディスク I/O の統計情報は以下のプログラムを使うと便利。

  • iostat(sysstat パッケージの1プログラム)
  • sar
  • iotop

References

Leave a comment