ユニットテスト用のPostgreSQLを立ち上げる際に、データフォルダ(PGDATA)をtmpfsに置けたらI/Oが早くなって、テスト時間短縮になるかなっておもって試してみました。テスト用ならば、シャットダウンでデータが消えてしまっても問題ないので。
Windows上で動かしたかったので、今回はVagrantでやりました。各種セットアップはAnsibleでやっています。
上記フォルダで、vagrant up
とすると、CentOS7.3でPostgreSQL10のインストールを行い、tmpfsとしてマウントした/mnt/ram
配下にデータフォルダを作成します。
また、testdb
というDBを作成し、user1
というユーザを作成しています。
pgbenchによるパフォーマンス測定
実際tmpfsにして早くなっているのか見るために、pgbenchを流してみます。
postgresql-contribをインストールします。
[root@localhost ~]# yum install postgresql10-contrib
テスト用のテーブルおよびデータを作成します。
[root@localhost ~]# /usr/pgsql-10/bin/pgbench -i testdb -U user1 Password: NOTICE: table "pgbench_history" does not exist, skipping NOTICE: table "pgbench_tellers" does not exist, skipping NOTICE: table "pgbench_accounts" does not exist, skipping NOTICE: table "pgbench_branches" does not exist, skipping creating tables... 100000 of 100000 tuples (100%) done (elapsed 0.12 s, remaining 0.00 s) vacuum... set primary keys... done.
10クライアントから1000回のトランザクションを発行します。
まずはtmpfsでは無い場合を試してみます。
(https://github.com/onozaty/sandbox/blob/master/postgresql/tmpfs/vars.yml のpostgresql_data_dir
を削除すると、デフォルトのデータフォルダになります)
[root@localhost ~]# /usr/pgsql-10/bin/pgbench -c 10 -t 1000 testdb -U user1 Password: starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 latency average = 10.335 ms tps = 967.558734 (including connections establishing) tps = 967.906273 (excluding connections establishing)
[root@localhost ~]# /usr/pgsql-10/bin/pgbench -c 10 -t 1000 testdb -U user1 Password: starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 latency average = 10.013 ms tps = 998.726630 (including connections establishing) tps = 999.077213 (excluding connections establishing)
2回計りました。tps(1秒間に実行できたトランザクションの数)は900後半でした。
続いてtmpfsの場合。こちらも2回計ってみます。
[root@localhost ~]# /usr/pgsql-10/bin/pgbench -c 10 -t 1000 testdb -U user1 Password: starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 latency average = 7.276 ms tps = 1374.364210 (including connections establishing) tps = 1374.912095 (excluding connections establishing)
[root@localhost ~]# /usr/pgsql-10/bin/pgbench -c 10 -t 1000 testdb -U user1 Password: starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 latency average = 7.619 ms tps = 1312.520754 (including connections establishing) tps = 1313.168002 (excluding connections establishing)
tpsは1300台でした。tmpfsにすることによって、1.3~1.4倍くらいの性能が出ています。ちなみにホストのストレージはSSDなので、これがもっと遅いストレージだと、もう少し差が大きくなるかもしれません。
おわりに
tmpfsにすることによってpgbenchでのパフォーマンスはあがりました。
ただ、tmpfsにしたために毎回起動時にinitdbから始めているので、その分余計な時間がかかることになります。トータルとして時間短縮の効果があるのかを判断しながら、使い分けてみようと思います。