カテゴリー
Computer Database Development Linux

PostgreSQLを使うならZFS

(Last Updated On: 2018/09/02)

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版)

参考:FedoraでZFSを使う

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のキャッシュもミラーリング可能で安全に利用できます。