Edited at

EXT4 vs XFS vs Btrfs vs ZFSをfioでベンチマークを取ってみました。

More than 5 years have passed since last update.


概要

CentOS7のデフォルトのファイルシステムがXFSとなりました。

mkfsコマンドでも、minix, xfs, btrfsが使えるようになりました。

そこで気になるファイルシステムを色々調べ、ベンチマークを自分なり取ってみました。

多少なりともご参考になればと思います。


色々なファイルシステム

こちらをご参考ください。

http://qiita.com/sion_cojp/items/c8e015db39ddbf43012e


それぞれファイルシステムを作ってみる


  • 今回の環境は


    • CentOS6(ホスト)


      • 4Core, MEM:32G, HDD:300G



    • CentOS7(ゲスト。こちらで計測しております。)


      • vCPU *1, MEM:4G, HDD:40G





  • 容量が少なかったため、btrfsのベンチマークが終わった後、zfsにファイルシステムを変更し検証をしております。

### zfsのインストール

$ sudo yum localinstall --nogpgcheck http://download.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-0.2.noarch.rpm
$ sudo yum localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release.el7.noarch.rpm
$ sudo yum install kernel-devel zfs

# spl zfsをカーネルモジュールにビルド
$ dkms status
spl, 0.6.3: added
zfs, 0.6.3: added
$ dkms install -m spl -v 0.6.3
Error! echo
Your kernel headers for kernel 3.10.0-123.el7.x86_64 cannot be found at
/lib/modules/3.10.0-123.el7.x86_64/build or /lib/modules/3.10.0-123.el7.x86_64/source.

# バージョンが違うと言われたので、入れ変えましょう
$ rpm -qa | grep kernel-devel
kernel-devel-3.10.0-123.6.3.el7.x86_64
$ rpm -e --nodeps kernel-devel-3.10.0-123.6.3.el7.x86_64
$ wget ftp://mirror.switch.ch/pool/4/mirror/scientificlinux/7rolling/x86_64/os/Packages/kernel-devel-3.10.0-123.el7.x86_64.rpm
$ rpm -ivh kernel-devel-3.10.0-123.el7.x86_64.rpm

# 再度ビルド
$ dkms install -m spl -v 0.6.3
DKMS: install completed.
$ dkms install -m zfs -v 0.6.3
DKMS: install completed.

# うまくいきました。念のため確認しましょう。
$dkms status
spl, 0.6.3, 3.10.0-123.el7.x86_64, x86_64: installed
zfs, 0.6.3, 3.10.0-123.el7.x86_64, x86_64: installed

### パーティション作成。雑に書いてます。。
$ sudo fdisk /dev/vda
n
e
enter enter
p

n
l
enter +5G
p
*3回

コマンド (m でヘルプ): p
/dev/vda1 * 2048 411647 204800 83 Linux
/dev/vda2 411648 45475839 22532096 8e Linux LVM
/dev/vda3 45475840 83886079 19205120 5 Extended
/dev/vda5 45477888 55963647 5242880 83 Linux
/dev/vda6 55965696 66451455 5242880 83 Linux

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

# サーバ再起動
$ reboot

### ext4のファイルシステムを作成します

$ sudo mkfs.ext4 /dev/vda5
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
327680 inodes, 1310720 blocks
65536 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1342177280
40 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

### xfsのファイルシステムを作成します 

$ sudo mkfs.xfs /dev/vda6
meta-data=/dev/vda6 isize=256 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0

### btrfsのファイルシステムを作成します。

$ sudo mkfs.btrfs /dev/vda7
WARNING! - Btrfs v3.12 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using
Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
fs created label (null) on /dev/vda7
nodesize 16384 leafsize 16384 sectorsize 4096 size 5.00GiB
Btrfs v3.12

### (btrfsの検証が終わったら)zfsのファイルシステムを作成します。

# zfsのストレージプール作成
$ zpool create zfs /dev/vda7
$ df | grep zfs
zfs 5128576 0 5128576 0% /zfs

# zfsのファイルシステム作成
$ zfs create zfs/test
$ zfs listcd
NAME USED AVAIL REFER MOUNTPOINT
zfs 148K 4.89G 32.5K /zfs
zfs/test 30K 4.89G 30K /zfs/test

### ちなみに削除するときは
$ umount zfs/test
$ zfs destroy zfs/test

$ umount zfs
$ zpool destroy zfs

### マウントしていきます。

$ mkdir -p {ext4, xfs, brtfs}
$ blkid | grep vda[5-7]
/dev/vda5: UUID="○○○" TYPE="ext4"
/dev/vda6: UUID="×××" TYPE="xfs"
/dev/vda7: UUID="△△△" UUID_SUB="□□□" TYPE="btrfs"

### 3行追加しましょう
$ sudo vi /etc/fstab
UUID="○○○" /ext4 ext4 defaults 1 2
UUID="×××" /xfs xfs defaults 1 2
UUID="△△△" /btrfs btrfs defaults 1 2

$ df -Tmh | grep "vda[5,6,7]\|ファイル"
ファイルシス タイプ サイズ 使用 残り 使用% マウント位置
/dev/vda5 ext4 4.8G 20M 4.6G 1% /ext4
/dev/vda6 xfs 5.0G 33M 5.0G 1% /xfs
/dev/vda7 btrfs 5.0G 320K 4.5G 1% /btrfs


