tmpfsがどれだけ早いのか検証してみた


# tmpfsとは？
tmpfsはメモリ上に作成できるファイルシステムのこと。メリットとしては、高速にアクセスできることがある。しかし、その反面、サーバリブート時にtmpfsのファイルシステム内にあるファイルは削除されてしまう。永続的に保管するのではなく、キャッシュ用途で使用する。
参考：https://linuc.org/study/knowledge/441/

# tmpfsを利用することで読み込み書き込みがどれくらい変わるのか調べてみる！

1. diskへの書き込みとtmpfsをマウントしたディレクトリ内のファイルへの書き込みの速度を比較してみる。
2. 続いて読み込みについても同様に比較してみる。

# 環境
virtualbox上のcentos7で実施しました！

```
[root@my_learning_server01 ~]# cat /etc/system-release
CentOS Linux release 7.7.1908 (Core)
```

# 準備
の前に、この記事はほぼ[こちら](https://blog.katsubemakito.net/linux/ramdisk-tmpfs)の記事を参考にしてますこちらの記事を元にコマンドの使い方などを補足してます！

作業用のディレクトリの作成して、tempfs用のディレクトリ（test_tmpfs）をtmpfsを使ってマウントする。
dfコマンドによりtest_tmpfsがマウントされていることを確認。

```
[root@my_learning_server01 mnt]# mkdir test_disk
[root@my_learning_server01 mnt]# mkdir test_tmpfs
[root@my_learning_server01 mnt]# df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
devtmpfs                  484M     0  484M    0% /dev
tmpfs                     496M     0  496M    0% /dev/shm
tmpfs                     496M  6.8M  489M    2% /run
tmpfs                     496M     0  496M    0% /sys/fs/cgroup
/dev/mapper/centos-root   6.2G  1.2G  5.1G   19% /
/dev/sda1                1014M  137M  878M   14% /boot
tmpfs                     100M     0  100M    0% /run/user/0
[root@my_learning_server01 mnt]# mount -t tmpfs /dev/shm test_tmpfs
[root@my_learning_server01 mnt]# df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
devtmpfs                  484M     0  484M    0% /dev
tmpfs                     496M     0  496M    0% /dev/shm
tmpfs                     496M  6.8M  489M    2% /run
tmpfs                     496M     0  496M    0% /sys/fs/cgroup
/dev/mapper/centos-root   6.2G  1.2G  5.1G   19% /
/dev/sda1                1014M  137M  878M   14% /boot
tmpfs                     100M     0  100M    0% /run/user/0
/dev/shm                  496M     0  496M    0% /root/mnt/test_tmpfs
```

- mountコマンド
`mount デバイス マウントポイント`
> 例えば「/dev/sdb1」というデバイスを「/usr/local/data1」というマウントポイントにマウントしたい場合、「mount /dev/sdb1 /usr/local/data1」と指定します
https://www.atmarkit.co.jp/ait/articles/1802/15/news035.html
-tはマウントするファイルシステムを指定している。今回はtmpfsを使用するため上のコマンドを使う。

# 1.diskとtmpfsの書き込みを比較
書き込み読み込みの速度を調べるためのコマンドとしてddコマンドを使用する。
以下のような結果がでた。
上がdiskへの書き込み実行結果で下がtmpfsへの書き込み実行結果となる。
約6倍tmpfsの方が書き込み速度が早いことがわかった。
ちなみにこの比較を100回やってみた平均は約3.5倍でした。

```
[root@my_learning_server01 mnt]# dd if=/dev/zero of=/root/mnt/test_disk/disk_file bs=64k count=1k conv=fdatasync
1024+0 レコード入力
1024+0 レコード出力
67108864 バイト (67 MB) コピーされました、 0.367838 秒、 182 MB/秒
[root@my_learning_server01 mnt]# dd if=/dev/zero of=/root/mnt/test_tmpfs/tmpfs_file bs=64k count=1k conv=fdatasync
1024+0 レコード入力
1024+0 レコード出力
67108864 バイト (67 MB) コピーされました、 0.0607435 秒、 1.1 GB/秒
```

- dfコマンド
`dd if=/dev/zero of=/root/mnt/test_disk/disk_file bs=64k count=1k conv=fdatasync`
データのコピーや変換の処理をするコマンド。if引数に指定した内容をof引数にコピーする。
bs引数✖️count引数　分のサイズのファイルが作成されます。出力（なぜかエラー出力）に転送速度や処理速度が出てくるので、今回はこのddコマンドを比較のためのコマンドとして使いました。

# 2. 続いて読み込みについても同様に比較してみる。
読み取りに関しても同様にddコマンドを実施して比較してみます。
書き込みほどの差は出なかったものの、tmpfsの方が早い結果となりました。

```
[root@my_learning_server01 mnt]# dd if=/root/mnt/test_disk/disk_file of=/dev/null bs=64k count=1k
1024+0 レコード入力
1024+0 レコード出力
67108864 バイト (67 MB) コピーされました、 0.00987859 秒、 6.8 GB/秒
[root@my_learning_server01 mnt]# dd if=/root/mnt/test_tmpfs/tmpfs_file of=/dev/null bs=64k count=1k
1024+0 レコード入力
1024+0 レコード出力
67108864 バイト (67 MB) コピーされました、 0.00954804 秒、 7.0 GB/秒
```
- 読み取りの場合のddコマンドについて
読み取りの場合、ifでは先ほど書き込みで作成したファイルを指定し、ofには/dev/nullを指定している。つまり、先ほど作成したファイルを読み取って/dev/nullに放り込むという処理をしている。ほぼ読みとりのみをしていると言えます。

ちなみに読み取りも100回実施したところ、約0.9倍となりtmpfsの方が遅い結果になってしまいました。。
なぜかはわからないのです。。。
実行結果は以下の通りでした。
result: 0.946945
disk avg:0.00741719
tmpfs avg:0.00783275

# 参考
https://blog.katsubemakito.net/linux/ramdisk-tmpfs
https://armadillo.atmark-techno.com/howto/mounting-tmpfs

# おまけ
最近、shellscriptを勉強しようと思い、とりあえずスクリプト作ってみるということをしています。。
今回、ddコマンドを連続で実行し、diskとtmpfsとの差を出すスクリプトを作ってみました。100回実行して平均を出したりというのはこのスクリプトを使っていました。
ご参考までに記載しておきます！

```

#!/bin/bash

# $1 write or read
# $2 disk file
# $3 tmpfs file
# $4 roop count

if [ -z $4 ]; then
  COUNT=9
else
  COUNT=$4
fi

result_disk=()
result_tmpfs=()
for i in `seq 0 $COUNT`
do
  if [ $1 = "write" ]; then
    result_disk[$i]=`dd if=/dev/zero of=$2 bs=64k count=1k conv=fdatasync |& tail -n 1 |awk -F " " '{print $6}'`
  elif [ $1 = "read" ]; then
    result_disk[$i]=`dd if=$2 of=/dev/null bs=64k count=1k |& tail -n 1 |awk -F " " '{print $6}'`
  else
    echo "parameter1 is only select read or write" && exit 1
  fi

  if [ $1 = "write" ]; then
    result_tmpfs[$i]=`dd if=/dev/zero of=$3 bs=64k count=1k conv=fdatasync |& tail -n 1 |awk -F ' ' '{print $6}'`
  elif [ $1 = "read" ]; then
    result_tmpfs[$i]=`dd if=$3 of=/dev/null bs=64k count=1k |& tail -n 1 |awk -F ' ' '{print $6}'`
  fi
done

sum_disk=0
sum_tmpfs=0
for i in `seq 0 $COUNT`
do
  num_disk=${result_disk[$i]}
  num_tmpfs=${result_tmpfs[$i]}
  sum_disk=`awk "BEGIN {print $sum_disk+$num_disk}"`
  sum_tmpfs=`awk "BEGIN {print $sum_tmpfs+$num_tmpfs}"`
done
ROOP=${#result_disk[@]}
result=`awk "BEGIN {print $sum_disk/$sum_tmpfs}"`
avg_disk_result=`awk "BEGIN {print $sum_disk/$ROOP}"`
avg_tmpfs_result=`awk "BEGIN {print $sum_tmpfs/$ROOP}"`
echo "result: "$result
echo "disk avg:"$avg_disk_result
```