PostgreSQLを使うならZFSで決まりです。数値で明らかです。ZFS以外を使うのは論外なくらいの性能差があります。
TL;DR;
PostgreSQL(他のデータベースでも)はZFSで使いましょう。
ベンチマーク環境
ハードウェア
- CPU: Xeon E3-1230 v5 @ 3.40GHz
- MEM: 32GB ECC
- HDD: HGST 7200 rpm HDD – HDS721010CLA332
- SSD: Crucial CT250MX200SSD
HDDは古く、SDDの性能も良いとは言えない物です。
ソフトウェア
- OS: Fedora 27
- Kernel: 4.14.8-300.fc27.x86_64
- ZFS: ZFS on Linux 0.7.5 – zfs-0.7.5-1.fc27.x86_64
- PostgreSQL 10 (2017/12/26 git版)
pgbenchのオプション
- スケールファクタ 100
- クライアント 100
- スレッド数 50
- pgbench結果は揺れが大きいので、3回実行して最大の結果を掲載
postgresql.confの変更箇所
- なし
ZFSオプション
- atime=off
- relatime=on
- recordsize=8K
- HDDは1台、ディスク全体をZFSに利用
- ARC(メモリキャッシュ)サイズは8GBに制限
- ZIL logキャッシュ(ZFSログの書き込みキャッシュ)はSSDの2GBを利用
- L2ARCなし(SSDのデータキャッシュなし)
[yohgaki@kiri testvol]$ zpool status testvol pool: testvol state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM testvol ONLINE 0 0 0 ata-Hitachi_HDS721010CLA332_JP6940HZ0934JF ONLINE 0 0 0 logs ata-Crucial_CT250MX200SSD1_1618127BA553-part7 ONLINE 0 0 0 errors: No known data errors
ベンチマーク:RAMディスク
/tmp (tmpfsはRAMディスク) で実行。これ以上の性能は見込めない。
[yohgaki@kiri tmp]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 1133156 latency average = 5.299 ms tps = 18871.500398 (including connections establishing) tps = 18882.329623 (excluding connections establishing)
参考ベンチマーク:Ext4 + fsync=off
PostgreSQLはfsync=offに設定するとRAMディスクと同等の性能を実現できます。このため、PostgreSQLでRAMディスクを使う意味はあまりありません。
[yohgaki@kiri mnt]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 1090771 latency average = 5.506 ms tps = 18163.326168 (including connections establishing) tps = 18178.052501 (excluding connections establishing)
ベンチマーク:Ext4
[yohgaki@kiri mnt]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 20974 latency average = 292.055 ms tps = 342.401428 (including connections establishing) tps = 342.443617 (excluding connections establishing)
ベンチマーク:XFS
[yohgaki@kiri mnt]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 17703 latency average = 340.007 ms tps = 294.111509 (including connections establishing) tps = 294.155913 (excluding connections establishing)
ベンチマーク:Btrfs
[yohgaki@kiri mnt]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 37261 latency average = 162.495 ms tps = 615.404451 (including connections establishing) tps = 615.487237 (excluding connections establishing)
ベンチマーク:ZFS (キャッシュなし)
キャッシュなしもでZFSのパフォーマンスは約2倍の性能でExt4, XFSを圧倒しています。BtrfsはZFSには少し及びません。
[yohgaki@kiri testvol]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 38873 latency average = 155.310 ms tps = 643.875143 (including connections establishing) tps = 643.977799 (excluding connections establishing)
ベンチマーク:ZFS + Logキャッシュ
SSDでZIL(ZFS Intent Log)をキャッシュすると、文字通り他のファイルシステムとは桁違い、XFSとは25倍以上、の性能差になります。HDDの信頼性とSSDの速さの良いところ取りです。
[yohgaki@kiri testvol]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 459698 latency average = 13.061 ms tps = 7656.160139 (including connections establishing) tps = 7658.075438 (excluding connections establishing)
参考ベンチマーク:SATA5台のRAIDZ + Logキャッシュ
一般にIOPSを要求される場合、ストライピング(RAIDZ)は不利とされています。しかし、このシステムの場合、以下のようなベンチマーク結果になります。
HDDは5400rpmの静音型ですが、新しいHDD、サイズが3TB(HGSTは1TB)である点が異なります。あくまで参考数値です。
[yohgaki@kiri ~]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 523853 latency average = 11.462 ms tps = 8724.291624 (including connections establishing) tps = 8725.956144 (excluding connections establishing)
追記:動作をよく見てみると単一のディスクでは単純にスループットが頭打ちになり、よりスループットが大きくなるRAIDZの方が高性能になったという形でした。DBだからIOPS重視でミラーで、と安直に決めない方がよいです。
参考ベンチマーク:SSD上のBtrfs
SSDにログをキャッシュしているから速いのでは?と思った方も多いと思います。ファイルシステムとして高性能だったBtrfsはこのシステムのルートファイルシステムになっています。SSD+Btrfsの参考として掲載します。ZFSには少し及ばない結果でした。
[yohgaki@kiri mnt]$ /usr/local/pgsql-10/bin/pgbench -c 100 -j 50 -T 60 test starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 100 query mode: simple number of clients: 100 number of threads: 50 duration: 60 s number of transactions actually processed: 425377 latency average = 14.117 ms tps = 7083.480074 (including connections establishing) tps = 7084.581074 (excluding connections establishing)
まとめ
環境によってベンチマーク結果は異なりますが、ほぼ全ての環境でPostgreSQLを使うならZFSで決まりでしょう。
ZFS on Linuxはデフォルトで搭載メモリの半分をARC(データキャッシュ)に使います。PostgreSQLのバッファキャッシュやワークメモリも必要です。多くの場合、半分よりも少ないメモリをARCに割り当てた方が良いでしょう。今時はメモリは十分にあると思います。足りなければ追加も簡単です。
ZFSとBtrfsはファイルシステムのデータ領域のチェックサムを取って整合性を維持しています。ZFSでLogをキャッシュする場合、SSDの信頼性が気になるかも知れません。Logのキャッシュもミラーリング可能で安全に利用できます。