1.2Gのファイルをコピー & 削除してみる(timeコマンドを用いて測定)

cp real time
rm real time

ext4
0m9.723s (124MB/s)
0m1.905s(631MB/s)

xfs
0m7.013s (171MB/s)
0m1.258s(960MB/s)

btrfs
0m8.505s (141MB/s)
0m1.329s(863MB/s)

zfs
1m40.611s(12MB/s)
0m2.589s(480MB/s)


  • 削除が遅いと言われたxfsだけど、全然速い。

  • 基本的なseq/read,writeが圧倒的に早いのだろう。

  • zfsはメモリが少ないのかめちゃくちゃ遅い。


fioでベンチマーク測定する

### fioのインストール

$ sudo yum install -y libaio-devel
$ wget http://pkgs.repoforge.org/fio/fio-2.1.7-1.el7.rf.x86_64.rpm
$ rpm -ivh fio-2.1.7-1.el7.rf.x86_64.rpm

### fioコマンドを打つ時は、各ファイルシステムのディレクトリに移動してください。
cd {/ext4, /xfs, /brtfs, /zfs/test}

### 実行コマンド。seq,random/read,write を図ります。
### bs=4K
$ fio -rw=read -bs=4k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=seqread
$ fio -rw=write -bs=4k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=seqwrite
$ fio -rw=randread -bs=4k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=randread
$ fio -rw=randwrite -bs=4k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=randwrite

### bs=16K
### 実行コマンド。seq,random/read,write を図ります。
$ fio -rw=read -bs=16k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=seqread
$ fio -rw=write -bs=16k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=seqwrite
$ fio -rw=randread -bs=16k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=randread
$ fio -rw=randwrite -bs=16k -size=100m -numjobs=40 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=randwrite

fioの詳細はこちら

オプション
詳細

bs
ブロックサイズの指定。
今回はlinuxのデフォルトブロックサイズとMySQLを想定して4Kと16K

size
この測定で読み書きするファイルサイズ

numjobs
ジョブのクローン数。同時にいくつIOを発生させるか。

rutime
測定時間(秒)

direct
ダイレクト転送。1は有効にする

invalidate
バッファキャッシュ。1は無効(デフォルト)

ioengine
利用するIOエンジン。liabaioはLinuxカーネル内で実装されてる非同期IO

iodepth
queue depthともいう。どれくらい平行して非同期読み書きを行うか。
一度に受け取れるコマンドの数。

ipdepth_batch
IO数をどれだけ出すか。基本はiodepthと同じ値にする。

ipdepth_batch_complete
どれだけのIOをすぐに回収するか。
デフォルトは1で、理由はカーネルから回収するプロセスの最小IO=1を求めるから。

group_reporting
結果をjob単位でなく、グループ単位で出力


測定結果(IOPS)


  • 3G(size)のファイル1個(numjobs)でベンチマークしても大差は全然ないので、100Mのファイル40個でいってみます。

  • 皆さんが運用してるMySQLのページサイズを設定して測っても良いでしょう

  • $ mysql -uroot -e 'show status' | grep page_size


bs=4K

※単位はIOPSです。

ext4(4K)
xfs(4K)
btrfs(4K)
zfs(4K)

seq-read
6155
17434
10631
測定不能

seq-write
639
1192
759
測定不能

random-read
1609
1438
1532
測定不能

random-write
188
188
191
測定不能


bs=16K

※単位はIOPSです。

ext4(16K)
xfs(16K)
btrfs(16K)
zfs(16K)

seq-read
6864
6502
3036
測定不能

seq-write
1085
1082
462
測定不能

random-read
1086
1208
387
測定不能

random-write
172
93
82
測定不能


fioの結果をみて


  • 4KだとIOPSは遅め。ただ、ブロックサイズが変わっても、IOPSがさほど変わらないext4は安定してるといえる。

  • xfsは4Kだと爆速。ブロックサイズが大きくなると遅くなっていく傾向でした。

  • btrfsもxfsと似ているが、ブロックサイズが大きくなると最悪な結果になってしまいました。

  • zfsは遅い。とにかく遅い。メモリが足りなかったのかもしれないが、時間がめっちゃかかりそうだったので測定不能にしました。


私なりの総評

ファイルシステムが混在するのは出来る限り避けたい。

というのをベースにするとXFSが良い。


  • 一般的にlinuxのブロックサイズは4kなので、xfsのほうが良さそう。




  • MySQLでページサイズ大きめならext4でもよい。xfsだとブロックサイズが大きくなるにつれて遅くなってる傾向が見える。


    • ランダムアクセスで劣って入る部分は、あえてフルテーブルスキャンを使ってインデックスを利用しない方法をとってもよい。



  • ただ、SSDやらioDriveだと、処理が爆速になるので、そのときはxfsを選ぶのが良いでしょう。



  • ストレージ系にxfsは無謀。(fsck時に1TBにつきメモリ1GBとか論外。)
    (修正されたという情報もあります。http://xfs.org/index.php/XFS_status_update_for_2010#XFS_status_update_for_January_2010)



  • ストレージ系にはZFSやBtrfsを組み込むと良い。将来的におすすめなのはZFSかね。


    • 重複ファイル節約機能や、チェック周りが安心とか嬉しい。今後開発でさらに良くなると思うので、動向を伺いたいですね。

    • しかし現状ではZFSはまだシステムに組み込むのは難しい。内容としては素晴らしい機能を組み込むので開発に期待。