CoreOSのファイルシステムの変更に伴うパフォーマンスの変化(または、さくらのクラウド上でのファイルシステムの性能への影響)

はじめに

 CoreOSがBtrfsからext4ファイルシステムを切り替えて早数か月。
 さくらのクラウド上で動作させた際に、ファイルシステムの変更がディスクIOの性能にどれぐらい影響するか測ってみました。

 測定には、Oracle ORIONを使用しました。
 Oracle ORIONには以下の特徴があります。

With the goal of closely mimicing the Oracle database, ORION generates a synthetic I/O workload, using the same I/O software stack as Oracle. ORION can be configured to generate a wide range of I/O workloads, including ones that simulate OLTP and data warehouse workloads.

 Oracle ORIONを使った理由は、以下の記事で「マルチスレッドで負荷を掛けた際にディスクIOの性能が劣化する可能性」が示唆されているため、その辺りをシミュレーション出来るものを使おうと思ったためです。

使用環境

データセンター(?)
サーバ
サーバA サーバB
CPU 2コア 同左
メモリ 2G 同左
ディスク 標準 60G 同左
ハイパーバイザ SAKURA Internet [CLOUD SERVICE 2.1] SAKURA Internet [CLOUD SERVICE 2.0]
収容ホスト名 sac-is1b-sv061 sac-is1b-sv041
ストレージ sac-is1b-iscsi3-st02 sac-is1b-iscsi3-st04
OS CoreOS 557.2.0 CoreOS 593.0.0
Linux Kernel 3.18.1 3.18.6
Docker Docker version 1.4.1, build 5bc2ff8-dirty Docker version 1.5.0, build a8a31ef-dirty
Docker Storage Driver Storage Driver: btrfs
Build Version: Btrfs v3.17.1
Library Version: 101
Storage Driver: overlay
Backing Filesystem: extfs

 OSは、Btrfsを採用しているバージョンで最も新しそうなものと、ext4を採用しているOSで最も古そうなものを採用しました。
 ただ、うまくOSのイメージをビルドできないものもいくつかあったので、ビルドできるものを使用しています。

 CPUを2コアにしていますが、Oracle ORIONを起動してCPUの使用状況をみたところ1コアしか使っていないようでした。
 多分2コアにする必然性はなかったと思われます。

 ディスク容量を60Gとっているのは、書き込みテストの都合です。
 Btrfs上で書き込みテストをしたところ、コピーオンライトとの兼ね合いなのか、やたらディスク領域を消費したため、大き目のディスク領域を用意しました。

 ディスクイメージは、ローカルでVMware用のものを用意したあと、さくらのクラウドアーカイブで使用できる形式に変換して使用しました。
 変換方法は以下を参照。

 さくらのクラウドのパブリックアーカイブにはCoreOS 367.1しかなく、これを元に起動したサーバをバージョンアップしても、ファイルシステムはバージョンアップ前と同様、Btrfsになるためです。

負荷生成ソフト

Oracle ORION Version 11.1.0.7.0

測定のパターン

Oracle ORION の負荷の生成のパターン
負荷のパターン I/Oリクエストサイズ 起動時のパラメータ
read 100%
write 0%
8K ./orion_linux_x86-64 -run advanced -testname orion-test -size_small 8 -num_disks 4
read 80%
write 20%
同上 ./orion_linux_x86-64 -run advanced -testname orion-test -write 20 -size_small 8 -num_disks 4
read 0%
write 100%
同上 ./orion_linux_x86-64 -run advanced -testname orion-test -write 100 -size_small 8 -num_disks 4

各パターンとも毎回以下のようなコマンドで約20Gのデータを用意してから実行しました。

core@localhost ~ $ dd if=/dev/zero of=/home/core/orion-test/testfile-010.dbf bs=1M count=10240
core@localhost ~ $ dd if=/dev/zero of=/home/core/orion-test/testfile-020.dbf bs=1M count=10240
Oracle ORION 起動環境のパターン
パターン コンテナ上のOS 使用サーバ
CoreOS 557.2.0 ホストで読み書き(Docker無) - サーバA
CoreOS 557.2.0 Docker使用 マウントしたホスト側ディレクトリで読み書き CentOS 7.0 同上
CoreOS 557.2.0 Docker使用 コンテナ内のディレクトリで読み書き 同上 同上
CoreOS 593.0.0 ホストで読み書き(Docker無) - サーバB
CoreOS 593.0.0 Docker使用 マウントしたホスト側ディレクトリで読み書き CentOS 7.0 同上
CoreOS 593.0.0 Docker使用 コンテナ内のディレクトリで読み書き 同上 同上

測定期間と測定値について

測定期間

2015/05/03(日)〜2015/05/06(水)

測定結果

 5回計測して中央値を使用しています。

read 100% write 0%

read 80% write 20%

read 0% write 100%

考察

read 100% write 0%

 意外とBtrfsは遅くないです。以下のサイトによれば、小さいブロックサイズならばBtrfsはext4よりも速いようなので、まあ、そんなものなのかもしれない。

 ext4について、コンテナ内のディレクトリから読んだ方が速いのですが、これは原因不明。
 overlayfsになにか秘密がありそうなのですが…。

read 80% write 20%

 取ってみたものの、特にコメントなしです。

read 0% write 100%

 負荷に関係なく、Small IOにおいて、ext4の書き込みが一定です。
 これは、ext4がioバリア有でマウントされているためだと思われます。
 マウントの状況を取得すると以下のようになっております。

core@localhost /etc/systemd $ cat /etc/mtab
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
devtmpfs /dev devtmpfs rw,nosuid,size=1014736k,nr_inodes=253684,mode=755 0 0
securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0
tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_cls,net_prio 0 0
cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
/dev/vda9 / ext4 rw,relatime,data=ordered 0 0
/dev/vda3 /usr ext2 rw,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
tmpfs /tmp tmpfs rw 0 0
tmpfs /media tmpfs rw,nosuid,nodev,noexec,relatime 0 0
hugetlbfs /dev/hugepages hugetlbfs rw,relatime 0 0
mqueue /dev/mqueue mqueue rw,relatime 0 0
/dev/vda6 /usr/share/oem ext4 rw,nodev,relatime,commit=600,data=ordered 0 0

さいごに

 CoreOS、ext4のをioバリア有りでマウントしているとは。
 これなら個人的にはBtrfsのままでよかったな、なんて思います。