この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ウィスキー、シガー、パイプをこよなく愛する大栗です。
最近 RDBMS のパフォーマンスを計測する機会があったので、手順をまとめておこうと思います。以前のエントリなどではJdbcRunnerを使用することが多かったのですが、今回は別のツールである HammerDB を使用しました。このエントリーでは PostgreSQL を対象としたベンチマークを実施します。
MySQL 版も書きました。MySQL での手順を確認したい方は、以下のエントリを御覧ください。
HammerDB
HammerDB は[Steve Shaw]氏を中心として開発を行っており、トランザクション処理性能評議会(TPC)がサポートしているオープンソースのデータベースベンチマークアプリケーションです。HammerDB では世界的に利用者が多い以下のデータベースをサポートしています。
- Oracle (TimesTen)
- SQL Server
- Db2
- MySQL (Amazon Aurora)
- PostgreSQL (ExterpriseDB / Amazon Redshift / Greenplum)
- MariaDB
サポートしているベンチマーク指標は以下のものになります。将来的に TPC-E をサポートする計画もあるようです。
- TPROC-C
- TPC-C の派生ベンチマーク
- オンライントランザクション処理 (OLTP) のベンチマークで卸売業者の業務モデルを模しています
- 詳細はドキュメントを参照
- TPROC-H
- TPC-H の派生ベンチマーク
- 意思決定支援ベンチマークで、大量のデータを調査し、複雑なクエリを実行します
- 詳細はドキュメントを参照
やってみる
注意
ベンチマーク結果は、データベース・ソフトウェアや提供環境により実施や公開が制限されている場合があります。例えば Oracle ではベンチマークテストの結果は公開を禁じられています。AWS では AWS Service Terms の 1.8 に準じる必要があります。
事前準備
ベンチマークの環境は以下としています。
- HammerDB : version 4.3
- クライアント環境
- AMI : ami-08a8688fb7eacb171 (amzn2-ami-kernel-5.10-hvm-2.0.20220207.1-x86_64-gp2)
- OS : Amazon Linux 2
- psql (PostgreSQL) 13.3
- データベース環境
- PostgreSQL 13
また、クライアントからデータベースへのネットワーク接続が問題なく出来ることとします。
Extras Library の PostgreSQL 13 を有効化します。
$ sudo amazon-linux-extras enable postgresql13
postgresql
とpostgresql-devel
をインストールします。
$ sudo yum clean metadata && sudo yum install -y postgresql postgresql-devel
HammerDB をダウンロードします。
$ wget https://github.com/TPC-Council/HammerDB/releases/download/v4.3/HammerDB-4.3-Linux.tar.gz
ダウンロードしたファイルを解凍します。
$ tar xvfz HammerDB-4.3-Linux.tar.gz
解凍したディレクトリへ移動します。
$ cd HammerDB-4.3
HammerDB の CLI を起動します。
$ ./hammerdbcli
librarycheck
コマンドでライブラリのインストール状況をチェックします。出力される結果の中で、PostgreSQL の内容がSuccess
になっていることを確認します。
hammerdb>librarycheck
Checking database library for Oracle
・
・
・
Checking database library for PostgreSQL
Success ... loaded library Pgtcl for PostgreSQL
・
・
・
一旦 HammerDB CLI を終了します。
hammerdb>exit
TPROC-C の実施
TPC-C の派生ベンチマークである TPROC-C を実行してみます
HammerDB の CLI を起動します。
$ ./hammerdbcli
対象データベースを PostgreSQL に設定し、ベンチマークを TPROC-C に設定します。
hammerdb>dbset db pg
hammerdb>dbset bm TPROC-C
設定内容を確認します。この内容について必要な項目を設定していきます。
hammerdb>print dict
Dictionary Settings for PostgreSQL
connection {
pg_host = localhost
pg_port = 5432
pg_sslmode = prefer
}
tpcc {
pg_count_ware = 1
pg_num_vu = 1
pg_superuser = postgres
pg_superuserpass = postgres
pg_defaultdbase = postgres
pg_user = tpcc
pg_pass = tpcc
pg_dbase = tpcc
pg_tspace = pg_default
pg_vacuum = false
pg_dritasnap = false
pg_oracompat = false
pg_storedprocs = false
pg_partition = false
pg_total_iterations = 10000000
pg_raiseerror = false
pg_keyandthink = false
pg_driver = test
pg_rampup = 2
pg_duration = 5
pg_allwarehouse = false
pg_timeprofile = false
pg_async_scale = false
pg_async_client = 10
pg_async_verbose = false
pg_async_delay = 1000
pg_connect_pool = false
}
接続先のホスト名と接続ポートを設定します。
hammerdb>diset connection pg_host xxxxxxxxxxxx.example.com
hammerdb>diset connection pg_port 99999
管理者ユーザ名、管理者パスワード、初期接続先のデータベースを入力します。
hammerdb>diset tpcc pg_superuser XXXXX
hammerdb>diset tpcc pg_superuserpass XXXXXXXXXXXXXXXX
hammerdb>diset tpcc pg_defaultdbase sampledb
必要に応じて、ベンチマークを実行する際のユーザ名、パスワード、データベースを入力します。ここで設定するユーザとデータベースは存在しない場合管理者ユーザを使用して自動で作成されます。
hammerdb>diset tpcc pg_user tpcc
hammerdb>diset tpcc pg_pass tpcc
hammerdb>diset tpcc pg_dbase tpcc
warehouse を指定します。倉庫を表し、データベース全体のサイズを決める因子になっています。
hammerdb>diset tpcc pg_count_ware 100
データロード時の同時実行数を指定します。
hammerdb>diset tpcc pg_num_vu 4
設定した内容を確認します。
hammerdb>print dict
Dictionary Settings for PostgreSQL
connection {
pg_host = xxxxxxxxxxxx.example.com
pg_port = 99999
pg_sslmode = prefer
}
tpcc {
pg_count_ware = 100
pg_num_vu = 4
pg_superuser = XXXXX
pg_superuserpass = XXXXXXXXXXXXXXXX
pg_defaultdbase = sampledb
pg_user = tpcc
pg_pass = tpcc
pg_dbase = tpcc
pg_tspace = pg_default
pg_vacuum = false
pg_dritasnap = false
pg_oracompat = false
pg_storedprocs = false
pg_partition = false
pg_total_iterations = 10000000
pg_raiseerror = false
pg_keyandthink = false
pg_driver = test
pg_rampup = 2
pg_duration = 5
pg_allwarehouse = false
pg_timeprofile = false
pg_async_scale = false
pg_async_client = 10
pg_async_verbose = false
pg_async_delay = 1000
pg_connect_pool = false
}
ベンチマーク用のスキーマとデータを作成します。
hammerdb>buildschema
データの作成が完了すると、以下のようなメッセージが表示されます。一度改行するとhammerdb>
のプロンプトに戻ります。
Vuser 1:TPCC SCHEMA COMPLETE
Vuser 1:FINISHED SUCCESS
ALL VIRTUAL USERS COMPLETE
データを作成したときの仮想ユーザを削除します。
hammerdb>vudestroy
次にベンチマークの実施設定を行います。ベンチマークの実施時はドライバスクリプトの設定をtimed
にします。
hammerdb>diset tpcc pg_driver timed
クライアント側のタイムプロファイルを有効にします。
hammerdb>diset tpcc pg_timeprofile true
dbset と diset で設定した内容をロードします
hammerdb>loadscript
仮想ユーザの構成を確認します。
hammerdb>print vuconf
Virtual Users = 5
User Delay(ms) = 500
Repeat Delay(ms) = 500
Iterations = 1
Show Output = 1
Log Output = 0
Unique Log Name = 0
No Log Buffer = 0
Log Timestamps = 0
設定項目を確認します。
hammerdb>vuset
Usage: vuset [vu|delay|repeat|iterations|showoutput|logtotemp|unique|nobuff|timestamps] value
ベンチマークを実行する同時実行ユーザー数を定義します。ここでは 8 にしています。
hammerdb>vuset vu 8
ログを出力する設定を行います。
hammerdb>vuset logtotemp 1
ログ名の設定
hammerdb>vuset unique 1
ログへのタイムスタンプ設定を行います。
hammerdb>vuset timestamps 1
実施した設定を確認します。
hammerdb>print vuconf
Virtual Users = 8
User Delay(ms) = 500
Repeat Delay(ms) = 500
Iterations = 1
Show Output = 1
Log Output = 1
Unique Log Name = 1
No Log Buffer = 0
Log Timestamps = 1
ベンチマークの実行ユーザを作成します。出力されるログのパスも表示されます。
hammerdb>vucreate
Vuser 1 created MONITOR - WAIT IDLE
Vuser 2 created - WAIT IDLE
Vuser 3 created - WAIT IDLE
Vuser 4 created - WAIT IDLE
Vuser 5 created - WAIT IDLE
Vuser 6 created - WAIT IDLE
Vuser 7 created - WAIT IDLE
Vuser 8 created - WAIT IDLE
Vuser 9 created - WAIT IDLE
Logging activated
to /tmp/hammerdb_1234ABCD5678EFGH1234ABCD.log
9 Virtual Users Created with Monitor VU
実行ユーザのステータスを確認します。各ユーザのステータスがWAIT IDLE
になっていることを確認します。
hammerdb>vustatus
1 = WAIT IDLE
2 = WAIT IDLE
3 = WAIT IDLE
4 = WAIT IDLE
5 = WAIT IDLE
6 = WAIT IDLE
7 = WAIT IDLE
8 = WAIT IDLE
9 = WAIT IDLE
ベンチマークを実行します。
hammerdb>vurun
Vuser 1:RUNNING
Vuser 1:Initializing xtprof time profiler
Vuser 1:Beginning rampup time of 2 minutes
・
・
・
ALL VIRTUAL USERS COMPLETE
が表示されるとベンチマークの完了です。TEST RESULT
の行に結果が出力されます。また時間情報が出力されたログのパスも出力されています。
結果にはNOPM
とTPM
があります。NOPM は New Orders per Minute の略で、新規発注処理を1分間に何回できたかを表しています。TPC-C の場合は分間の新規発注処理数を tpmC で表しますが、HammerDB では 厳密には TPC-C に準拠していないため使用できません。そのため NOPM という指標を使用しています。TPM は Transactions per Minute の略で、オンライン トランザクション カウンターに表示される値で異なるデータベース間では比較できません。
Vuser 1:Test complete, Taking end Transaction Count.
Vuser 1:8 Active Virtual Users configured
Vuser 1:TEST RESULT : System achieved 99999 NOPM from 99999 PostgreSQL TPM
Vuser 1:Gathering timing data from Active Virtual Users...
Vuser 4:FINISHED SUCCESS
Vuser 5:FINISHED SUCCESS
Vuser 2:FINISHED SUCCESS
Vuser 9:FINISHED SUCCESS
Vuser 3:FINISHED SUCCESS
Vuser 7:FINISHED SUCCESS
Vuser 6:FINISHED SUCCESS
Vuser 8:FINISHED SUCCESS
Vuser 1:Calculating timings...
Vuser 1:Writing timing data to /tmp/hdbxtprofile.log
Vuser 1:FINISHED SUCCESS
ALL VIRTUAL USERS COMPLETE
ログの中身を確認します。各実行ユーザの結果詳細が出力されており、一番最後に各オペレーションの全体結果が出力されます。
$ cat /tmp/hdbxtprofile.log
PostgreSQL Hammerdb Time Profile Report @ Wed Feb 09 09:51:40 UTC 2022
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>>>>> VIRTUAL USER 2 : ELAPSED TIME : 999999ms
>>>>> PROC: NEWORD
・
・
・
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>>>>> SUMMARY OF 8 ACTIVE VIRTUAL USERS : MEDIAN ELAPSED TIME : 999999ms
>>>>> PROC: NEWORD
CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms
P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999%
>>>>> PROC: PAYMENT
CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms
P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999%
>>>>> PROC: DELIVERY
CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms
P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999%
>>>>> PROC: SLEV
CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms
P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999%
>>>>> PROC: OSTAT
CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms
P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999%
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TPROC-H の実施
TPC-H の派生ベンチマークである TPROC-H を実行してみます
HammerDB の CLI を起動します。
$ ./hammerdbcli
対象データベースを PostgreSQL に設定し、ベンチマークを TPROC-H に設定します。
hammerdb>dbset db pg
hammerdb>dbset bm TPROC-H
設定内容を確認します。この内容について必要な項目を設定していきます。
hammerdb>print dict
Dictionary Settings for PostgreSQL
connection {
pg_host = localhost
pg_port = 5432
pg_sslmode = prefer
}
tpch {
pg_scale_fact = 1
pg_tpch_superuser = postgres
pg_tpch_superuserpass = postgres
pg_tpch_defaultdbase = postgres
pg_tpch_user = tpch
pg_tpch_pass = tpch
pg_tpch_dbase = tpch
pg_tpch_tspace = pg_default
pg_tpch_gpcompat = false
pg_tpch_gpcompress = false
pg_num_tpch_threads = 1
pg_total_querysets = 1
pg_raise_query_error = false
pg_verbose = false
pg_refresh_on = false
pg_degree_of_parallel = 2
pg_update_sets = 1
pg_trickle_refresh = 1000
pg_refresh_verbose = false
pg_cloud_query = false
pg_rs_compat = false
}
接続先のホスト名と接続ポートを設定します。
hammerdb>diset connection pg_host xxxxxxxxxxxx.example.com
hammerdb>diset connection pg_port 99999
管理者ユーザ名、管理者パスワード、初期接続先のデータベースを入力します。
hammerdb>diset tpch pg_tpch_superuser XXXXX
hammerdb>diset tpch pg_tpch_superuserpass XXXXXXXXXXXXXXXX
hammerdb>diset tpch pg_tpch_defaultdbase sampledb
必要に応じて、ベンチマークを実行する際のユーザ名、パスワード、データベースを入力します。ここで設定するユーザとデータベースは存在しない場合管理者ユーザを使用して自動で作成されます。
hammerdb>diset tpch pg_tpch_user tpch
hammerdb>diset tpch pg_tpch_pass tpch
hammerdb>diset tpch pg_tpch_dbase tpch
pg_scale_fact を指定します。データのサイズです。以下の値のいずれかを入力します。
1, 10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000
hammerdb>diset tpch pg_scale_fact 100
データロード時の同時実行数を指定します。
hammerdb>diset tpch pg_num_tpch_threads 4
設定した内容を確認します。
hammerdb>print dict
Dictionary Settings for PostgreSQL
connection {
pg_host = xxxxxxxxxxxx.example.com
pg_port = 99999
pg_sslmode = prefer
}
tpch {
pg_scale_fact = 100
pg_tpch_superuser = XXXXX
pg_tpch_superuserpass = XXXXXXXXXXXXXXXX
pg_tpch_defaultdbase = sampledb
pg_tpch_user = tpch
pg_tpch_pass = tpch
pg_tpch_dbase = tpch
pg_tpch_tspace = pg_default
pg_tpch_gpcompat = false
pg_tpch_gpcompress = false
pg_num_tpch_threads = 1
pg_total_querysets = 1
pg_raise_query_error = false
pg_verbose = false
pg_refresh_on = false
pg_degree_of_parallel = 2
pg_update_sets = 1
pg_trickle_refresh = 1000
pg_refresh_verbose = false
pg_cloud_query = false
pg_rs_compat = false
}
ベンチマーク用のスキーマとデータを作成します。
hammerdb>buildschema
データの作成が完了すると、以下のようなメッセージが表示されます。一度改行するとhammerdb>
のプロンプトに戻ります。
Vuser 1:TPCH SCHEMA COMPLETE
Vuser 1:FINISHED SUCCESS
ALL VIRTUAL USERS COMPLETE
TPROC-H Driver Script
データを作成したときの仮想ユーザを削除します。
hammerdb>vudestroy
dbset と diset で設定した内容をロードします
hammerdb>loadscript
仮想ユーザの構成を確認します。
hammerdb>print vuconf
Virtual Users = 5
User Delay(ms) = 500
Repeat Delay(ms) = 500
Iterations = 1
Show Output = 1
Log Output = 0
Unique Log Name = 0
No Log Buffer = 0
Log Timestamps = 0
ベンチマークを実行する同時実行ユーザー数を定義します。ここでは 1 にしています。
hammerdb>vuset vu 1
ログを出力する設定を行います。
hammerdb>vuset logtotemp 1
ログ名の設定
hammerdb>vuset unique 1
実施した設定を確認します。
hammerdb>print vuconf
Virtual Users = 1
User Delay(ms) = 500
Repeat Delay(ms) = 500
Iterations = 1
Show Output = 1
Log Output = 1
Unique Log Name = 1
No Log Buffer = 0
Log Timestamps = 0
ベンチマークの実行ユーザを作成します。出力されるログのパスも表示されます。
hammerdb>vucreate
Vuser 1 created - WAIT IDLE
Logging activated
to /tmp/hammerdb_ABCD1234EFGH5678IJKM1234.log
1 Virtual Users Created
実行ユーザのステータスを確認します。各ユーザのステータスがWAIT IDLE
になっていることを確認します。
hammerdb>vustatus
1 = WAIT IDLE
ベンチマークを実行します。
hammerdb>vurun
Vuser 1:RUNNING
Vuser 1:Executing Query 14 (1 of 22)
・
・
・
Vuser 1:Completed 1 query set(s) in 99 seconds
Vuser 1:Geometric mean of query times returning rows (22) is 9.99999
Vuser 1:FINISHED SUCCESS
ALL VIRTUAL USERS COMPLETE
TPROC-H Driver Script
ログの中身を確認します。各クエリの実行時間が出力されています。TPC-H では QphH@Size という 1時間当たりの複合クエリのパフォーマンスを指標にしたものを使用しますが、HammerDB では派生の TPROC-H を使用しているため使用できません。結果を評価するにはクエリの実行時間を個別に比較するなどが良いかもしれません。
$ cat /tmp/hammerdb_ABCD1234EFGH5678IJKM1234.log
Hammerdb Log @ Wed Feb 09 14:08:34 UTC 2022
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Vuser 1:Executing Query 14 (1 of 22)
Vuser 1:query 14 completed in 0.999 seconds
Vuser 1:Executing Query 2 (2 of 22)
Vuser 1:query 2 completed in 0.999 seconds
Vuser 1:Executing Query 9 (3 of 22)
Vuser 1:query 9 completed in 0.999 seconds
Vuser 1:Executing Query 20 (4 of 22)
Vuser 1:query 20 completed in 0.999 seconds
Vuser 1:Executing Query 6 (5 of 22)
Vuser 1:query 6 completed in 0.999 seconds
Vuser 1:Executing Query 17 (6 of 22)
Vuser 1:query 17 completed in 0.999 seconds
Vuser 1:Executing Query 18 (7 of 22)
Vuser 1:query 18 completed in 0.999 seconds
Vuser 1:Executing Query 8 (8 of 22)
Vuser 1:query 8 completed in 0.999 seconds
Vuser 1:Executing Query 21 (9 of 22)
Vuser 1:query 21 completed in 0.999 seconds
Vuser 1:Executing Query 13 (10 of 22)
Vuser 1:query 13 completed in 0.999 seconds
Vuser 1:Executing Query 3 (11 of 22)
Vuser 1:query 3 completed in 0.999 seconds
Vuser 1:Executing Query 22 (12 of 22)
Vuser 1:query 22 completed in 0.999 seconds
Vuser 1:Executing Query 16 (13 of 22)
Vuser 1:query 16 completed in 0.999 seconds
Vuser 1:Executing Query 4 (14 of 22)
Vuser 1:query 4 completed in 0.999 seconds
Vuser 1:Executing Query 11 (15 of 22)
Vuser 1:query 11 completed in 0.999 seconds
Vuser 1:Executing Query 15 (16 of 22)
Vuser 1:query 15 completed in 0.999 seconds
Vuser 1:Executing Query 1 (17 of 22)
Vuser 1:query 1 completed in 0.999 seconds
Vuser 1:Executing Query 10 (18 of 22)
Vuser 1:query 10 completed in 0.999 seconds
Vuser 1:Executing Query 19 (19 of 22)
Vuser 1:query 19 completed in 0.999 seconds
Vuser 1:Executing Query 5 (20 of 22)
Vuser 1:query 5 completed in 0.999 seconds
Vuser 1:Executing Query 7 (21 of 22)
Vuser 1:query 7 completed in 0.999 seconds
Vuser 1:Executing Query 12 (22 of 22)
Vuser 1:query 12 completed in 0.999 seconds
Vuser 1:Completed 1 query set(s) in 99 seconds
Vuser 1:Geometric mean of query times returning rows (22) is 0.99999
さいごに
HammerDB は、OLTP と OLAP の両方のベンチマークを簡単に行えるツールです。使用するデータベースのパフォーマンスは実ワークロードで確認するのが最適なのですが、なかなか実施するのは難しいです。そのため HammerDB のようなベンチマークテストツールを使用して必要なパフォーマンスを発揮するかの目安を確認すると良いのではないでしょうか。